text: /*  Make the following connections:
    - 3V3 (ESP32) --> 5V (shield's logic voltage pin)
    - GND (ESP32) --> GND (shield)
    - RX2 (ESP32) --> 10 (shield's TX)
    - TX2 (ESP32) --> 11 (shield's RX)
    - D5 (ESP32) --> 7 (shield's RST)
    - D18 (ESP32) --> 6 (shield's PWRKEY)
    - Optional: SCL (GPIO22) and SDA (GPIO21) if you want to use the temperature sensor
  */
  
  /******* ORIGINAL ADAFRUIT FONA LIBRARY TEXT *******/
  /***************************************************
    This is an example for our Adafruit FONA Cellular Module
  
    Designed specifically to work with the Adafruit FONA
    ----> http://www.adafruit.com/products/1946
    ----> http://www.adafruit.com/products/1963
    ----> http://www.adafruit.com/products/2468
    ----> http://www.adafruit.com/products/2542
  
    These cellular modules use TTL Serial to communicate, 2 pins are
    required to interface
    Adafruit invests time and resources providing this open source code,
    please support Adafruit and open-source hardware by purchasing
    products from Adafruit!
   ****************************************************/
  
  #include <Wire.h>
  #include "Adafruit_FONA.h"
  
  // For SIM7000 shield with ESP32
  #define FONA_PWRKEY 18
  #define FONA_RST 5
  #define FONA_TX 16 // ESP32 hardware serial RX2 (GPIO16)
  #define FONA_RX 17 // ESP32 hardware serial TX2 (GPIO17)
  
  // For ESP32 hardware serial
  #include <HardwareSerial.h>
  HardwareSerial fonaSS(1);
  
  // Use this one for LTE CAT-M/NB-IoT modules (like SIM7000)
  // Notice how we don't include the reset pin because it's reserved for emergencies on the LTE module!
  Adafruit_FONA_LTE fona = Adafruit_FONA_LTE();
  
  uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
  uint8_t type;
  char replybuffer[255]; // this is a large buffer for replies
  char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  
  // Power on the module
  void powerOn() {
    digitalWrite(FONA_PWRKEY, LOW);
    // See spec sheets for your particular module
    delay(100); // For SIM7000
  
    digitalWrite(FONA_PWRKEY, HIGH);
  }
  
  void printMenu(void) {
    Serial.println(F("-------------------------------------"));
    // General
    Serial.println(F("[?] Print this menu"));
    Serial.println(F("[a] Read the ADC 2.8V max for SIM800/808, 1.7V max for SIM7000 shield"));
    Serial.println(F("[b] Read supply voltage")); // Will also give battery % charged for most modules
    Serial.println(F("[C] Read the SIM CCID"));
    Serial.println(F("[U] Unlock SIM with PIN code"));
    Serial.println(F("[i] Read signal strength (RSSI)"));
    Serial.println(F("[n] Get network status"));
    Serial.println(F("[1] Get network connection info")); // See what connection type and band you're on!
    // SMS
    Serial.println(F("[N] Number of SMS's"));
    Serial.println(F("[r] Read SMS #"));
    Serial.println(F("[R] Read all SMS"));
    Serial.println(F("[d] Delete SMS #"));
    Serial.println(F("[s] Send SMS"));
    Serial.println(F("[u] Send USSD"));
  
    // Time
    Serial.println(F("[y] Enable local time stamp (SIM800/808/7000)"));
    Serial.println(F("[Y] Enable NTP time sync (SIM800/808/7000)")); // Need to use "G" command first!
    Serial.println(F("[t] Get network time")); // Works just by being connected to network
  
    // Data Connection
    Serial.println(F("[G] Enable cellular data"));
    Serial.println(F("[g] Disable cellular data"));
    Serial.println(F("[l] Query GSMLOC (2G)"));
    Serial.println(F("[w] Read webpage"));
    Serial.println(F("[W] Post to website"));
    // The following option below posts dummy data to dweet.io for demonstration purposes. See the
    // IoT_example sketch for an actual application of this function!
    Serial.println(F("[2] Post to dweet.io via 2G / LTE CAT-M / NB-IoT")); // This can be SIM800/808/900/7000
    Serial.println(F("[3] Post to dweet.io via 3G / 4G LTE")); // SIM5320/7500
  
    // GPS
    Serial.println(F("[O] Turn GPS on (SIM808/5320/7000)"));
    Serial.println(F("[o] Turn GPS off (SIM808/5320/7000)"));
    Serial.println(F("[L] Query GPS location (SIM808/5320/7000)"));
    if (type == SIM808_V1) {
      Serial.println(F("[x] GPS fix status (FONA808 v1 only)"));
    }
    Serial.println(F("[E] Raw NMEA out (SIM808)"));
  
    Serial.println(F("[S] Create serial passthru tunnel"));
    Serial.println(F("-------------------------------------"));
    Serial.println(F(""));
  }
  
  void setup() {
    //  while (!Serial);
  
    pinMode(FONA_RST, OUTPUT);
    digitalWrite(FONA_RST, HIGH); // Default state
  
    pinMode(FONA_PWRKEY, OUTPUT);
  
    // Turn on the module by pulsing PWRKEY low for a little bit
    // This amount of time depends on the specific module that's used
    powerOn(); // See function definition at the very end of the sketch
  
    Serial.begin(115200);
    Serial.println(F("ESP32 Basic Test"));
    Serial.println(F("Initializing....(May take several seconds)"));
  
    // Note: The SIM7000A baud rate seems to reset after being power cycled (SIMCom firmware thing)
    // SIM7000 takes about 3s to turn on but SIM7500 takes about 15s
    // Press reset button if the module is still turning on and the board doesn't find it.
    // When the module is on it should communicate right after pressing reset
    
    // Start at default SIM7000 shield baud rate
    fonaSS.begin(115200, SERIAL_8N1, FONA_TX, FONA_RX); // baud rate, protocol, ESP32 RX pin, ESP32 TX pin
  
    Serial.println(F("Configuring to 9600 baud"));
    fonaSS.println("AT+IPR=9600"); // Set baud rate
    delay(100); // Short pause to let the command run
    fonaSS.begin(9600, SERIAL_8N1, FONA_TX, FONA_RX); // Switch to 9600
    if (! fona.begin(fonaSS)) {
      Serial.println(F("Couldn't find FONA"));
      while (1); // Don't proceed if it couldn't find the device
    }
  
    type = fona.type();
    Serial.println(F("FONA is OK"));
    Serial.print(F("Found "));
    switch (type) {
      case SIM7000A:
        Serial.println(F("SIM7000A (American)")); break;
      case SIM7000C:
        Serial.println(F("SIM7000C (Chinese)")); break;
      case SIM7000E:
        Serial.println(F("SIM7000E (European)")); break;
      case SIM7000G:
        Serial.println(F("SIM7000G (Global)")); break;
      default:
        Serial.println(F("???")); break;
    }
  
    // Print module IMEI number.
    uint8_t imeiLen = fona.getIMEI(imei);
    if (imeiLen > 0) {
      Serial.print("Module IMEI: "); Serial.println(imei);
    }
  
    // Set modem to full functionality
    fona.setFunctionality(1); // AT+CFUN=1
  
    // Configure a GPRS APN, username, and password.
    // You might need to do this to access your network's GPRS/data
    // network.  Contact your provider for the exact APN, username,
    // and password values.  Username and password are optional and
    // can be removed, but APN is required.
    //fona.setNetworkSettings(F("your APN"), F("your username"), F("your password"));
    //fona.setNetworkSettings(F("m2m.com.attz")); // For AT&T IoT SIM card
    //fona.setNetworkSettings(F("telstra.internet")); // For Telstra (Australia) SIM card - CAT-M1 (Band 28)
    fona.setNetworkSettings(F("hologram")); // For Hologram SIM card
  
    // Optionally configure HTTP gets to follow redirects over SSL.
    // Default is not to follow SSL redirects, however if you uncomment
    // the following line then redirects over SSL will be followed.
    //fona.setHTTPSRedirect(true);
  
    /*
    // Other examples of some things you can set:
    fona.setPreferredMode(38); // Use LTE only, not 2G
    fona.setPreferredLTEMode(1); // Use LTE CAT-M only, not NB-IoT
    fona.setOperatingBand("CAT-M", 12); // AT&T uses band 12
  //  fona.setOperatingBand("CAT-M", 13); // Verizon uses band 13
    fona.enableRTC(true);
    
    fona.enableSleepMode(true);
    fona.set_eDRX(1, 4, "0010");
    fona.enablePSM(true);
  
    // Set the network status LED blinking pattern while connected to a network (see AT+SLEDS command)
    fona.setNetLED(true, 2, 64, 3000); // on/off, mode, timer_on, timer_off
    fona.setNetLED(false); // Disable network status LED
    */
  
    printMenu();
  }
  
  void flushSerial() {
    while (Serial.available())
      Serial.read();
  }
  
  char readBlocking() {
    while (!Serial.available());
    return Serial.read();
  }
  uint16_t readnumber() {
    uint16_t x = 0;
    char c;
    while (! isdigit(c = readBlocking())) {
      //Serial.print(c);
    }
    Serial.print(c);
    x = c - '0';
    while (isdigit(c = readBlocking())) {
      Serial.print(c);
      x *= 10;
      x += c - '0';
    }
    return x;
  }
  
  uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
    uint16_t buffidx = 0;
    boolean timeoutvalid = true;
    if (timeout == 0) timeoutvalid = false;
  
    while (true) {
      if (buffidx > maxbuff) {
        //Serial.println(F("SPACE"));
        break;
      }
  
      while (Serial.available()) {
        char c =  Serial.read();
  
        //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);
  
        if (c == '\r') continue;
        if (c == 0xA) {
          if (buffidx == 0)   // the first 0x0A is ignored
            continue;
  
          timeout = 0;         // the second 0x0A is the end of the line
          timeoutvalid = true;
          break;
        }
        buff[buffidx] = c;
        buffidx++;
      }
  
      if (timeoutvalid && timeout == 0) {
        //Serial.println(F("TIMEOUT"));
        break;
      }
      delay(1);
    }
    buff[buffidx] = 0;  // null term
    return buffidx;
  }
  
  void loop() {
    Serial.print(F("FONA> "));
    while (! Serial.available() ) {
      if (fona.available()) {
        Serial.write(fona.read());
      }
    }
  
    char command = Serial.read();
    Serial.println(command);
  
  
    switch (command) {
      case '?': {
          printMenu();
          break;
        }
  
      case 'a': {
          // read the ADC
          uint16_t adc;
          if (! fona.getADCVoltage(&adc)) {
            Serial.println(F("Failed to read ADC"));
          } else {
            Serial.print(F("ADC = ")); Serial.print(adc); Serial.println(F(" mV"));
          }
          break;
        }
  
      case 'b': {
          // read the battery voltage and percentage
          uint16_t vbat;
          if (! fona.getBattVoltage(&vbat)) {
            Serial.println(F("Failed to read Batt"));
          } else {
            Serial.print(F("VBat = ")); Serial.print(vbat); Serial.println(F(" mV"));
          }
  
          if ( (type != SIM7500A) && (type != SIM7500E) ) {
            if (! fona.getBattPercent(&vbat)) {
              Serial.println(F("Failed to read Batt"));
            } else {
              Serial.print(F("VPct = ")); Serial.print(vbat); Serial.println(F("%"));
            }
          }
  
          break;
        }
  
      case 'U': {
          // Unlock the SIM with a PIN code
          char PIN[5];
          flushSerial();
          Serial.println(F("Enter 4-digit PIN"));
          readline(PIN, 3);
          Serial.println(PIN);
          Serial.print(F("Unlocking SIM card: "));
          if (! fona.unlockSIM(PIN)) {
            Serial.println(F("Failed"));
          } else {
            Serial.println(F("OK!"));
          }
          break;
        }
  
      case 'C': {
          // read the CCID
          fona.getSIMCCID(replybuffer);  // make sure replybuffer is at least 21 bytes!
          Serial.print(F("SIM CCID = ")); Serial.println(replybuffer);
          break;
        }
  
      case 'i': {
          // read the RSSI
          uint8_t n = fona.getRSSI();
          int8_t r;
  
          Serial.print(F("RSSI = ")); Serial.print(n); Serial.print(": ");
          if (n == 0) r = -115;
          if (n == 1) r = -111;
          if (n == 31) r = -52;
          if ((n >= 2) && (n <= 30)) {
            r = map(n, 2, 30, -110, -54);
          }
          Serial.print(r); Serial.println(F(" dBm"));
  
          break;
        }
  
      case 'n': {
          // read the network/cellular status
          uint8_t n = fona.getNetworkStatus();
          Serial.print(F("Network status "));
          Serial.print(n);
          Serial.print(F(": "));
          if (n == 0) Serial.println(F("Not registered"));
          if (n == 1) Serial.println(F("Registered (home)"));
          if (n == 2) Serial.println(F("Not registered (searching)"));
          if (n == 3) Serial.println(F("Denied"));
          if (n == 4) Serial.println(F("Unknown"));
          if (n == 5) Serial.println(F("Registered roaming"));
          break;
        }
      case '1': {
          // Get connection type, cellular band, carrier name, etc.
          fona.getNetworkInfo();
          break;
        }
  
      /*** SMS ***/
  
      case 'N': {
          // read the number of SMS's!
          int8_t smsnum = fona.getNumSMS();
          if (smsnum < 0) {
            Serial.println(F("Could not read # SMS"));
          } else {
            Serial.print(smsnum);
            Serial.println(F(" SMS's on SIM card!"));
          }
          break;
        }
      case 'r': {
          // read an SMS
          flushSerial();
          Serial.print(F("Read #"));
          uint8_t smsn = readnumber();
          Serial.print(F("\n\rReading SMS #")); Serial.println(smsn);
  
          // Retrieve SMS sender address/phone number.
          if (! fona.getSMSSender(smsn, replybuffer, 250)) {
            Serial.println("Failed!");
            break;
          }
          Serial.print(F("FROM: ")); Serial.println(replybuffer);
  
          // Retrieve SMS value.
          uint16_t smslen;
          if (! fona.readSMS(smsn, replybuffer, 250, &smslen)) { // pass in buffer and max len!
            Serial.println("Failed!");
            break;
          }
          Serial.print(F("***** SMS #")); Serial.print(smsn);
          Serial.print(" ("); Serial.print(smslen); Serial.println(F(") bytes *****"));
          Serial.println(replybuffer);
          Serial.println(F("*****"));
  
          break;
        }
      case 'R': {
          // read all SMS
          int8_t smsnum = fona.getNumSMS();
          uint16_t smslen;
          int8_t smsn;
  
          if ( (type == SIM5320A) || (type == SIM5320E) ) {
            smsn = 0; // zero indexed
            smsnum--;
          } else {
            smsn = 1;  // 1 indexed
          }
  
          for ( ; smsn <= smsnum; smsn++) {
            Serial.print(F("\n\rReading SMS #")); Serial.println(smsn);
            if (!fona.readSMS(smsn, replybuffer, 250, &smslen)) {  // pass in buffer and max len!
              Serial.println(F("Failed!"));
              break;
            }
            // if the length is zero, its a special case where the index number is higher
            // so increase the max we'll look at!
            if (smslen == 0) {
              Serial.println(F("[empty slot]"));
              smsnum++;
              continue;
            }
  
            Serial.print(F("***** SMS #")); Serial.print(smsn);
            Serial.print(" ("); Serial.print(smslen); Serial.println(F(") bytes *****"));
            Serial.println(replybuffer);
            Serial.println(F("*****"));
          }
          break;
        }
  
      case 'd': {
          // delete an SMS
          flushSerial();
          Serial.print(F("Delete #"));
          uint8_t smsn = readnumber();
  
          Serial.print(F("\n\rDeleting SMS #")); Serial.println(smsn);
          if (fona.deleteSMS(smsn)) {
            Serial.println(F("OK!"));
          } else {
            Serial.println(F("Couldn't delete"));
          }
          break;
        }
  
      case 's': {
          // send an SMS!
          char sendto[21], message[141];
          flushSerial();
          Serial.print(F("Send to #"));
          readline(sendto, 20);
          Serial.println(sendto);
          Serial.print(F("Type out one-line message (140 char): "));
          readline(message, 140);
          Serial.println(message);
          if (!fona.sendSMS(sendto, message)) {
            Serial.println(F("Failed"));
          } else {
            Serial.println(F("Sent!"));
          }
  
          break;
        }
  
      case 'u': {
          // send a USSD!
          char message[141];
          flushSerial();
          Serial.print(F("Type out one-line message (140 char): "));
          readline(message, 140);
          Serial.println(message);
  
          uint16_t ussdlen;
          if (!fona.sendUSSD(message, replybuffer, 250, &ussdlen)) { // pass in buffer and max len!
            Serial.println(F("Failed"));
          } else {
            Serial.println(F("Sent!"));
            Serial.print(F("***** USSD Reply"));
            Serial.print(" ("); Serial.print(ussdlen); Serial.println(F(") bytes *****"));
            Serial.println(replybuffer);
            Serial.println(F("*****"));
          }
        }
  
      /*** Time ***/
  
      case 'y': {
          // enable network time sync
          if (!fona.enableRTC(true))
            Serial.println(F("Failed to enable"));
          break;
        }
  
      case 'Y': {
          // enable NTP time sync
          if (!fona.enableNTPTimeSync(true, F("pool.ntp.org")))
            Serial.println(F("Failed to enable"));
          break;
        }
  
      case 't': {
          // read the time
          char buffer[23];
  
          fona.getTime(buffer, 23);  // make sure replybuffer is at least 23 bytes!
          Serial.print(F("Time = ")); Serial.println(buffer);
          break;
        }
  
  
      /*********************************** GPS */
  
      case 'o': {
          // turn GPS off
          if (!fona.enableGPS(false))
            Serial.println(F("Failed to turn off"));
          break;
        }
      case 'O': {
          // turn GPS on
          if (!fona.enableGPS(true))
            Serial.println(F("Failed to turn on"));
          break;
        }
      case 'x': {
          int8_t stat;
          // check GPS fix
          stat = fona.GPSstatus();
          if (stat < 0)
            Serial.println(F("Failed to query"));
          if (stat == 0) Serial.println(F("GPS off"));
          if (stat == 1) Serial.println(F("No fix"));
          if (stat == 2) Serial.println(F("2D fix"));
          if (stat == 3) Serial.println(F("3D fix"));
          break;
        }
  
      case 'L': {
          /*
            // Uncomment this block if all you want to see is the AT command response
            // check for GPS location
            char gpsdata[120];
            fona.getGPS(0, gpsdata, 120);
            if (type == SIM808_V1)
            Serial.println(F("Reply in format: mode,longitude,latitude,altitude,utctime(yyyymmddHHMMSS),ttff,satellites,speed,course"));
            else if ( (type == SIM5320A) || (type == SIM5320E) || (type == SIM7500A) || (type == SIM7500E) )
            Serial.println(F("Reply in format: [<lat>],[<N/S>],[<lon>],[<E/W>],[<date>],[<UTC time>(yyyymmddHHMMSS)],[<alt>],[<speed>],[<course>]"));
            else
            Serial.println(F("Reply in format: mode,fixstatus,utctime(yyyymmddHHMMSS),latitude,longitude,altitude,speed,course,fixmode,reserved1,HDOP,PDOP,VDOP,reserved2,view_satellites,used_satellites,reserved3,C/N0max,HPA,VPA"));
  
            Serial.println(gpsdata);
  
            break;
          */
  
          float latitude, longitude, speed_kph, heading, altitude, second;
          uint16_t year;
          uint8_t month, day, hour, minute;
  
          // Use the top line if you want to parse UTC time data as well, the line below it if you don't care
          //        if (fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude, &year, &month, &day, &hour, &minute, &second)) {
          if (fona.getGPS(&latitude, &longitude, &speed_kph, &heading, &altitude)) { // Use this line instead if you don't want UTC time
            Serial.println(F("---------------------"));
            Serial.print(F("Latitude: ")); Serial.println(latitude, 6);
            Serial.print(F("Longitude: ")); Serial.println(longitude, 6);
            Serial.print(F("Speed: ")); Serial.println(speed_kph);
            Serial.print(F("Heading: ")); Serial.println(heading);
            Serial.print(F("Altitude: ")); Serial.println(altitude);
            // Comment out the stuff below if you don't care about UTC time
            /*
              Serial.print(F("Year: ")); Serial.println(year);
              Serial.print(F("Month: ")); Serial.println(month);
              Serial.print(F("Day: ")); Serial.println(day);
              Serial.print(F("Hour: ")); Serial.println(hour);
              Serial.print(F("Minute: ")); Serial.println(minute);
              Serial.print(F("Second: ")); Serial.println(second);
              Serial.println(F("---------------------"));
            */
          }
  
          break;
        }
  
      case 'E': {
          flushSerial();
          if (type == SIM808_V1) {
            Serial.print(F("GPS NMEA output sentences (0 = off, 34 = RMC+GGA, 255 = all)"));
          } else {
            Serial.print(F("On (1) or Off (0)? "));
          }
          uint8_t nmeaout = readnumber();
  
          // turn on NMEA output
          fona.enableGPSNMEA(nmeaout);
  
          break;
        }
  
      /*********************************** GPRS/data */
  
      case 'g': {
          // turn data off
          if (!fona.enableGPRS(false))
            Serial.println(F("Failed to turn off"));
          break;
        }
      case 'G': {
          // turn data off first for SIM7500
          // turn data on
          if (!fona.enableGPRS(true))
            Serial.println(F("Failed to turn on"));
          break;
        }
      case 'l': {
          // check for GSMLOC (requires GPRS)
          uint16_t returncode;
  
          if (!fona.getGSMLoc(&returncode, replybuffer, 250))
            Serial.println(F("Failed!"));
          if (returncode == 0) {
            Serial.println(replybuffer);
          } else {
            Serial.print(F("Fail code #")); Serial.println(returncode);
          }
  
          break;
        }
      case 'w': {
          // read website URL
          uint16_t statuscode;
          int16_t length;
          char url[80];
  
          flushSerial();
          Serial.println(F("URL to read (e.g. dweet.io/get/latest/dweet/for/sim7500test123):"));
          Serial.print(F("http://")); readline(url, 79);
          Serial.println(url);
  
          Serial.println(F("****"));
          if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length)) {
            Serial.println("Failed!");
            break;
          }
          while (length > 0) {
            while (fona.available()) {
              char c = fona.read();
  
              // Serial.write is too slow, we'll write directly to Serial register!
              Serial.write(c);
              length--;
              if (! length) break;
            }
          }
          Serial.println(F("\n****"));
          fona.HTTP_GET_end();
          break;
        }
  
      case 'W': {
          // Post data to website
          uint16_t statuscode;
          int16_t length;
          char url[80];
          char data[80];
  
          flushSerial();
          Serial.println(F("NOTE: in beta! Use simple websites to post!"));
          Serial.println(F("URL to post (e.g. httpbin.org/post):"));
          Serial.print(F("http://")); readline(url, 79);
          Serial.println(url);
          Serial.println(F("Data to post (e.g. \"foo\" or \"{\"simple\":\"json\"}\"):"));
          readline(data, 79);
          Serial.println(data);
  
          Serial.println(F("****"));
          if (!fona.HTTP_POST_start(url, F("text/plain"), (uint8_t *) data, strlen(data), &statuscode, (uint16_t *)&length)) {
            Serial.println("Failed!");
            break;
          }
          while (length > 0) {
            while (fona.available()) {
              char c = fona.read();
              Serial.write(c);
              length--;
              if (! length) break;
            }
          }
          Serial.println(F("\n****"));
          fona.HTTP_POST_end();
          break;
        }
      case '2': {
          // Post data to website via 2G or LTE CAT-M/NB-IoT
          float temperature = analogRead(A0) * 1.23; // Change this to suit your needs
  
          // Voltage in mV, just for testing. Use the read battery function instead.
          // Please note that for the LTE shield the voltage read will always be around 3.6V
          // because the SIM7000 is powered by a 3.6V regulator. If you want to monitor the
          // power source to the Arduino you will have to use something else.
          uint16_t battLevel = 3600;
  
          // Create char buffers for the floating point numbers for sprintf
          // Make sure these buffers are long enough for your request URL
          char URL[150];
          char body[100];
          char tempBuff[16];
          char battLevelBuff[16];
  
          // Format the floating point numbers as needed
          dtostrf(temperature, 1, 2, tempBuff); // float_val, min_width, digits_after_decimal, char_buffer
          dtostrf(battLevel, 1, 0, battLevelBuff);
  
          // Construct the appropriate URL's and body, depending on request type
          // Use IMEI as device ID for this example
  
          // GET request
          sprintf(URL, "dweet.io/dweet/for/%s?temp=%s&batt=%s", imei, tempBuff, battLevelBuff); // No need to specify http:// or https://
          //        sprintf(URL, "http://dweet.io/dweet/for/%s?temp=%s&batt=%s", imei, tempBuff, battLevelBuff); // But this works too
  
          if (!fona.postData("GET", URL))
            Serial.println(F("Failed to complete HTTP GET..."));
  
          // POST request
          /*
            sprintf(URL, "http://dweet.io/dweet/for/%s", imei);
            sprintf(body, "{\"temp\":%s,\"batt\":%s}", tempBuff, battLevelBuff);
  
            if (!fona.postData("POST", URL, body)) // Can also add authorization token parameter!
            Serial.println(F("Failed to complete HTTP POST..."));
          */
  
          break;
        }
      /*****************************************/
  
      case 'S': {
          Serial.println(F("Creating SERIAL TUBE"));
          while (1) {
            while (Serial.available()) {
              delay(1);
              fona.write(Serial.read());
            }
            if (fona.available()) {
              Serial.write(fona.read());
            }
          }
          break;
        }
  
      default: {
          Serial.println(F("Unknown command"));
          printMenu();
          break;
        }
    }
    // flush input
    flushSerial();
    while (fona.available()) {
      Serial.write(fona.read());
    }
  
  }
  