Based on https://developer.mbed.org/users/jbaker66/notebook/adafruit-fona-800-minigsm/
Adafruit_FONA.h
- Committer:
- jd0205
- Date:
- 2017-05-03
- Revision:
- 0:58ff0234d7bb
File content as of revision 0:58ff0234d7bb:
/*************************************************** This is a library 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 These displays 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 ****************************************************/ /* * Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768 */ #ifndef ADAFRUIT_FONA_H #define ADAFRUIT_FONA_H #include "mbed.h" //#define ADAFRUIT_FONA_DEBUG #define FONA_HEADSETAUDIO 0 #define FONA_EXTAUDIO 1 #define FONA_STTONE_DIALTONE 1 #define FONA_STTONE_BUSY 2 #define FONA_STTONE_CONGESTION 3 #define FONA_STTONE_PATHACK 4 #define FONA_STTONE_DROPPED 5 #define FONA_STTONE_ERROR 6 #define FONA_STTONE_CALLWAIT 7 #define FONA_STTONE_RINGING 8 #define FONA_STTONE_BEEP 16 #define FONA_STTONE_POSTONE 17 #define FONA_STTONE_ERRTONE 18 #define FONA_STTONE_INDIANDIALTONE 19 #define FONA_STTONE_USADIALTONE 20 #define FONA_DEFAULT_TIMEOUT_MS 500 //timeout between send AT and reply from FONA #define FONA_HTTP_GET 0 #define FONA_HTTP_POST 1 #define FONA_HTTP_HEAD 2 #define RX_BUFFER_SIZE 255 /** Adafruit FONA 800H Class * Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768 */ class Adafruit_FONA : public Stream { public: /** Listener for FONA events. Inherit this class to customize. @code #define FONA_RST p12 #define FONA_TX p13 #define FONA_RX p14 #define FONA_RI p11 Adafruit_FONA my_fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI); DigitalOut led1(LED1); class FonaEventListener : public Adafruit_FONA::EventListener { virtual void onRing() { led1 = 1; } virtual void onNoCarrier() { led1 = 0; } }; FonaEventListener fonaEventListener; my_fona.setEventListener(&fonaEventListener); @endcode */ class EventListener { public: /** * Method called when somebody call the FONA. */ virtual void onRing() = 0; /** * Method called when the calling person stop his call. */ virtual void onNoCarrier() = 0; }; public: /** Create instance of the Adafruit_FONA @param tx Set mbed TX @param rx Set mbed RX @param rst Set reset pin @param ringIndicator Set ring indicator pin. This is to let mbed know if there is an incoming call */ Adafruit_FONA(PinName tx, PinName rx, PinName rst, PinName ringIndicator) : _rstpin(rst, false), _ringIndicatorInterruptIn(ringIndicator), apn("FONAnet"), apnusername(NULL), apnpassword(NULL), httpsredirect(false), useragent("FONA"), _incomingCall(false), eventListener(NULL), mySerial(tx, rx), rxBufferInIndex(0), rxBufferOutIndex(0), currentReceivedLineSize(0) {} /** Built-in Test to see if FONA is connected @param baudrate test and set at baudrate @return true upon success @return false upon failure. Most likely something is not hooked up. EXAMPLE CODE: @code // See if the FONA is responding // fona is an instance of Adafruit_FONA if (! fona.begin(9600)) { printf("Couldn't find FONA\r\n"); while (1); } @endcode */ bool begin(int baudrate); /** Set the event listener for incoming calls @param eventListener A pointer to the event listener @see Adafruit_FONA::EventListener for specific example */ void setEventListener(EventListener *eventListener); // Stream---------------------------------------------------------------------- virtual int _putc(int value); virtual int _getc(); /** Check if FONA has anything in its output buffer @return 0 if nothing */ int readable(void); // RTC---------------------------------------------------------------------- bool enableRTC(uint8_t i); // i = 0 <=> disable, i = 1 <=> enable // Battery and ADC---------------------------------------------------------------------- /** Get ADC voltage from external pin @param v uint16_t pointer to insert ADC voltage data @return TRUE if successful EXAMPLE CODE: @code // read the ADC // fona is an instance of Adafruit_FONA uint16_t adc; if (! fona.getADCVoltage(&adc)) { printf("Failed to read ADC\r\n"); } else { printf("ADC = %d mV\r\n", adc); } @endcode */ bool getADCVoltage(uint16_t *v); /** Get battery percentage level @param p uint16_t pointer to insert battery percent data @return TRUE if successful EXAMPLE CODE: @code // read the battery percent level // fona is an instance of Adafruit_FONA uint16_t vbatPer; if (! fona.getBattPercent(&vbatPer)) { printf("Failed to read Batt\r\n"); } else { printf("VPct = %d%%\r\n", vbatPer); } @endcode */ bool getBattPercent(uint16_t *p); /** Get battery voltage level @param v uint16_t pointer to insert battery voltage data @return TRUE if successful EXAMPLE CODE: @code // read the battery voltage // fona is an instance of Adafruit_FONA uint16_t vbat; if (! fona.getBattPercent(&vbat)) { printf("Failed to read Batt\r\n"); } else { printf("Vbat = %d%%\r\n", vbat); } @endcode */ bool getBattVoltage(uint16_t *v); // SIM query---------------------------------------------------------------------- /** Unlock SIM if needed @param pin 4 digit char arrary @return TRUE if successful */ bool unlockSIM(char *pin); /** Get the SIM chip card interface device (CCID) @param ccid make sure it is at least 21 bytes long @return length of CCID */ uint8_t getSIMCCID(char *ccid); /** Get the Network Status of FONA @return Code 0-5 @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 80 */ uint8_t getNetworkStatus(void); /** Get the RSSI of the network signal @return RSSI value in dBm per below reference EXAMPLE @code // read the RSSI uint8_t n = fona.getRSSI(); int8_t r = 0; pcSerial.printf("RSSI = %d: ", n); 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); } printf("%d dBm\r\n", r); // helper function MAP to do calculations long MAP(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } @endcode @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 82 */ uint8_t getRSSI(void); // IMEI---------------------------------------------------------------------- /** Get the International Mobile Station Equipment Identity (IMEI) @param imei A char array with minimum length 16 @return The IMEI of the device EXAMPLE CODE: @code // Print SIM card IMEI number. char imei[15] = {0}; // MUST use a 16 character buffer for IMEI! uint8_t imeiLen = fona.getIMEI(imei); //fona is an instance of Adafruit_FONA if (imeiLen > 0) { pcSerial.printf("SIM card IMEI: %s\r\n", imei); } @endcode */ uint8_t getIMEI(char *imei); // set Audio output---------------------------------------------------------------------- /** Set the Audio Output interface @param a 0 is headset, 1 is external audio @return TRUE if successful */ bool setAudio(uint8_t a); /** Set the Audio Volume @param i a unit8_t volume number @return TRUE if successful */ bool setVolume(uint8_t i); /** Get the Audio Volume @return the current volume */ uint8_t getVolume(void); bool playToolkitTone(uint8_t t, uint16_t len); bool setMicVolume(uint8_t a, uint8_t level); bool playDTMF(char tone); // FM radio functions---------------------------------------------------------------------- /** Tune the FM radio @param station frequency, for example 107.9 MHz -> 1079 @return TRUE if successful */ bool tuneFMradio(uint16_t station); /** FM radio set output @param onoff bool to turn on if TRUE @param a 0 (default) is headset, 1 is external audio @return TRUE if successful */ bool FMradio(bool onoff, uint8_t a = FONA_HEADSETAUDIO); /** Set the FM Radio Volume @param i a unit8_t volume number @return TRUE if successful */ bool setFMVolume(uint8_t i); /** Get the FM Volume @return the current FM volume */ int8_t getFMVolume(); /** Get the FM signal strength @param station a unit8_t volume number @return TRUE if successful */ int8_t getFMSignalLevel(uint16_t station); // SMS handling---------------------------------------------------------------------- /** Set the SMS Interrupt @param i 0 = OFF, 1 = ON with TCPIP, FTP, and URC control Ring Indicator Pin, 2 = ON with only TCPIP control @return TRUE if successful @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 152 */ bool setSMSInterrupt(uint8_t i); /** Get SMS Interrupt Setting @return setting @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 152 */ uint8_t getSMSInterrupt(void); /** Set the SMS Interrupt @return number of SMS messages in inbox */ int8_t getNumSMS(void); /** Read SMS @param i sms number in memory @param smsbuff char pointer to char array @param max Maximum length of smsbuff @param readsize the size in bytes of the SMS @return TRUE if successful */ bool readSMS(uint8_t i, char *smsbuff, uint16_t max, uint16_t *readsize); /** Send SMS @param smsaddr Phone number to send out @param smsmsg Char array containing message @return TRUE if successful */ bool sendSMS(char *smsaddr, char *smsmsg); /** Delete SMS @param i number of SMS in memory @return TRUE if successful */ bool deleteSMS(uint8_t i); /** Send SMS @param i Number of SMS in memory @param sender Char array to store the sender number @param senderlen length of sender @return TRUE if successful */ bool getSMSSender(uint8_t i, char *sender, int senderlen); // Time---------------------------------------------------------------------- /** Enable FONA to sync time with the cellular network @param onoff on = true, off = false @return TRUE if successful */ bool enableNetworkTimeSync(bool onoff); /** Enable FONA to sync time with the time server @param onoff true = on, false = off @return TRUE if successful */ bool enableNTPTimeSync(bool onoff, const char* ntpserver=0); /** Retrieve the current time from the enabled server @param buff char array to store time value. Given as "yy/MM/dd,hh:mm:ss+zz" @param maxlen Maximum length of the char array @return TRUE if successful */ bool getTime(char* buff, uint16_t maxlen); // GPRS handling---------------------------------------------------------------------- bool enableGPRS(bool onoff); uint8_t GPRSstate(void); bool getGSMLoc(uint16_t *replycode, char *buff, uint16_t maxlen); bool getGSMLoc(float *lat, float *lon); void setGPRSNetworkSettings(const char* apn, const char* username=0, const char* password=0); // GPS handling---------------------------------------------------------------------- bool enableGPS(bool onoff); int8_t GPSstatus(void); uint8_t getGPS(uint8_t arg, char *buffer, uint8_t maxbuff); bool getGPS(float *lat, float *lon, float *speed_kph=0, float *heading=0, float *altitude=0); bool enableGPSNMEA(uint8_t nmea); // TCP raw connections---------------------------------------------------------------------- bool TCPconnect(char *server, uint16_t port); bool TCPclose(void); bool TCPconnected(void); bool TCPsend(char *packet, uint8_t len); uint16_t TCPavailable(void); uint16_t TCPread(uint8_t *buff, uint8_t len); // HTTP low level interface (maps directly to SIM800 commands).---------------------------------------------------------------------- bool HTTP_init(); bool HTTP_term(); void HTTP_para_start(const char* parameter, bool quoted = true); bool HTTP_para_end(bool quoted = true); bool HTTP_para(const char* parameter, const char *value); bool HTTP_para(const char* parameter, int32_t value); bool HTTP_data(uint32_t size, uint32_t maxTime=10000); bool HTTP_action(uint8_t method, uint16_t *status, uint16_t *datalen, int32_t timeout = 10000); bool HTTP_readall(uint16_t *datalen); bool HTTP_ssl(bool onoff); // HTTP high level interface (easier to use, less flexible).---------------------------------------------------------------------- bool HTTP_GET_start(char *url, uint16_t *status, uint16_t *datalen); void HTTP_GET_end(void); bool HTTP_POST_start(char *url, const char* contenttype, const uint8_t *postdata, uint16_t postdatalen, uint16_t *status, uint16_t *datalen); void HTTP_POST_end(void); void setUserAgent(const char* useragent); // HTTPS---------------------------------------------------------------------- void setHTTPSRedirect(bool onoff); // PWM (buzzer)---------------------------------------------------------------------- /** Control the buzzer capability of the PWM out on the FONA @param period of the buzzing cycle (max 2000) @param duty the duty cycle of the buzzer (0 to 100) @return TRUE if successful */ bool setPWM(uint16_t period, uint8_t duty = 50); // Phone calls---------------------------------------------------------------------- /** Call a phone @param phonenum a character array of the phone number @return TRUE if successful */ bool callPhone(char *phonenum); /** Hang up a phone call */ bool hangUp(void); /** Answer a phone call */ bool pickUp(void); /** Enable/disable caller ID @param enable true to enable, false to disable @return TRUE if successful */ bool callerIdNotification(bool enable); /** Retrieve the incoming call number @param phonenum a character array of the phone number calling @return TRUE if successful */ bool incomingCallNumber(char* phonenum); // Helper functions to verify responses. bool expectReply(const char* reply, uint16_t timeout = 10000); private: DigitalOut _rstpin; InterruptIn _ringIndicatorInterruptIn; char replybuffer[255]; // the output of getreply(), readline() is the function that changes the replybuffer char* apn; char* apnusername; char* apnpassword; bool httpsredirect; char* useragent; volatile bool _incomingCall; EventListener *eventListener; Serial mySerial; // Circular buffer used to receive serial data from an interruption int rxBuffer[RX_BUFFER_SIZE + 1]; volatile int rxBufferInIndex; // Index where new data is added to the buffer volatile int rxBufferOutIndex; // Index where data is removed from the buffer char currentReceivedLine[RX_BUFFER_SIZE]; // Array containing the current received line int currentReceivedLineSize; inline bool isRxBufferFull() { return ((rxBufferInIndex + 1) % RX_BUFFER_SIZE) == rxBufferOutIndex; } inline bool isRxBufferEmpty() { return rxBufferInIndex == rxBufferOutIndex; } inline void incrementRxBufferInIndex() { rxBufferInIndex = (rxBufferInIndex + 1) % RX_BUFFER_SIZE; } inline void incrementRxBufferOutIndex() { rxBufferOutIndex = (rxBufferOutIndex + 1) % RX_BUFFER_SIZE; } /** * Method called when Serial data is received (interrupt routine). */ void onSerialDataReceived(); // HTTP helpers bool HTTP_setup(char *url); void flushInput(); uint16_t readRaw(uint16_t b); uint8_t readline(uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS, bool multiline = false); uint8_t getReply(const char* send, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); uint8_t getReply(const char* prefix, char *suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); uint8_t getReply(const char* prefix, int32_t suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); uint8_t getReply(const char* prefix, int32_t suffix1, int32_t suffix2, uint16_t timeout); // Don't set default value or else function call is ambiguous. uint8_t getReplyQuoted(const char* prefix, const char* suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); bool sendCheckReply(const char* send, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); bool sendCheckReply(const char* prefix, char *suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); bool sendCheckReply(const char* prefix, int32_t suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); bool sendCheckReply(const char* prefix, int32_t suffix, int32_t suffix2, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); bool sendCheckReplyQuoted(const char* prefix, const char* suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS); bool parseReply(const char* toreply, uint16_t *v, char divider = ',', uint8_t index=0); bool parseReply(const char* toreply, char *v, char divider = ',', uint8_t index=0); bool parseReplyQuoted(const char* toreply, char* v, int maxlen, char divider, uint8_t index); bool sendParseReply(const char* tosend, const char* toreply, uint16_t *v, char divider = ',', uint8_t index = 0); void onIncomingCall(); }; #endif