espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.01k stars 7.3k forks source link

Adafruit FONA 808: couldn't find fona #426

Closed architmuchhal12 closed 6 years ago

architmuchhal12 commented 7 years ago

Hello, I am using Espressif ESp32 along with Adafruit FONA808. I am able to compile the code and upload too. I am trying the basic FONAtest program available in the _AdafruitFona Library After uploading, I get a message on Serial Com as -

Couldn't find FONA

I have set the baud rate as 115200 and also attached a battery. I am attaching the screenshots of the Serial Com.

Fig 1 f1

Fig 2 f2

The connections which I've made are as-

VIO ---> 3V3 GND ---> GND RST ---> Pin 4 (GPIO4) TX ---> Pin 16 (U2_RXD) RX ---> Pin 17 (U2_TXD) Key ---> GND

Any suggestions are welcome. Thanks!

me-no-dev commented 7 years ago

How do you initialize Serial2? Show some code :)

architmuchhal12 commented 7 years ago

This is the code which I used. It's a basic FONAtest example from the Adafruit FONA Library -


#include <SoftwareSerial.h>

/***************************************************
  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!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

/*
THIS CODE IS STILL IN PROGRESS!

Open up the serial console on the Arduino at 115200 baud to interact with FONA

Note that if you need to set a GPRS APN, username, and password scroll down to
the commented section below at the end of the setup() function.
*/
#include "Adafruit_FONA.h"

#define FONA_TX 16 
#define FONA_RX 17 
#define FONA_RST 4

// this is a large buffer for replies
char replybuffer[255];

// We default to using software serial. If you want to use hardware serial
// (because softserial isnt supported) comment out the following three lines 
// and uncomment the HardwareSerial line
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible!
//  HardwareSerial *fonaSerial = &Serial1;

// Use this for FONA 800 and 808s
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
// Use this one for FONA 3G
//Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

uint8_t type;

void setup() {
  while (!Serial);

  Serial.begin(115200);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
  delay(1000);

  fonaSerial->begin(115200);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA800L:
      Serial.println(F("FONA 800L")); break;
    case FONA800H:
      Serial.println(F("FONA 800H")); break;
    case FONA808_V1:
      Serial.println(F("FONA 808 (v1)")); break;
    case FONA808_V2:
      Serial.println(F("FONA 808 (v2)")); break;
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default: 
      Serial.println(F("???")); break;
  }

  // Print module IMEI number.
  char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }

  // Optionally 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.setGPRSNetworkSettings(F("your APN"), F("your username"), F("your password"));

  // 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);

  printMenu();
}

void printMenu(void) {
  Serial.println(F("-------------------------------------"));
  Serial.println(F("[?] Print this menu"));
  Serial.println(F("[a] read the ADC 2.8V max (FONA800 & 808)"));
  Serial.println(F("[b] read the Battery V and % charged"));
  Serial.println(F("[C] read the SIM CCID"));
  Serial.println(F("[U] Unlock SIM with PIN code"));
  Serial.println(F("[i] read RSSI"));
  Serial.println(F("[n] get Network status"));
  Serial.println(F("[v] set audio Volume"));
  Serial.println(F("[V] get Volume"));
  Serial.println(F("[H] set Headphone audio (FONA800 & 808)"));
  Serial.println(F("[e] set External audio (FONA800 & 808)"));
  Serial.println(F("[T] play audio Tone"));
  Serial.println(F("[P] PWM/Buzzer out (FONA800 & 808)"));

  // FM (SIM800 only!)
  Serial.println(F("[f] tune FM radio (FONA800)"));
  Serial.println(F("[F] turn off FM (FONA800)"));
  Serial.println(F("[m] set FM volume (FONA800)"));
  Serial.println(F("[M] get FM volume (FONA800)"));
  Serial.println(F("[q] get FM station signal level (FONA800)"));

  // Phone
  Serial.println(F("[c] make phone Call"));
  Serial.println(F("[A] get call status"));
  Serial.println(F("[h] Hang up phone"));
  Serial.println(F("[p] Pick up phone"));

  // SMS
  Serial.println(F("[N] Number of SMSs"));
  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 network time sync (FONA 800 & 808)"));
  Serial.println(F("[Y] Enable NTP time sync (GPRS FONA 800 & 808)"));
  Serial.println(F("[t] Get network time"));

  // GPRS
  Serial.println(F("[G] Enable GPRS"));
  Serial.println(F("[g] Disable GPRS"));
  Serial.println(F("[l] Query GSMLOC (GPRS)"));
  Serial.println(F("[w] Read webpage (GPRS)"));
  Serial.println(F("[W] Post to website (GPRS)"));

  // GPS
  if ((type == FONA3G_A) || (type == FONA3G_E) || (type == FONA808_V1) || (type == FONA808_V2)) {
    Serial.println(F("[O] Turn GPS on (FONA 808 & 3G)"));
    Serial.println(F("[o] Turn GPS off (FONA 808 & 3G)"));
    Serial.println(F("[L] Query GPS location (FONA 808 & 3G)"));
    if (type == FONA808_V1) {
      Serial.println(F("[x] GPS fix status (FONA808 v1 only)"));
    }
    Serial.println(F("[E] Raw NMEA out (FONA808)"));
  }

  Serial.println(F("[S] create Serial passthru tunnel"));
  Serial.println(F("-------------------------------------"));
  Serial.println(F(""));

}
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 (! 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;
      }

    /*** Audio ***/
    case 'v': {
        // set volume
        flushSerial();
        if ( (type == FONA3G_A) || (type == FONA3G_E) ) {
          Serial.print(F("Set Vol [0-8] "));
        } else {
          Serial.print(F("Set Vol % [0-100] "));
        }
        uint8_t vol = readnumber();
        Serial.println();
        if (! fona.setVolume(vol)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    case 'V': {
        uint8_t v = fona.getVolume();
        Serial.print(v);
        if ( (type == FONA3G_A) || (type == FONA3G_E) ) {
          Serial.println(" / 8");
        } else {
          Serial.println("%");
        }
        break;
      }

    case 'H': {
        // Set Headphone output
        if (! fona.setAudio(FONA_HEADSETAUDIO)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        fona.setMicVolume(FONA_HEADSETAUDIO, 15);
        break;
      }
    case 'e': {
        // Set External output
        if (! fona.setAudio(FONA_EXTAUDIO)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }

        fona.setMicVolume(FONA_EXTAUDIO, 10);
        break;
      }

    case 'T': {
        // play tone
        flushSerial();
        Serial.print(F("Play tone #"));
        uint8_t kittone = readnumber();
        Serial.println();
        // play for 1 second (1000 ms)
        if (! fona.playToolkitTone(kittone, 1000)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    /*** FM Radio ***/

    case 'f': {
        // get freq
        flushSerial();
        Serial.print(F("FM Freq (eg 1011 == 101.1 MHz): "));
        uint16_t station = readnumber();
        Serial.println();
        // FM radio ON using headset
        if (fona.FMradio(true, FONA_HEADSETAUDIO)) {
          Serial.println(F("Opened"));
        }
        if (! fona.tuneFMradio(station)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("Tuned"));
        }
        break;
      }
    case 'F': {
        // FM radio off
        if (! fona.FMradio(false)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }
    case 'm': {
        // Set FM volume.
        flushSerial();
        Serial.print(F("Set FM Vol [0-6]:"));
        uint8_t vol = readnumber();
        Serial.println();
        if (!fona.setFMVolume(vol)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }
    case 'M': {
        // Get FM volume.
        uint8_t fmvol = fona.getFMVolume();
        if (fmvol < 0) {
          Serial.println(F("Failed"));
        } else {
          Serial.print(F("FM volume: "));
          Serial.println(fmvol, DEC);
        }
        break;
      }
    case 'q': {
        // Get FM station signal level (in decibels).
        flushSerial();
        Serial.print(F("FM Freq (eg 1011 == 101.1 MHz): "));
        uint16_t station = readnumber();
        Serial.println();
        int8_t level = fona.getFMSignalLevel(station);
        if (level < 0) {
          Serial.println(F("Failed! Make sure FM radio is on (tuned to station)."));
        } else {
          Serial.print(F("Signal level (dB): "));
          Serial.println(level, DEC);
        }
        break;
      }

    /*** PWM ***/

    case 'P': {
        // PWM Buzzer output @ 2KHz max
        flushSerial();
        Serial.print(F("PWM Freq, 0 = Off, (1-2000): "));
        uint16_t freq = readnumber();
        Serial.println();
        if (! fona.setPWM(freq)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    /*** Call ***/
    case 'c': {
        // call a phone!
        char number[30];
        flushSerial();
        Serial.print(F("Call #"));
        readline(number, 30);
        Serial.println();
        Serial.print(F("Calling ")); Serial.println(number);
        if (!fona.callPhone(number)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("Sent!"));
        }

        break;
      }
    case 'A': {
        // get call status
        int8_t callstat = fona.getCallStatus();
        switch (callstat) {
          case 0: Serial.println(F("Ready")); break;
          case 1: Serial.println(F("Could not get status")); break;
          case 3: Serial.println(F("Ringing (incoming)")); break;
          case 4: Serial.println(F("Ringing/in progress (outgoing)")); break;
          default: Serial.println(F("Unknown")); break;
        }
        break;
      }

    case 'h': {
        // hang up!
        if (! fona.hangUp()) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    case 'p': {
        // pick up!
        if (! fona.pickUp()) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        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 == FONA3G_A) || (type == FONA3G_E) ) {
          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.enableNetworkTimeSync(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 (SIM808 only) */

    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': {
        // check for GPS location
        char gpsdata[120];
        fona.getGPS(0, gpsdata, 120);
        if (type == FONA808_V1)
          Serial.println(F("Reply in format: mode,longitude,latitude,altitude,utctime(yyyymmddHHMMSS),ttff,satellites,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;
      }

    case 'E': {
        flushSerial();
        if (type == FONA808_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 */

    case 'g': {
        // turn GPRS off
        if (!fona.enableGPRS(false))
          Serial.println(F("Failed to turn off"));
        break;
      }
    case 'G': {
        // turn GPRS 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("NOTE: in beta! Use small webpages to read!"));
        Serial.println(F("URL to read (e.g. www.adafruit.com/testwifi/index.html):"));
        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!
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
            loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
            UDR0 = c;
#else
            Serial.write(c);
#endif
            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();

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
            loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
            UDR0 = c;
#else
            Serial.write(c);
#endif

            length--;
            if (! length) break;
          }
        }
        Serial.println(F("\n****"));
        fona.HTTP_POST_end();
        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());
  }

}

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;
}

#include <SoftwareSerial.h>

/***************************************************
  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!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

/*
THIS CODE IS STILL IN PROGRESS!

Open up the serial console on the Arduino at 115200 baud to interact with FONA

Note that if you need to set a GPRS APN, username, and password scroll down to
the commented section below at the end of the setup() function.
*/
#include "Adafruit_FONA.h"

#define FONA_TX 16 
#define FONA_RX 17 
#define FONA_RST 4

// this is a large buffer for replies
char replybuffer[255];

// We default to using software serial. If you want to use hardware serial
// (because softserial isnt supported) comment out the following three lines 
// and uncomment the HardwareSerial line
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible!
//  HardwareSerial *fonaSerial = &Serial1;

// Use this for FONA 800 and 808s
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
// Use this one for FONA 3G
//Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

uint8_t type;

void setup() {
  while (!Serial);

  Serial.begin(115200);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
  delay(1000);

  fonaSerial->begin(115200);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA800L:
      Serial.println(F("FONA 800L")); break;
    case FONA800H:
      Serial.println(F("FONA 800H")); break;
    case FONA808_V1:
      Serial.println(F("FONA 808 (v1)")); break;
    case FONA808_V2:
      Serial.println(F("FONA 808 (v2)")); break;
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default: 
      Serial.println(F("???")); break;
  }

  // Print module IMEI number.
  char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }

  // Optionally 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.setGPRSNetworkSettings(F("your APN"), F("your username"), F("your password"));

  // 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);

  printMenu();
}

void printMenu(void) {
  Serial.println(F("-------------------------------------"));
  Serial.println(F("[?] Print this menu"));
  Serial.println(F("[a] read the ADC 2.8V max (FONA800 & 808)"));
  Serial.println(F("[b] read the Battery V and % charged"));
  Serial.println(F("[C] read the SIM CCID"));
  Serial.println(F("[U] Unlock SIM with PIN code"));
  Serial.println(F("[i] read RSSI"));
  Serial.println(F("[n] get Network status"));
  Serial.println(F("[v] set audio Volume"));
  Serial.println(F("[V] get Volume"));
  Serial.println(F("[H] set Headphone audio (FONA800 & 808)"));
  Serial.println(F("[e] set External audio (FONA800 & 808)"));
  Serial.println(F("[T] play audio Tone"));
  Serial.println(F("[P] PWM/Buzzer out (FONA800 & 808)"));

  // FM (SIM800 only!)
  Serial.println(F("[f] tune FM radio (FONA800)"));
  Serial.println(F("[F] turn off FM (FONA800)"));
  Serial.println(F("[m] set FM volume (FONA800)"));
  Serial.println(F("[M] get FM volume (FONA800)"));
  Serial.println(F("[q] get FM station signal level (FONA800)"));

  // Phone
  Serial.println(F("[c] make phone Call"));
  Serial.println(F("[A] get call status"));
  Serial.println(F("[h] Hang up phone"));
  Serial.println(F("[p] Pick up phone"));

  // SMS
  Serial.println(F("[N] Number of SMSs"));
  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 network time sync (FONA 800 & 808)"));
  Serial.println(F("[Y] Enable NTP time sync (GPRS FONA 800 & 808)"));
  Serial.println(F("[t] Get network time"));

  // GPRS
  Serial.println(F("[G] Enable GPRS"));
  Serial.println(F("[g] Disable GPRS"));
  Serial.println(F("[l] Query GSMLOC (GPRS)"));
  Serial.println(F("[w] Read webpage (GPRS)"));
  Serial.println(F("[W] Post to website (GPRS)"));

  // GPS
  if ((type == FONA3G_A) || (type == FONA3G_E) || (type == FONA808_V1) || (type == FONA808_V2)) {
    Serial.println(F("[O] Turn GPS on (FONA 808 & 3G)"));
    Serial.println(F("[o] Turn GPS off (FONA 808 & 3G)"));
    Serial.println(F("[L] Query GPS location (FONA 808 & 3G)"));
    if (type == FONA808_V1) {
      Serial.println(F("[x] GPS fix status (FONA808 v1 only)"));
    }
    Serial.println(F("[E] Raw NMEA out (FONA808)"));
  }

  Serial.println(F("[S] create Serial passthru tunnel"));
  Serial.println(F("-------------------------------------"));
  Serial.println(F(""));

}
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 (! 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;
      }

    /*** Audio ***/
    case 'v': {
        // set volume
        flushSerial();
        if ( (type == FONA3G_A) || (type == FONA3G_E) ) {
          Serial.print(F("Set Vol [0-8] "));
        } else {
          Serial.print(F("Set Vol % [0-100] "));
        }
        uint8_t vol = readnumber();
        Serial.println();
        if (! fona.setVolume(vol)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    case 'V': {
        uint8_t v = fona.getVolume();
        Serial.print(v);
        if ( (type == FONA3G_A) || (type == FONA3G_E) ) {
          Serial.println(" / 8");
        } else {
          Serial.println("%");
        }
        break;
      }

    case 'H': {
        // Set Headphone output
        if (! fona.setAudio(FONA_HEADSETAUDIO)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        fona.setMicVolume(FONA_HEADSETAUDIO, 15);
        break;
      }
    case 'e': {
        // Set External output
        if (! fona.setAudio(FONA_EXTAUDIO)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }

        fona.setMicVolume(FONA_EXTAUDIO, 10);
        break;
      }

    case 'T': {
        // play tone
        flushSerial();
        Serial.print(F("Play tone #"));
        uint8_t kittone = readnumber();
        Serial.println();
        // play for 1 second (1000 ms)
        if (! fona.playToolkitTone(kittone, 1000)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    /*** FM Radio ***/

    case 'f': {
        // get freq
        flushSerial();
        Serial.print(F("FM Freq (eg 1011 == 101.1 MHz): "));
        uint16_t station = readnumber();
        Serial.println();
        // FM radio ON using headset
        if (fona.FMradio(true, FONA_HEADSETAUDIO)) {
          Serial.println(F("Opened"));
        }
        if (! fona.tuneFMradio(station)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("Tuned"));
        }
        break;
      }
    case 'F': {
        // FM radio off
        if (! fona.FMradio(false)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }
    case 'm': {
        // Set FM volume.
        flushSerial();
        Serial.print(F("Set FM Vol [0-6]:"));
        uint8_t vol = readnumber();
        Serial.println();
        if (!fona.setFMVolume(vol)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }
    case 'M': {
        // Get FM volume.
        uint8_t fmvol = fona.getFMVolume();
        if (fmvol < 0) {
          Serial.println(F("Failed"));
        } else {
          Serial.print(F("FM volume: "));
          Serial.println(fmvol, DEC);
        }
        break;
      }
    case 'q': {
        // Get FM station signal level (in decibels).
        flushSerial();
        Serial.print(F("FM Freq (eg 1011 == 101.1 MHz): "));
        uint16_t station = readnumber();
        Serial.println();
        int8_t level = fona.getFMSignalLevel(station);
        if (level < 0) {
          Serial.println(F("Failed! Make sure FM radio is on (tuned to station)."));
        } else {
          Serial.print(F("Signal level (dB): "));
          Serial.println(level, DEC);
        }
        break;
      }

    /*** PWM ***/

    case 'P': {
        // PWM Buzzer output @ 2KHz max
        flushSerial();
        Serial.print(F("PWM Freq, 0 = Off, (1-2000): "));
        uint16_t freq = readnumber();
        Serial.println();
        if (! fona.setPWM(freq)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    /*** Call ***/
    case 'c': {
        // call a phone!
        char number[30];
        flushSerial();
        Serial.print(F("Call #"));
        readline(number, 30);
        Serial.println();
        Serial.print(F("Calling ")); Serial.println(number);
        if (!fona.callPhone(number)) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("Sent!"));
        }

        break;
      }
    case 'A': {
        // get call status
        int8_t callstat = fona.getCallStatus();
        switch (callstat) {
          case 0: Serial.println(F("Ready")); break;
          case 1: Serial.println(F("Could not get status")); break;
          case 3: Serial.println(F("Ringing (incoming)")); break;
          case 4: Serial.println(F("Ringing/in progress (outgoing)")); break;
          default: Serial.println(F("Unknown")); break;
        }
        break;
      }

    case 'h': {
        // hang up!
        if (! fona.hangUp()) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        break;
      }

    case 'p': {
        // pick up!
        if (! fona.pickUp()) {
          Serial.println(F("Failed"));
        } else {
          Serial.println(F("OK!"));
        }
        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 == FONA3G_A) || (type == FONA3G_E) ) {
          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.enableNetworkTimeSync(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 (SIM808 only) */

    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': {
        // check for GPS location
        char gpsdata[120];
        fona.getGPS(0, gpsdata, 120);
        if (type == FONA808_V1)
          Serial.println(F("Reply in format: mode,longitude,latitude,altitude,utctime(yyyymmddHHMMSS),ttff,satellites,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;
      }

    case 'E': {
        flushSerial();
        if (type == FONA808_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 */

    case 'g': {
        // turn GPRS off
        if (!fona.enableGPRS(false))
          Serial.println(F("Failed to turn off"));
        break;
      }
    case 'G': {
        // turn GPRS 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("NOTE: in beta! Use small webpages to read!"));
        Serial.println(F("URL to read (e.g. www.adafruit.com/testwifi/index.html):"));
        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!
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
            loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
            UDR0 = c;
#else
            Serial.write(c);
#endif
            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();

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
            loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
            UDR0 = c;
#else
            Serial.write(c);
#endif

            length--;
            if (! length) break;
          }
        }
        Serial.println(F("\n****"));
        fona.HTTP_POST_end();
        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());
  }

}

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;
}
me-no-dev commented 7 years ago

Aaahhh SoftwareSerial ;) that is probably your problem ;) lib might need rework to be able to work with one of ESP32's hardware serial interfaces

architmuchhal12 commented 7 years ago

I had found this library for ESP32 Software Serial -

https://github.com/jdollar/espsoftwareserial/

So, should I use this or there is some other way in which I should proceed?

Thanx!

andrei-ivanov commented 7 years ago
// Hardware serial is also possible!
//  HardwareSerial *fonaSerial = &Serial1;

Doesn't that work? It's commented there in the code.

me-no-dev commented 7 years ago

ESP32 has 3 hardware serials that you can attach to pretty much any pin (pins below 34), So no need to try SoftSerial at all

architmuchhal12 commented 7 years ago

Hey, thanks for the suggestion. So, I did some changes to use the HardwareSerial. But, I think, I am missing something here. Could you just help me with that? This is the code -

#include "Adafruit_FONA.h"
//#include <SoftwareSerial.h>

//#define FONA_TX 16 
//#define FONA_RX 17 
#define FONA_RST 4

// this is a large buffer for replies
char replybuffer[255];

// We default to using software serial. If you want to use hardware serial
// (because softserial isnt supported) comment out the following three lines 
// and uncomment the HardwareSerial line

//SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
//SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible!
  HardwareSerial *fonaSerial = &Serial2;

// Use this for FONA 800 and 808s
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
// Use this one for FONA 3G
//Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

uint8_t type;

void setup() {
  while (!Serial);

  Serial.begin(115200);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
  delay(1000);

  fonaSerial->begin(115200);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA800L:
      Serial.println(F("FONA 800L")); break;
    case FONA800H:
      Serial.println(F("FONA 800H")); break;
    case FONA808_V1:
      Serial.println(F("FONA 808 (v1)")); break;
    case FONA808_V2:
      Serial.println(F("FONA 808 (v2)")); break;
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default: 
      Serial.println(F("???")); break;
  }

  // Print module IMEI number.
  char imei[16] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    Serial.print("Module IMEI: "); Serial.println(imei);
  }
printMenu();
}

I am getting error as -

FONAtest:45: error: 'Serial2' was not declared in this scope

   HardwareSerial *fonaSerial = &Serial2;

                                 ^

I really appreciate the quick response! Thanks a lot!

me-no-dev commented 7 years ago
HardwareSerial *fonaSerial = new HardwareSerial(2);

OR

HardwareSerial Serial2(2);
HardwareSerial *fonaSerial = &Serial2;
architmuchhal12 commented 7 years ago

Thanks a lot! I have got it to work! You guys are doing great work! Cheers!

mswmIoT commented 7 years ago

hello, am using adafruit fona32u4 am getting the following error while running Fonatest from example library, i have tried both hardware and software serial. Can anybody help please. FONA basic test Initializing....(May take 3 seconds) Attempting to open comm with ATs ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- ---> AT <--- Timeout: No response to AT... last ditch attempt. ---> AT <--- ---> AT <--- ---> AT <--- ---> ATE0 <--- ---> ATE0 <--- Couldn't find FONA

forthlightning commented 7 years ago

Is there a way to use FONA with TLS and MQTT? I'm trying to publish messages to a MQTT broker, but it requires TLS encryption

copercini commented 7 years ago

@forthlightning I know 2 methods (If you find any more, please let me know!):

hevnsnt commented 7 years ago

@architmuchhal12 do you mind posting your final code? I am also having the same problem. Thanks!

architmuchhal12 commented 7 years ago

@hevnsnt You need to use HardwareSerial. That's the only change I made - Here is the code -

#include "Adafruit_FONA.h"

#define FONA_RST 25

// this is a large buffer for replies
char replybuffer[255];

// Hardware serial is also possible!
HardwareSerial Serial2(2);
HardwareSerial *fonaSerial = &Serial2;

// Use this for FONA 800 and 808s
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

uint8_t type;

void setup() {
  while (!Serial);

  Serial.begin(115200);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
  delay(1000);

  fonaSerial->begin(115200);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    while (1);
  }
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA800L:
      Serial.println(F("FONA 800L")); break;
    case FONA800H:
      Serial.println(F("FONA 800H")); break;
    case FONA808_V1:
      Serial.println(F("FONA 808 (v1)")); break;
    case FONA808_V2:
      Serial.println(F("FONA 808 (v2)")); break;
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default:
      Serial.println(F("???")); break;
  }
carlosbvz commented 6 years ago

Hi Guys,

Same error here and I tried to replace the softSerial with those lines in order to use the hardwareSerial.

I got this error: (Any help would be appreciated)

FONAtest:46: error: no matching function for call to 'HardwareSerial::HardwareSerial(int)' HardwareSerial Serial2(2); ^ /var/folders/tp/7_mqsr6d4t39s0pj11bnng69_rx_kz/T/arduino_modified_sketch_589308/FONAtest.ino:46:25: note: candidates are: In file included from /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:232:0, from sketch/FONAtest.ino.cpp:1: /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.h:117:12: note: HardwareSerial::HardwareSerial(volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*) inline HardwareSerial( ^ /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.h:117:12: note: candidate expects 6 arguments, 1 provided /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.h:93:7: note: constexpr HardwareSerial::HardwareSerial(const HardwareSerial&) class HardwareSerial : public Stream ^ /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.h:93:7: note: no known conversion for argument 1 from 'int' to 'const HardwareSerial&' /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.h:93:7: note: constexpr HardwareSerial::HardwareSerial(HardwareSerial&&) /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.h:93:7: note: no known conversion for argument 1 from 'int' to 'HardwareSerial&&' exit status 1 no matching function for call to 'HardwareSerial::HardwareSerial(int)'

me-no-dev commented 6 years ago

You selected the wrong board in the menu.

mobimation commented 6 years ago

If you are using the sketch provided for Fona 32u4 they have a part to confuse the enemy:

You'll need to make a simple change to the sketch. At the top find these lines: Download file Copy Code

include "Adafruit_FONA.h"

define FONA_RX 2

define FONA_TX 3

define FONA_RST 4

and change them to: Download file Copy Code

define FONA_RX 9

define FONA_TX 8

define FONA_RST 4

define FONA_RI 7

A subtle mapping difference think you not ? :) Well once changed the sketch works. No doubt many moons have passed since and there have had plenty of time to modifying that sketch instead of leaving it up to the developer. But maybe it is about picking out the cherry developers.

beegee-tokyo commented 6 years ago

Added your findings to the Wiki

AlphaMinor commented 6 years ago

@architmuchhal12 did u use a hardware serial library?

RicoJia commented 6 years ago

@architmuchhal12 @AlphaMinor Hi all, Try to check the physical connections: Fona_TX to your arduino pins! I am using a shield and had EXACTLY the same problem. However, I found out this bug and now it's working totally fine.

AustinGregory223 commented 6 years ago

Hey Guys, I have a DFRobot Sim 7000c and am getting the same issue every time "Couldn't find FONA" This is my Code Much appreciated if anyone could help becasue im building a GPS Tracker

AustinGregory223 commented 6 years ago

/*** 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!

Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****/

/* THIS CODE IS STILL IN PROGRESS!

Open up the serial console on the Arduino at 115200 baud to interact with FONA

Note that if you need to set a GPRS APN, username, and password scroll down to the commented section below at the end of the setup() function. */

include "Adafruit_FONA.h"

define FONA_RX 2

define FONA_TX 3

define FONA_RST 4

// this is a large buffer for replies char replybuffer[255];

// We default to using software serial. If you want to use hardware serial // (because softserial isnt supported) comment out the following three lines // and uncomment the HardwareSerial line

include

SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX); SoftwareSerial *fonaSerial = &fonaSS;

// Hardware serial is also possible! // HardwareSerial *fonaSerial = &Serial1;

// Use this for FONA 800 and 808s Adafruit_FONA fona = Adafruit_FONA(FONA_RST); // Use this one for FONA 3G //Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

uint8_t type;

void setup() { while (!Serial);

Serial.begin(115200); Serial.println(F("FONA basic test")); Serial.println(F("Initializing....(May take 3 seconds)"));

fonaSerial->begin(4800); if (! fona.begin(*fonaSerial)) { Serial.println(F("Couldn't find FONA")); while (1); } type = fona.type(); Serial.println(F("FONA is OK")); Serial.print(F("Found ")); switch (type) { case FONA800L: Serial.println(F("FONA 800L")); break; case FONA800H: Serial.println(F("FONA 800H")); break; case FONA808_V1: Serial.println(F("FONA 808 (v1)")); break; case FONA808_V2: Serial.println(F("FONA 808 (v2)")); break; case FONA3G_A: Serial.println(F("FONA 3G (American)")); break; case FONA3G_E: Serial.println(F("FONA 3G (European)")); break; default: Serial.println(F("???")); break; }

// Print module IMEI number. char imei[16] = {0}; // MUST use a 16 character buffer for IMEI! uint8_t imeiLen = fona.getIMEI(imei); if (imeiLen > 0) { Serial.print("Module IMEI: "); Serial.println(imei); }

// Optionally 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.setGPRSNetworkSettings(F("your APN"), F("your username"), F("your password"));

// 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);

printMenu(); }

void printMenu(void) { Serial.println(F("-------------------------------------")); Serial.println(F("[?] Print this menu")); Serial.println(F("[a] read the ADC 2.8V max (FONA800 & 808)")); Serial.println(F("[b] read the Battery V and % charged")); Serial.println(F("[C] read the SIM CCID")); Serial.println(F("[U] Unlock SIM with PIN code")); Serial.println(F("[i] read RSSI")); Serial.println(F("[n] get Network status")); Serial.println(F("[v] set audio Volume")); Serial.println(F("[V] get Volume")); Serial.println(F("[H] set Headphone audio (FONA800 & 808)")); Serial.println(F("[e] set External audio (FONA800 & 808)")); Serial.println(F("[T] play audio Tone")); Serial.println(F("[P] PWM/Buzzer out (FONA800 & 808)"));

// FM (SIM800 only!) Serial.println(F("[f] tune FM radio (FONA800)")); Serial.println(F("[F] turn off FM (FONA800)")); Serial.println(F("[m] set FM volume (FONA800)")); Serial.println(F("[M] get FM volume (FONA800)")); Serial.println(F("[q] get FM station signal level (FONA800)"));

// Phone Serial.println(F("[c] make phone Call")); Serial.println(F("[A] get call status")); Serial.println(F("[h] Hang up phone")); Serial.println(F("[p] Pick up phone"));

// SMS Serial.println(F("[N] Number of SMSs")); 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 network time sync (FONA 800 & 808)")); Serial.println(F("[Y] Enable NTP time sync (GPRS FONA 800 & 808)")); Serial.println(F("[t] Get network time"));

// GPRS Serial.println(F("[G] Enable GPRS")); Serial.println(F("[g] Disable GPRS")); Serial.println(F("[l] Query GSMLOC (GPRS)")); Serial.println(F("[w] Read webpage (GPRS)")); Serial.println(F("[W] Post to website (GPRS)"));

// GPS if ((type == FONA3G_A) || (type == FONA3G_E) || (type == FONA808_V1) || (type == FONA808_V2)) { Serial.println(F("[O] Turn GPS on (FONA 808 & 3G)")); Serial.println(F("[o] Turn GPS off (FONA 808 & 3G)")); Serial.println(F("[L] Query GPS location (FONA 808 & 3G)")); if (type == FONA808_V1) { Serial.println(F("[x] GPS fix status (FONA808 v1 only)")); } Serial.println(F("[E] Raw NMEA out (FONA808)")); }

Serial.println(F("[S] create Serial passthru tunnel")); Serial.println(F("-------------------------------------")); Serial.println(F(""));

} 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 (! 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;
  }

/*** Audio ***/
case 'v': {
    // set volume
    flushSerial();
    if ( (type == FONA3G_A) || (type == FONA3G_E) ) {
      Serial.print(F("Set Vol [0-8] "));
    } else {
      Serial.print(F("Set Vol % [0-100] "));
    }
    uint8_t vol = readnumber();
    Serial.println();
    if (! fona.setVolume(vol)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    break;
  }

case 'V': {
    uint8_t v = fona.getVolume();
    Serial.print(v);
    if ( (type == FONA3G_A) || (type == FONA3G_E) ) {
      Serial.println(" / 8");
    } else {
      Serial.println("%");
    }
    break;
  }

case 'H': {
    // Set Headphone output
    if (! fona.setAudio(FONA_HEADSETAUDIO)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    fona.setMicVolume(FONA_HEADSETAUDIO, 15);
    break;
  }
case 'e': {
    // Set External output
    if (! fona.setAudio(FONA_EXTAUDIO)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }

    fona.setMicVolume(FONA_EXTAUDIO, 10);
    break;
  }

case 'T': {
    // play tone
    flushSerial();
    Serial.print(F("Play tone #"));
    uint8_t kittone = readnumber();
    Serial.println();
    // play for 1 second (1000 ms)
    if (! fona.playToolkitTone(kittone, 1000)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    break;
  }

/*** FM Radio ***/

case 'f': {
    // get freq
    flushSerial();
    Serial.print(F("FM Freq (eg 1011 == 101.1 MHz): "));
    uint16_t station = readnumber();
    Serial.println();
    // FM radio ON using headset
    if (fona.FMradio(true, FONA_HEADSETAUDIO)) {
      Serial.println(F("Opened"));
    }
    if (! fona.tuneFMradio(station)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("Tuned"));
    }
    break;
  }
case 'F': {
    // FM radio off
    if (! fona.FMradio(false)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    break;
  }
case 'm': {
    // Set FM volume.
    flushSerial();
    Serial.print(F("Set FM Vol [0-6]:"));
    uint8_t vol = readnumber();
    Serial.println();
    if (!fona.setFMVolume(vol)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    break;
  }
case 'M': {
    // Get FM volume.
    uint8_t fmvol = fona.getFMVolume();
    if (fmvol < 0) {
      Serial.println(F("Failed"));
    } else {
      Serial.print(F("FM volume: "));
      Serial.println(fmvol, DEC);
    }
    break;
  }
case 'q': {
    // Get FM station signal level (in decibels).
    flushSerial();
    Serial.print(F("FM Freq (eg 1011 == 101.1 MHz): "));
    uint16_t station = readnumber();
    Serial.println();
    int8_t level = fona.getFMSignalLevel(station);
    if (level < 0) {
      Serial.println(F("Failed! Make sure FM radio is on (tuned to station)."));
    } else {
      Serial.print(F("Signal level (dB): "));
      Serial.println(level, DEC);
    }
    break;
  }

/*** PWM ***/

case 'P': {
    // PWM Buzzer output @ 2KHz max
    flushSerial();
    Serial.print(F("PWM Freq, 0 = Off, (1-2000): "));
    uint16_t freq = readnumber();
    Serial.println();
    if (! fona.setPWM(freq)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    break;
  }

/*** Call ***/
case 'c': {
    // call a phone!
    char number[30];
    flushSerial();
    Serial.print(F("Call #"));
    readline(number, 30);
    Serial.println();
    Serial.print(F("Calling ")); Serial.println(number);
    if (!fona.callPhone(number)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("Sent!"));
    }

    break;
  }
case 'A': {
    // get call status
    int8_t callstat = fona.getCallStatus();
    switch (callstat) {
      case 0: Serial.println(F("Ready")); break;
      case 1: Serial.println(F("Could not get status")); break;
      case 3: Serial.println(F("Ringing (incoming)")); break;
      case 4: Serial.println(F("Ringing/in progress (outgoing)")); break;
      default: Serial.println(F("Unknown")); break;
    }
    break;
  }

case 'h': {
    // hang up!
    if (! fona.hangUp()) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    break;
  }

case 'p': {
    // pick up!
    if (! fona.pickUp()) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("OK!"));
    }
    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 == FONA3G_A) || (type == FONA3G_E) ) {
      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.enableNetworkTimeSync(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 (SIM808 only) */

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': {
    // check for GPS location
    char gpsdata[120];
    fona.getGPS(0, gpsdata, 120);
    if (type == FONA808_V1)
      Serial.println(F("Reply in format: mode,longitude,latitude,altitude,utctime(yyyymmddHHMMSS),ttff,satellites,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;
  }

case 'E': {
    flushSerial();
    if (type == FONA808_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 */

case 'g': {
    // turn GPRS off
    if (!fona.enableGPRS(false))
      Serial.println(F("Failed to turn off"));
    break;
  }
case 'G': {
    // turn GPRS 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("NOTE: in beta! Use small webpages to read!"));
    Serial.println(F("URL to read (e.g. www.adafruit.com/testwifi/index.html):"));
    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!

if defined(AVR_ATmega328P) || defined(AVR_ATmega168)

        loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
        UDR0 = c;

else

        Serial.write(c);

endif

        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();

if defined(AVR_ATmega328P) || defined(AVR_ATmega168)

        loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
        UDR0 = c;

else

        Serial.write(c);

endif

        length--;
        if (! length) break;
      }
    }
    Serial.println(F("\n****"));
    fona.HTTP_POST_end();
    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()); }

}

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; }

AustinGregory223 commented 6 years ago

It says to add your APN details but i am not sure where

AustinGregory223 commented 6 years ago

I am trying to follow this guys tutorial http://www.instructables.com/id/LTE-NB-IoT-Shield-for-Arduino/