Version using RawSerial instead of Serial (thread safe)

Fork of FONA_Cellphone_Library by Dream Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_FONA.h Source File

Adafruit_FONA.h

00001 /***************************************************
00002   This is a library for our Adafruit FONA Cellular Module
00003 
00004   Designed specifically to work with the Adafruit FONA
00005   ----> http://www.adafruit.com/products/1946
00006   ----> http://www.adafruit.com/products/1963
00007 
00008   These displays use TTL Serial to communicate, 2 pins are required to
00009   interface
00010   Adafruit invests time and resources providing this open source code,
00011   please support Adafruit and open-source hardware by purchasing
00012   products from Adafruit!
00013 
00014   Written by Limor Fried/Ladyada for Adafruit Industries.
00015   BSD license, all text above must be included in any redistribution
00016  ****************************************************/
00017  
00018  /*
00019   *  Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768
00020   */
00021  
00022 #ifndef ADAFRUIT_FONA_H
00023 #define ADAFRUIT_FONA_H
00024 
00025 #include "mbed.h"
00026 #include "rtos.h"
00027 
00028 //#define ADAFRUIT_FONA_DEBUG
00029 
00030 #define FONA_HEADSETAUDIO 0
00031 #define FONA_EXTAUDIO 1
00032 
00033 #define FONA_STTONE_DIALTONE 1
00034 #define FONA_STTONE_BUSY 2
00035 #define FONA_STTONE_CONGESTION 3
00036 #define FONA_STTONE_PATHACK 4
00037 #define FONA_STTONE_DROPPED 5
00038 #define FONA_STTONE_ERROR 6
00039 #define FONA_STTONE_CALLWAIT 7
00040 #define FONA_STTONE_RINGING 8
00041 #define FONA_STTONE_BEEP 16
00042 #define FONA_STTONE_POSTONE 17
00043 #define FONA_STTONE_ERRTONE 18
00044 #define FONA_STTONE_INDIANDIALTONE 19
00045 #define FONA_STTONE_USADIALTONE 20
00046 
00047 #define FONA_DEFAULT_TIMEOUT_MS 500 //timeout between send AT and reply from FONA
00048 
00049 #define FONA_HTTP_GET   0
00050 #define FONA_HTTP_POST  1
00051 #define FONA_HTTP_HEAD  2 
00052 
00053 #define RX_BUFFER_SIZE  255
00054 
00055 /** Adafruit FONA 800H Class
00056 *  Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768
00057 */
00058 
00059 class Adafruit_FONA : public Stream {
00060     public:
00061 /**
00062 Listener for FONA events. Inherit this class to customize.
00063 @code
00064 #define FONA_RST p12
00065 #define FONA_TX p13
00066 #define FONA_RX p14
00067 #define FONA_RI p11
00068 
00069 Adafruit_FONA my_fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
00070 DigitalOut led1(LED1); 
00071 class FonaEventListener : public Adafruit_FONA::EventListener {
00072     virtual void onRing() {
00073         led1 = 1;
00074 }
00075 
00076     virtual void onNoCarrier() {
00077         led1 = 0; 
00078     }
00079 };
00080 FonaEventListener fonaEventListener;
00081 my_fona.setEventListener(&fonaEventListener);
00082 @endcode
00083 */
00084         
00085         class EventListener {
00086             public:
00087                 /**
00088                  * Method called when somebody call the FONA.
00089                  */
00090                 virtual void onRing() = 0;
00091                 
00092                 /**
00093                  * Method called when the calling person stop his call.
00094                  */
00095                 virtual void onNoCarrier() = 0;
00096         };
00097     
00098     public:
00099         /** Create instance of the Adafruit_FONA
00100         @param tx Set mbed TX 
00101         @param rx Set mbed RX
00102         @param rst Set reset pin
00103         @param ringIndicator Set ring indicator pin. This is to let mbed know if there is an incoming call
00104         */
00105         
00106         Adafruit_FONA(PinName tx, PinName rx, PinName rst, PinName ringIndicator) :
00107             _rstpin(rst, false), _ringIndicatorInterruptIn(ringIndicator),
00108             apn("FONAnet"), apnusername(NULL), apnpassword(NULL), httpsredirect(false), useragent("FONA"),
00109             _incomingCall(false), eventListener(NULL), mySerial(tx, rx), rxBufferInIndex(0), rxBufferOutIndex(0), 
00110             currentReceivedLineSize(0) {}
00111             
00112         /** Built-in Test to see if FONA is connected
00113         @param baudrate test and set at baudrate
00114         @return true upon success
00115         @return false upon failure. Most likely something is not hooked up.
00116         
00117 EXAMPLE CODE:
00118         @code
00119 // See if the FONA is responding
00120 // fona is an instance of Adafruit_FONA
00121 if (! fona.begin(9600)) {
00122     printf("Couldn't find FONA\r\n");
00123     while (1);
00124 }
00125         @endcode
00126         */
00127         bool begin(int baudrate);
00128         
00129         /** Set the event listener for incoming calls
00130         @param eventListener A pointer to the event listener
00131         @see Adafruit_FONA::EventListener for specific example
00132         */
00133         
00134         void setEventListener(EventListener *eventListener);
00135         
00136         // Stream----------------------------------------------------------------------
00137         virtual int _putc(int value);
00138         virtual int _getc();
00139         
00140         /** Check if FONA has anything in its output buffer
00141         @return 0 if nothing
00142         */
00143         int readable(void);
00144         
00145         // RTC----------------------------------------------------------------------
00146         bool enableRTC(uint8_t i); // i = 0 <=> disable, i = 1 <=> enable
00147         
00148         // Battery and ADC----------------------------------------------------------------------
00149         /** Get ADC voltage from external pin
00150         @param v uint16_t pointer to insert ADC voltage data
00151         @return TRUE if successful
00152         
00153 EXAMPLE CODE:
00154         @code
00155 // read the ADC
00156 // fona is an instance of Adafruit_FONA
00157 uint16_t adc;
00158 if (! fona.getADCVoltage(&adc)) {
00159     printf("Failed to read ADC\r\n");
00160 } 
00161 else {
00162     printf("ADC = %d mV\r\n", adc);
00163 }
00164         @endcode
00165         */
00166         bool getADCVoltage(uint16_t *v);
00167         
00168         /** Get battery percentage level
00169         @param p uint16_t pointer to insert battery percent data
00170         @return TRUE if successful
00171         
00172 EXAMPLE CODE:
00173         @code
00174 // read the battery percent level
00175 // fona is an instance of Adafruit_FONA
00176 uint16_t vbatPer;
00177 if (! fona.getBattPercent(&vbatPer)) {
00178     printf("Failed to read Batt\r\n");
00179 } 
00180 else {
00181     printf("VPct = %d%%\r\n", vbatPer);
00182 }
00183         @endcode
00184         */
00185         
00186         bool getBattPercent(uint16_t *p);
00187         
00188         /** Get battery voltage level
00189         @param v uint16_t pointer to insert battery voltage data
00190         @return TRUE if successful
00191         
00192 EXAMPLE CODE:
00193         @code
00194 // read the battery voltage
00195 // fona is an instance of Adafruit_FONA
00196 uint16_t vbat;
00197 if (! fona.getBattPercent(&vbat)) {
00198     printf("Failed to read Batt\r\n");
00199 } 
00200 else {
00201     printf("Vbat = %d%%\r\n", vbat);
00202 }
00203         @endcode
00204         */
00205         bool getBattVoltage(uint16_t *v);
00206         
00207         // SIM query----------------------------------------------------------------------
00208         /** Unlock SIM if needed
00209         @param pin 4 digit char arrary
00210         @return TRUE if successful
00211         */        
00212         bool unlockSIM(char *pin);
00213         /** Get the SIM chip card interface device (CCID)
00214         @param ccid make sure it is at least 21 bytes long
00215         @return length of CCID
00216         */
00217         
00218         uint8_t getSIMCCID(char *ccid);
00219         /** Get the Network Status of FONA
00220         @return Code 0-5 
00221         @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 80
00222         */
00223         uint8_t getNetworkStatus(void);
00224         
00225         /** Set mobile data to international roaming
00226         @return code -1, 1
00227         */
00228         uint8_t setNetworkRoaming();
00229         
00230         /** Get the RSSI of the network signal
00231         @return RSSI value in dBm per below reference
00232         
00233         EXAMPLE
00234         @code
00235 // read the RSSI
00236 uint8_t n = fona.getRSSI();
00237 int8_t r = 0;
00238 
00239 pcSerial.printf("RSSI = %d: ", n);
00240 if (n == 0) r = -115;
00241 if (n == 1) r = -111;
00242 if (n == 31) r = -52;
00243 if ((n >= 2) && (n <= 30)) {
00244     r = map(n, 2, 30, -110, -54);
00245 }
00246 printf("%d dBm\r\n", r);
00247 
00248 // helper function MAP to do calculations
00249 long MAP(long x, long in_min, long in_max, long out_min, long out_max)
00250 {
00251     return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
00252 }
00253         @endcode
00254         @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 82
00255         */
00256         uint8_t getRSSI(void);
00257         
00258         // IMEI----------------------------------------------------------------------
00259         /** Get the International Mobile Station Equipment Identity (IMEI)
00260         @param imei A char array with minimum length 16
00261         @return The IMEI of the device
00262         
00263 EXAMPLE CODE:
00264         @code
00265 // Print SIM card IMEI number.
00266 char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
00267 uint8_t imeiLen = fona.getIMEI(imei); //fona is an instance of Adafruit_FONA
00268 if (imeiLen > 0) {
00269     pcSerial.printf("SIM card IMEI: %s\r\n", imei);
00270 }
00271         @endcode
00272         */
00273         uint8_t getIMEI(char *imei);
00274         
00275         // set Audio output----------------------------------------------------------------------
00276         /** Set the Audio Output interface
00277         @param a 0 is headset, 1 is external audio
00278         @return TRUE if successful
00279         */
00280         bool setAudio(uint8_t a);
00281 
00282         /** Set the Audio Volume
00283         @param i a unit8_t volume number
00284         @return TRUE if successful
00285         */
00286         bool setVolume(uint8_t i);
00287 
00288         /** Get the Audio Volume
00289         @return the current volume
00290         */
00291         uint8_t getVolume(void);
00292         bool playToolkitTone(uint8_t t, uint16_t len);
00293         bool setMicVolume(uint8_t a, uint8_t level);
00294         bool playDTMF(char tone);
00295         
00296         // FM radio functions----------------------------------------------------------------------
00297         /** Tune the FM radio
00298         @param station frequency, for example 107.9 MHz -> 1079 
00299         @return TRUE if successful
00300         */
00301         bool tuneFMradio(uint16_t station);
00302 
00303         /** FM radio set output
00304         @param onoff bool to turn on if TRUE
00305         @param a 0 (default) is headset, 1 is external audio
00306         @return TRUE if successful
00307         */
00308         bool FMradio(bool onoff, uint8_t a = FONA_HEADSETAUDIO);
00309 
00310         /** Set the FM Radio Volume
00311         @param i a unit8_t volume number
00312         @return TRUE if successful
00313         */
00314         bool setFMVolume(uint8_t i);
00315 
00316         /** Get the FM Volume
00317         @return the current FM volume
00318         */
00319         int8_t getFMVolume();
00320 
00321         /** Get the FM signal strength
00322         @param station a unit8_t volume number
00323         @return TRUE if successful
00324         */
00325         int8_t getFMSignalLevel(uint16_t station);
00326         
00327         // SMS handling----------------------------------------------------------------------
00328         /** Set the SMS Interrupt
00329         @param i 0 = OFF, 1 = ON with TCPIP, FTP, and URC control Ring Indicator Pin, 2 = ON with only TCPIP control
00330         @return TRUE if successful
00331         @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 152
00332         */
00333         bool setSMSInterrupt(uint8_t i);
00334 
00335         /** Get SMS Interrupt Setting
00336         @return setting
00337         @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 152
00338         */
00339         uint8_t getSMSInterrupt(void);
00340 
00341         /** Set the SMS Interrupt
00342         @return number of SMS messages in inbox
00343         */
00344         int8_t getNumSMS(void);
00345 
00346         /** Read SMS
00347         @param i sms number in memory
00348         @param smsbuff char pointer to char array
00349         @param max Maximum length of smsbuff
00350         @param readsize the size in bytes of the SMS
00351         @return TRUE if successful
00352         */
00353         bool readSMS(uint8_t i, char *smsbuff, uint16_t max, uint16_t *readsize);
00354 
00355         /** Send SMS
00356         @param smsaddr Phone number to send out
00357         @param smsmsg Char array containing message
00358         @return TRUE if successful
00359         */
00360         bool sendSMS(char *smsaddr, char *smsmsg);
00361 
00362         /** Delete SMS
00363         @param i number of SMS in memory
00364         @return TRUE if successful
00365         */
00366         bool deleteSMS(uint8_t i);
00367 
00368         /** Send SMS
00369         @param i Number of SMS in memory
00370         @param sender Char array to store the sender number
00371         @param senderlen length of sender
00372         @return TRUE if successful
00373         */
00374         bool getSMSSender(uint8_t i, char *sender, int senderlen);
00375         
00376         // Time----------------------------------------------------------------------
00377         /** Enable FONA to sync time with the cellular network
00378         @param onoff on = true, off = false
00379         @return TRUE if successful
00380         */
00381         bool enableNetworkTimeSync(bool onoff);
00382 
00383         /** Enable FONA to sync time with the time server
00384         @param onoff true = on, false = off
00385         @return TRUE if successful
00386         */
00387         bool enableNTPTimeSync(bool onoff, const char* ntpserver=0);
00388 
00389         /** Retrieve the current time from the enabled server
00390         @param buff char array to store time value. Given as "yy/MM/dd,hh:mm:ss+zz"
00391         @param maxlen Maximum length of the char array
00392         @return TRUE if successful
00393         */
00394         bool getTime(char* buff, uint16_t maxlen);
00395 
00396         // GPRS handling----------------------------------------------------------------------
00397         bool enableGPRS(bool onoff);
00398         uint8_t GPRSstate(void);
00399         bool getGSMLoc(uint16_t *replycode, char *buff, uint16_t maxlen);
00400         bool getGSMLoc(float *lat, float *lon);
00401         void setGPRSNetworkSettings(const char* apn, const char* username=0, const char* password=0);
00402 
00403         // GPS handling----------------------------------------------------------------------
00404         bool enableGPS(bool onoff);
00405         int8_t GPSstatus(void);
00406         uint8_t getGPS(uint8_t arg, char *buffer, uint8_t maxbuff);
00407         bool getGPS(float *lat, float *lon, float *speed_kph=0, float *heading=0, float *altitude=0);
00408         bool enableGPSNMEA(uint8_t nmea);
00409 
00410         // TCP raw connections----------------------------------------------------------------------
00411         bool TCPconnect(char *server, uint16_t port);
00412         bool TCPclose(void);
00413         bool TCPconnected(void);
00414         bool TCPsend(char *packet, uint8_t len);
00415         uint16_t TCPavailable(void);
00416         uint16_t TCPread(uint8_t *buff, uint8_t len);
00417 
00418         // HTTP low level interface (maps directly to SIM800 commands).----------------------------------------------------------------------
00419         bool HTTP_init();
00420         bool HTTP_term();
00421         void HTTP_para_start(const char* parameter, bool quoted = true);
00422         bool HTTP_para_end(bool quoted = true);
00423         bool HTTP_para(const char* parameter, const char *value);
00424         bool HTTP_para(const char* parameter, int32_t value);
00425         bool HTTP_data(uint32_t size, uint32_t maxTime=10000);
00426         bool HTTP_action(uint8_t method, uint16_t *status, uint16_t *datalen, int32_t timeout = 10000);
00427         bool HTTP_readall(uint16_t *datalen);
00428         bool HTTP_ssl(bool onoff);
00429 
00430         // HTTP high level interface (easier to use, less flexible).----------------------------------------------------------------------
00431         bool HTTP_GET_start(char *url, uint16_t *status, uint16_t *datalen);
00432         void HTTP_GET_end(void);
00433         bool HTTP_POST_start(char *url, const char* contenttype, const uint8_t *postdata, uint16_t postdatalen, uint16_t *status, uint16_t *datalen);
00434         void HTTP_POST_end(void);
00435         void setUserAgent(const char* useragent);
00436 
00437         // HTTPS----------------------------------------------------------------------
00438         void setHTTPSRedirect(bool onoff);
00439 
00440         // PWM (buzzer)----------------------------------------------------------------------
00441         /** Control the buzzer capability of the PWM out on the FONA
00442         @param period of the buzzing cycle (max 2000)
00443         @param duty the duty cycle of the buzzer (0 to 100)
00444         @return TRUE if successful
00445         */
00446         bool setPWM(uint16_t period, uint8_t duty = 50);
00447 
00448         // Phone calls----------------------------------------------------------------------
00449         /** Call a phone
00450         @param phonenum a character array of the phone number
00451         @return TRUE if successful
00452         */
00453         bool callPhone(char *phonenum);
00454 
00455         /** Hang up a phone call
00456         */
00457         bool hangUp(void);
00458 
00459         /** Answer a phone call
00460         */
00461         bool pickUp(void);
00462 
00463         /** Enable/disable caller ID
00464         @param enable true to enable, false to disable
00465         @return TRUE if successful
00466         */
00467         bool callerIdNotification(bool enable);
00468 
00469         /** Retrieve the incoming call number
00470         @param phonenum a character array of the phone number calling
00471         @return TRUE if successful
00472         */
00473         bool incomingCallNumber(char* phonenum);
00474 
00475         // Helper functions to verify responses.
00476         bool expectReply(const char* reply, uint16_t timeout = 10000);
00477 
00478     private:
00479         DigitalOut _rstpin;
00480         InterruptIn _ringIndicatorInterruptIn;
00481 
00482         char replybuffer[255]; // the output of getreply(), readline() is the function that changes the replybuffer
00483         char* apn;
00484         char* apnusername;
00485         char* apnpassword;
00486         bool httpsredirect;
00487         char* useragent;
00488 
00489         volatile bool _incomingCall;
00490         EventListener *eventListener;
00491         RawSerial mySerial;
00492 
00493         // Circular buffer used to receive serial data from an interruption
00494         int rxBuffer[RX_BUFFER_SIZE + 1];
00495         volatile int rxBufferInIndex; // Index where new data is added to the buffer
00496         volatile int rxBufferOutIndex; // Index where data is removed from the buffer
00497         char currentReceivedLine[RX_BUFFER_SIZE]; // Array containing the current received line
00498         int currentReceivedLineSize;
00499 
00500         inline bool isRxBufferFull() {
00501             return ((rxBufferInIndex + 1) % RX_BUFFER_SIZE) == rxBufferOutIndex;
00502         }
00503 
00504         inline bool isRxBufferEmpty() {
00505             return rxBufferInIndex == rxBufferOutIndex;
00506         }
00507 
00508         inline void incrementRxBufferInIndex() {
00509             rxBufferInIndex = (rxBufferInIndex + 1) % RX_BUFFER_SIZE;
00510         }
00511 
00512         inline void incrementRxBufferOutIndex() {
00513             rxBufferOutIndex = (rxBufferOutIndex + 1) % RX_BUFFER_SIZE;
00514         }
00515 
00516         /**
00517          * Method called when Serial data is received (interrupt routine).
00518          */
00519         void onSerialDataReceived();
00520 
00521         // HTTP helpers
00522         bool HTTP_setup(char *url);
00523 
00524         void flushInput();
00525         uint16_t readRaw(uint16_t b);
00526         uint8_t readline(uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS, bool multiline = false);
00527         uint8_t getReply(const char* send, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00528         uint8_t getReply(const char* prefix, char *suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00529         uint8_t getReply(const char* prefix, int32_t suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00530         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.
00531         uint8_t getReplyQuoted(const char* prefix, const char* suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00532 
00533         bool sendCheckReply(const char* send, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00534         bool sendCheckReply(const char* prefix, char *suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00535         bool sendCheckReply(const char* prefix, int32_t suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00536         bool sendCheckReply(const char* prefix, int32_t suffix, int32_t suffix2, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00537         bool sendCheckReplyQuoted(const char* prefix, const char* suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
00538 
00539         bool parseReply(const char* toreply, uint16_t *v, char divider  = ',', uint8_t index=0);
00540         bool parseReply(const char* toreply, char *v, char divider  = ',', uint8_t index=0);
00541         bool parseReplyQuoted(const char* toreply, char* v, int maxlen, char divider, uint8_t index);
00542 
00543         bool sendParseReply(const char* tosend, const char* toreply, uint16_t *v, char divider = ',', uint8_t index = 0);
00544 
00545         void onIncomingCall();
00546 };
00547 
00548 #endif