Allows SMS to be sent to query Alexa. Also allows HTTP requests to be sent to Alexa via an ESP8266-hosted web server.
Revision 0:1271d15b4d4b, committed 2017-05-02
- Comitter:
- itatchi42
- Date:
- Tue May 02 03:13:27 2017 +0000
- Commit message:
- Allows SMS communication with Amazon Dot's Alexa.; Also allows URL queries to be sent to ESP8266-hosted HTTP server to communicate with Alexa.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_FONA.cpp Tue May 02 03:13:27 2017 +0000
@@ -0,0 +1,1447 @@
+/***************************************************
+ 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
+ */
+#include <algorithm>
+#include "Adafruit_FONA.h"
+
+#define HIGH 1
+#define LOW 0
+
+/*
+Notes George is taking:
+sendCheckReply returns a boolean where its true when FONA responds with the string of its second input
+
+*/
+
+
+bool Adafruit_FONA::begin(int baudrate) {
+ mySerial.baud(baudrate); //set the baud rate of the fona serial connection
+ mySerial.attach(this, &Adafruit_FONA::onSerialDataReceived, Serial::RxIrq); //attached onSerialDataReceived as Serial receive interrupt
+
+ // INIT Reboot process
+ _rstpin = HIGH;
+ wait_ms(10);
+ _rstpin = LOW;
+ wait_ms(100);
+ _rstpin = HIGH;
+
+ // give 3 seconds to reboot
+ wait_ms(3000);
+
+ // flushes the serial port
+ while (readable()) getc();
+
+ // Make sure FONA is alive
+ sendCheckReply("AT", "OK");
+ wait_ms(100);
+ sendCheckReply("AT", "OK");
+ wait_ms(100);
+ sendCheckReply("AT", "OK");
+ wait_ms(100);
+
+ // turn off Echo!
+ sendCheckReply("ATE0", "OK");
+ wait_ms(100);
+
+ // Just checks if the FONA even responds, if it doesnt, then return false
+ if (! sendCheckReply("ATE0", "OK")) {
+ return false;
+ }
+
+ return true;
+}
+
+void Adafruit_FONA::setEventListener(EventListener *eventListener) {
+ this->eventListener = eventListener;
+}
+
+/********* Stream ********************************************/
+
+int Adafruit_FONA::_putc(int value) {
+ return mySerial.putc(value);
+}
+
+int Adafruit_FONA::_getc() {
+ __disable_irq(); // Start Critical Section - don't interrupt while changing global buffer variables
+
+ // Wait for data if the buffer is empty
+ if (isRxBufferEmpty()) {
+ __enable_irq(); // End Critical Section - need to allow rx interrupt to get new characters for buffer
+
+ while(isRxBufferEmpty());
+
+ __disable_irq(); // Start Critical Section - don't interrupt while changing global buffer variables
+ }
+
+ int data = rxBuffer[rxBufferOutIndex];
+ incrementRxBufferOutIndex();
+
+ __enable_irq(); // End Critical Section
+
+ return data;
+}
+
+int Adafruit_FONA::readable() {
+ return !isRxBufferEmpty();
+}
+
+void Adafruit_FONA::onSerialDataReceived() {
+ while (mySerial.readable() && !isRxBufferFull()) {
+ int data = mySerial.getc();
+ rxBuffer[rxBufferInIndex] = data;
+
+ //
+ // Analyze the received data in order to detect events like RING or NO CARRIER
+ //
+
+ // Copy the data in the current line
+ if (currentReceivedLineSize < RX_BUFFER_SIZE && data != '\r' && data != '\n') {
+ currentReceivedLine[currentReceivedLineSize] = (char) data;
+ currentReceivedLineSize++;
+ }
+
+ // Check if the line is complete
+ if (data == '\n') {
+ currentReceivedLine[currentReceivedLineSize] = 0;
+
+ if (eventListener != NULL) {
+ // Check if we have a special event
+ if (strcmp(currentReceivedLine, "RING") == 0) {
+ eventListener->onRing();
+ } else if (strcmp(currentReceivedLine, "NO CARRIER") == 0) {
+ eventListener->onNoCarrier();
+ }
+ }
+
+ currentReceivedLineSize = 0;
+ }
+
+ incrementRxBufferInIndex();
+ }
+}
+
+/********* Real Time Clock ********************************************/
+
+bool Adafruit_FONA::enableRTC(uint8_t i) {
+ if (! sendCheckReply("AT+CLTS=", i, "OK"))
+ return false;
+ return sendCheckReply("AT&W", "OK");
+}
+
+/********* BATTERY & ADC ********************************************/
+
+/* returns value in mV (uint16_t) */
+bool Adafruit_FONA::getBattVoltage(uint16_t *v) {
+ return sendParseReply("AT+CBC", "+CBC: ", v, ',', 2);
+}
+
+/* returns the percentage charge of battery as reported by sim800 */
+bool Adafruit_FONA::getBattPercent(uint16_t *p) {
+ return sendParseReply("AT+CBC", "+CBC: ", p, ',', 1);
+}
+
+bool Adafruit_FONA::getADCVoltage(uint16_t *v) {
+ return sendParseReply("AT+CADC?", "+CADC: 1,", v);
+}
+
+/********* SIM ***********************************************************/
+
+bool Adafruit_FONA::unlockSIM(char *pin)
+{
+ char sendbuff[14] = "AT+CPIN=";
+ sendbuff[8] = pin[0];
+ sendbuff[9] = pin[1];
+ sendbuff[10] = pin[2];
+ sendbuff[11] = pin[3];
+ sendbuff[12] = NULL;
+
+ return sendCheckReply(sendbuff, "OK");
+}
+
+uint8_t Adafruit_FONA::getSIMCCID(char *ccid) {
+ getReply("AT+CCID");
+ // up to 20 chars
+ strncpy(ccid, replybuffer, 20);
+ ccid[20] = 0;
+
+ readline(); // eat 'OK'
+
+ return strlen(ccid);
+}
+
+/********* IMEI **********************************************************/
+
+uint8_t Adafruit_FONA::getIMEI(char *imei) {
+ getReply("AT+GSN");
+
+ // up to 15 chars
+ strncpy(imei, replybuffer, 15);
+ imei[15] = 0;
+
+ readline(); // eat 'OK'
+
+ return strlen(imei);
+}
+
+/********* NETWORK *******************************************************/
+
+uint8_t Adafruit_FONA::getNetworkStatus(void) {
+ uint16_t status;
+
+ if (! sendParseReply("AT+CREG?", "+CREG: ", &status, ',', 1)) return 0;
+
+ return status;
+}
+
+
+uint8_t Adafruit_FONA::getRSSI(void) {
+ uint16_t reply;
+
+ if (! sendParseReply("AT+CSQ", "+CSQ: ", &reply) ) return 0;
+
+ return reply;
+}
+
+/********* AUDIO *******************************************************/
+
+bool Adafruit_FONA::setAudio(uint8_t a) {
+ // 0 is headset, 1 is external audio
+ if (a > 1) return false;
+
+ return sendCheckReply("AT+CHFA=", a, "OK");
+}
+
+uint8_t Adafruit_FONA::getVolume(void) {
+ uint16_t reply;
+
+ if (! sendParseReply("AT+CLVL?", "+CLVL: ", &reply) ) return 0;
+
+ return reply;
+}
+
+bool Adafruit_FONA::setVolume(uint8_t i) {
+ return sendCheckReply("AT+CLVL=", i, "OK");
+}
+
+
+bool Adafruit_FONA::playDTMF(char dtmf) {
+ char str[4];
+ str[0] = '\"';
+ str[1] = dtmf;
+ str[2] = '\"';
+ str[3] = 0;
+ return sendCheckReply("AT+CLDTMF=3,", str, "OK");
+}
+
+bool Adafruit_FONA::playToolkitTone(uint8_t t, uint16_t len) {
+ return sendCheckReply("AT+STTONE=1,", t, len, "OK");
+}
+
+bool Adafruit_FONA::setMicVolume(uint8_t a, uint8_t level) {
+ // 0 is headset, 1 is external audio
+ if (a > 1) return false;
+
+ return sendCheckReply("AT+CMIC=", a, level, "OK");
+}
+
+/********* FM RADIO *******************************************************/
+
+
+bool Adafruit_FONA::FMradio(bool onoff, uint8_t a) {
+ if (! onoff) {
+ return sendCheckReply("AT+FMCLOSE", "OK");
+ }
+
+ // 0 is headset, 1 is external audio
+ if (a > 1) return false;
+
+ return sendCheckReply("AT+FMOPEN=", a, "OK");
+}
+
+bool Adafruit_FONA::tuneFMradio(uint16_t station) {
+ // Fail if FM station is outside allowed range.
+ if ((station < 870) || (station > 1090))
+ return false;
+
+ return sendCheckReply("AT+FMFREQ=", station, "OK");
+}
+
+bool Adafruit_FONA::setFMVolume(uint8_t i) {
+ // Fail if volume is outside allowed range (0-6).
+ if (i > 6) {
+ return false;
+ }
+ // Send FM volume command and verify response.
+ return sendCheckReply("AT+FMVOLUME=", i, "OK");
+}
+
+int8_t Adafruit_FONA::getFMVolume() {
+ uint16_t level;
+
+ if (! sendParseReply("AT+FMVOLUME?", "+FMVOLUME: ", &level) ) return 0;
+
+ return level;
+}
+
+int8_t Adafruit_FONA::getFMSignalLevel(uint16_t station) {
+ // Fail if FM station is outside allowed range.
+ if ((station < 875) || (station > 1080)) {
+ return -1;
+ }
+
+ // Send FM signal level query command.
+ // Note, need to explicitly send timeout so right overload is chosen.
+ getReply("AT+FMSIGNAL=", station, FONA_DEFAULT_TIMEOUT_MS);
+ // Check response starts with expected value.
+ char *p = strstr(replybuffer, "+FMSIGNAL: ");
+ if (p == 0) return -1;
+ p+=11;
+ // Find second colon to get start of signal quality.
+ p = strchr(p, ':');
+ if (p == 0) return -1;
+ p+=1;
+ // Parse signal quality.
+ int8_t level = atoi(p);
+ readline(); // eat the "OK"
+ return level;
+}
+
+/********* PWM/BUZZER **************************************************/
+
+bool Adafruit_FONA::setPWM(uint16_t period, uint8_t duty) {
+ if (period > 2000) return false;
+ if (duty > 100) return false;
+
+ return sendCheckReply("AT+SPWM=0,", period, duty, "OK");
+}
+
+/********* CALL PHONES **************************************************/
+bool Adafruit_FONA::callPhone(char *number) {
+ char sendbuff[35] = "ATD";
+ strncpy(sendbuff+3, number, min((int)30, (int)strlen(number)));
+ uint8_t x = strlen(sendbuff);
+ sendbuff[x] = ';';
+ sendbuff[x+1] = 0;
+
+ return sendCheckReply(sendbuff, "OK");
+}
+
+bool Adafruit_FONA::hangUp(void) {
+ return sendCheckReply("ATH0", "OK");
+}
+
+bool Adafruit_FONA::pickUp(void) {
+ return sendCheckReply("ATA", "OK");
+}
+
+void Adafruit_FONA::onIncomingCall() {
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("> Incoming call...\r\n");
+#endif
+ _incomingCall = true;
+}
+
+bool Adafruit_FONA::callerIdNotification(bool enable) {
+ if(enable){
+ _ringIndicatorInterruptIn.fall(this, &Adafruit_FONA::onIncomingCall);
+ return sendCheckReply("AT+CLIP=1", "OK");
+ }
+
+ _ringIndicatorInterruptIn.fall(NULL);
+ return sendCheckReply("AT+CLIP=0", "OK");
+}
+
+bool Adafruit_FONA::incomingCallNumber(char* phonenum) {
+ //+CLIP: "<incoming phone number>",145,"",0,"",0
+ if(!_incomingCall)
+ return false;
+
+ readline();
+ while(!strcmp(replybuffer, "RING") == 0) {
+ flushInput();
+ readline();
+ }
+
+ readline(); //reads incoming phone number line
+
+ parseReply("+CLIP: \"", phonenum, '"');
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("Phone Number: %s\r\n", replybuffer);
+#endif
+
+ _incomingCall = false;
+ return true;
+}
+
+/********* SMS **********************************************************/
+
+uint8_t Adafruit_FONA::getSMSInterrupt(void) {
+ uint16_t reply;
+
+ if (! sendParseReply("AT+CFGRI?", "+CFGRI: ", &reply) ) return 0;
+
+ return reply;
+}
+
+bool Adafruit_FONA::setSMSInterrupt(uint8_t i) {
+ return sendCheckReply("AT+CFGRI=", i, "OK");
+}
+
+int8_t Adafruit_FONA::getNumSMS(void) {
+ uint16_t numsms;
+
+ if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
+ // ask how many sms are stored
+
+ if (! sendParseReply("AT+CPMS?", "+CPMS: \"SM_P\",", &numsms) ) return -1;
+
+ return numsms;
+}
+
+// Reading SMS's is a bit involved so we don't use helpers that may cause delays or debug
+// printouts!
+bool Adafruit_FONA::readSMS(uint8_t i, char *smsbuff, uint16_t maxlen, uint16_t *readlen) {
+ // text mode
+ if (! sendCheckReply("AT+CMGF=1", "OK")) return false;
+
+ // show all text mode parameters
+ if (! sendCheckReply("AT+CSDH=1", "OK")) return false;
+
+ // parse out the SMS len
+ uint16_t thesmslen = 0;
+
+ //getReply(F("AT+CMGR="), i, 1000); // do not print debug!
+ mySerial.printf("AT+CMGR=%d\r\n", i);
+ readline(1000); // timeout
+
+ // parse it out...
+ if (! parseReply("+CMGR:", &thesmslen, ',', 11)) {
+ *readlen = 0;
+ return false;
+ }
+
+ readRaw(thesmslen);
+
+ flushInput();
+
+ uint16_t thelen = min(maxlen, (uint16_t)strlen(replybuffer));
+ strncpy(smsbuff, replybuffer, thelen);
+ smsbuff[thelen] = 0; // end the string
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("%s\r\n", replybuffer);
+#endif
+ *readlen = thelen;
+ return true;
+}
+
+// Retrieve the sender of the specified SMS message and copy it as a string to
+// the sender buffer. Up to senderlen characters of the sender will be copied
+// and a null terminator will be added if less than senderlen charactesr are
+// copied to the result. Returns true if a result was successfully retrieved,
+// otherwise false.
+bool Adafruit_FONA::getSMSSender(uint8_t i, char *sender, int senderlen) {
+ // Ensure text mode and all text mode parameters are sent.
+ if (! sendCheckReply("AT+CMGF=1", "OK")) return false;
+ if (! sendCheckReply("AT+CSDH=1", "OK")) return false;
+ // Send command to retrieve SMS message and parse a line of response.
+ mySerial.printf("AT+CMGR=%d\r\n", i);
+ readline(1000);
+ // Parse the second field in the response.
+ bool result = parseReplyQuoted("+CMGR:", sender, senderlen, ',', 1);
+ // Drop any remaining data from the response.
+ flushInput();
+ return result;
+}
+
+bool Adafruit_FONA::sendSMS(char *smsaddr, char *smsmsg) {
+ if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
+
+ char sendcmd[30] = "AT+CMGS=\"";
+ strncpy(sendcmd+9, smsaddr, 30-9-2); // 9 bytes beginning, 2 bytes for close quote + null
+ sendcmd[strlen(sendcmd)] = '\"';
+
+ if (! sendCheckReply(sendcmd, "> ")) return false;
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("> %s\r\n", smsmsg);
+#endif
+ mySerial.printf("%s\r\n\r\n", smsmsg);
+ mySerial.putc(0x1A);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("^Z\r\n");
+#endif
+ readline(10000); // read the +CMGS reply, wait up to 10 seconds!!!
+ //Serial.print("* "); Serial.println(replybuffer);
+ if (strstr(replybuffer, "+CMGS") == 0) {
+ return false;
+ }
+ readline(1000); // read OK
+ //Serial.print("* "); Serial.println(replybuffer);
+
+ if (strcmp(replybuffer, "OK") != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+
+bool Adafruit_FONA::deleteSMS(uint8_t i) {
+ if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
+ // read an sms
+ char sendbuff[12] = "AT+CMGD=000";
+ sendbuff[8] = (i / 100) + '0';
+ i %= 100;
+ sendbuff[9] = (i / 10) + '0';
+ i %= 10;
+ sendbuff[10] = i + '0';
+
+ return sendCheckReply(sendbuff, "OK", 2000);
+}
+
+/********* TIME **********************************************************/
+
+bool Adafruit_FONA::enableNetworkTimeSync(bool onoff) {
+ if (onoff) {
+ if (! sendCheckReply("AT+CLTS=1", "OK"))
+ return false;
+ } else {
+ if (! sendCheckReply("AT+CLTS=0", "OK"))
+ return false;
+ }
+
+ flushInput(); // eat any 'Unsolicted Result Code'
+
+ return true;
+}
+
+bool Adafruit_FONA::enableNTPTimeSync(bool onoff, const char* ntpserver) {
+ if (onoff) {
+ if (! sendCheckReply("AT+CNTPCID=1", "OK"))
+ return false;
+
+ mySerial.printf("AT+CNTP=\"");
+ if (ntpserver != 0) {
+ mySerial.printf(ntpserver);
+ } else {
+ mySerial.printf("pool.ntp.org");
+ }
+ mySerial.printf("\",0\r\n");
+ readline(FONA_DEFAULT_TIMEOUT_MS);
+ if (strcmp(replybuffer, "OK") != 0)
+ return false;
+
+ if (! sendCheckReply("AT+CNTP", "OK", 10000))
+ return false;
+
+ uint16_t status;
+ readline(10000);
+ if (! parseReply("+CNTP:", &status))
+ return false;
+ } else {
+ if (! sendCheckReply("AT+CNTPCID=0", "OK"))
+ return false;
+ }
+
+ return true;
+}
+
+bool Adafruit_FONA::getTime(char* buff, uint16_t maxlen) {
+ getReply("AT+CCLK?", (uint16_t) 10000);
+ if (strncmp(replybuffer, "+CCLK: ", 7) != 0)
+ return false;
+
+ char *p = replybuffer+7;
+ uint16_t lentocopy = min((uint16_t)(maxlen-1), (uint16_t)strlen(p));
+ strncpy(buff, p, lentocopy+1);
+ buff[lentocopy] = 0;
+
+ readline(); // eat OK
+
+ return true;
+}
+
+/********* GPS **********************************************************/
+
+
+bool Adafruit_FONA::enableGPS(bool onoff) {
+ uint16_t state;
+
+ // first check if its already on or off
+ if (! sendParseReply("AT+CGPSPWR?", "+CGPSPWR: ", &state) )
+ return false;
+
+ if (onoff && !state) {
+ if (! sendCheckReply("AT+CGPSPWR=1", "OK"))
+ return false;
+ } else if (!onoff && state) {
+ if (! sendCheckReply("AT+CGPSPWR=0", "OK"))
+ return false;
+ }
+ return true;
+}
+
+int8_t Adafruit_FONA::GPSstatus(void) {
+ getReply("AT+CGPSSTATUS?");
+
+ char *p = strstr(replybuffer, "+CGPSSTATUS: Location ");
+ if (p == 0) return -1;
+
+ p+=22;
+
+ readline(); // eat 'OK'
+
+
+ if (p[0] == 'U') return 0;
+ if (p[0] == 'N') return 1;
+ if (p[0] == '2') return 2;
+ if (p[0] == '3') return 3;
+
+ // else
+ return 0;
+}
+
+uint8_t Adafruit_FONA::getGPS(uint8_t arg, char *buffer, uint8_t maxbuff) {
+ int32_t x = arg;
+
+ getReply("AT+CGPSINF=", x);
+
+ char *p = strstr(replybuffer, "CGPSINF: ");
+ if (p == 0){
+ buffer[0] = 0;
+ return 0;
+ }
+ p+=9;
+ uint8_t len = max((uint8_t)(maxbuff-1), (uint8_t)strlen(p));
+ strncpy(buffer, p, len);
+ buffer[len] = 0;
+
+ readline(); // eat 'OK'
+ return len;
+}
+
+bool Adafruit_FONA::getGPS(float *lat, float *lon, float *speed_kph, float *heading, float *altitude) {
+ char gpsbuffer[120];
+
+ // we need at least a 2D fix
+ if (GPSstatus() < 2)
+ return false;
+
+ // grab the mode 2^5 gps csv from the sim808
+ uint8_t res_len = getGPS(32, gpsbuffer, 120);
+
+ // make sure we have a response
+ if (res_len == 0)
+ return false;
+
+ // skip mode
+ char *tok = strtok(gpsbuffer, ",");
+ if (! tok) return false;
+
+ // skip date
+ tok = strtok(NULL, ",");
+ if (! tok) return false;
+
+ // skip fix
+ tok = strtok(NULL, ",");
+ if (! tok) return false;
+
+ // grab the latitude
+ char *latp = strtok(NULL, ",");
+ if (! latp) return false;
+
+ // grab latitude direction
+ char *latdir = strtok(NULL, ",");
+ if (! latdir) return false;
+
+ // grab longitude
+ char *longp = strtok(NULL, ",");
+ if (! longp) return false;
+
+ // grab longitude direction
+ char *longdir = strtok(NULL, ",");
+ if (! longdir) return false;
+
+ double latitude = atof(latp);
+ double longitude = atof(longp);
+
+ // convert latitude from minutes to decimal
+ float degrees = floor(latitude / 100);
+ double minutes = latitude - (100 * degrees);
+ minutes /= 60;
+ degrees += minutes;
+
+ // turn direction into + or -
+ if (latdir[0] == 'S') degrees *= -1;
+
+ *lat = degrees;
+
+ // convert longitude from minutes to decimal
+ degrees = floor(longitude / 100);
+ minutes = longitude - (100 * degrees);
+ minutes /= 60;
+ degrees += minutes;
+
+ // turn direction into + or -
+ if (longdir[0] == 'W') degrees *= -1;
+
+ *lon = degrees;
+
+ // only grab speed if needed
+ if (speed_kph != NULL) {
+
+ // grab the speed in knots
+ char *speedp = strtok(NULL, ",");
+ if (! speedp) return false;
+
+ // convert to kph
+ *speed_kph = atof(speedp) * 1.852;
+
+ }
+
+ // only grab heading if needed
+ if (heading != NULL) {
+
+ // grab the speed in knots
+ char *coursep = strtok(NULL, ",");
+ if (! coursep) return false;
+
+ *heading = atof(coursep);
+
+ }
+
+ // no need to continue
+ if (altitude == NULL)
+ return true;
+
+ // we need at least a 3D fix for altitude
+ if (GPSstatus() < 3)
+ return false;
+
+ // grab the mode 0 gps csv from the sim808
+ res_len = getGPS(0, gpsbuffer, 120);
+
+ // make sure we have a response
+ if (res_len == 0)
+ return false;
+
+ // skip mode
+ tok = strtok(gpsbuffer, ",");
+ if (! tok) return false;
+
+ // skip lat
+ tok = strtok(NULL, ",");
+ if (! tok) return false;
+
+ // skip long
+ tok = strtok(NULL, ",");
+ if (! tok) return false;
+
+ // grab altitude
+ char *altp = strtok(NULL, ",");
+ if (! altp) return false;
+
+ *altitude = atof(altp);
+
+ return true;
+}
+
+bool Adafruit_FONA::enableGPSNMEA(uint8_t i) {
+ char sendbuff[15] = "AT+CGPSOUT=000";
+ sendbuff[11] = (i / 100) + '0';
+ i %= 100;
+ sendbuff[12] = (i / 10) + '0';
+ i %= 10;
+ sendbuff[13] = i + '0';
+
+ return sendCheckReply(sendbuff, "OK", 2000);
+}
+
+
+/********* GPRS **********************************************************/
+
+
+bool Adafruit_FONA::enableGPRS(bool onoff) {
+ if (onoff) {
+ // disconnect all sockets
+ sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000);
+
+ if (! sendCheckReply("AT+CGATT=1", "OK", 10000))
+ return false;
+
+ // set bearer profile! connection type GPRS
+ if (! sendCheckReply("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK", 10000))
+ return false;
+
+ // set bearer profile access point name
+ if (apn) {
+ // Send command AT+SAPBR=3,1,"APN","<apn value>" where <apn value> is the configured APN value.
+ if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"APN\",", apn, "OK", 10000))
+ return false;
+
+ // set username/password
+ if (apnusername) {
+ // Send command AT+SAPBR=3,1,"USER","<user>" where <user> is the configured APN username.
+ if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"USER\",", apnusername, "OK", 10000))
+ return false;
+ }
+ if (apnpassword) {
+ // Send command AT+SAPBR=3,1,"PWD","<password>" where <password> is the configured APN password.
+ if (! sendCheckReplyQuoted("AT+SAPBR=3,1,\"PWD\",", apnpassword, "OK", 10000))
+ return false;
+ }
+ }
+
+ // open GPRS context
+ if (! sendCheckReply("AT+SAPBR=1,1", "OK", 10000))
+ return false;
+ } else {
+ // disconnect all sockets
+ if (! sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000))
+ return false;
+
+ // close GPRS context
+ if (! sendCheckReply("AT+SAPBR=0,1", "OK", 10000))
+ return false;
+
+ if (! sendCheckReply("AT+CGATT=0", "OK", 10000))
+ return false;
+ }
+ return true;
+}
+
+uint8_t Adafruit_FONA::GPRSstate(void) {
+ uint16_t state;
+
+ if (! sendParseReply("AT+CGATT?", "+CGATT: ", &state) )
+ return -1;
+
+ return state;
+}
+
+void Adafruit_FONA::setGPRSNetworkSettings(const char* apn, const char* ausername, const char* apassword) {
+ this->apn = (char*) apn;
+ this->apnusername = (char*) ausername;
+ this->apnpassword = (char*) apassword;
+}
+
+bool Adafruit_FONA::getGSMLoc(uint16_t *errorcode, char *buff, uint16_t maxlen) {
+ getReply("AT+CIPGSMLOC=1,1", (uint16_t)10000);
+
+ if (! parseReply("+CIPGSMLOC: ", errorcode))
+ return false;
+
+ char *p = replybuffer+14;
+ uint16_t lentocopy = min((uint16_t)(maxlen-1), (uint16_t)strlen(p));
+ strncpy(buff, p, lentocopy+1);
+
+ readline(); // eat OK
+
+ return true;
+}
+
+bool Adafruit_FONA::getGSMLoc(float *lat, float *lon) {
+ uint16_t returncode;
+ char gpsbuffer[120];
+
+ // make sure we could get a response
+ if (! getGSMLoc(&returncode, gpsbuffer, 120))
+ return false;
+
+ // make sure we have a valid return code
+ if (returncode != 0)
+ return false;
+
+ // tokenize the gps buffer to locate the lat & long
+ char *latp = strtok(gpsbuffer, ",");
+ if (! latp) return false;
+
+ char *longp = strtok(NULL, ",");
+ if (! longp) return false;
+
+ *lat = atof(latp);
+ *lon = atof(longp);
+
+ return true;
+}
+
+/********* TCP FUNCTIONS ************************************/
+
+
+bool Adafruit_FONA::TCPconnect(char *server, uint16_t port) {
+ flushInput();
+
+ // close all old connections
+ if (! sendCheckReply("AT+CIPSHUT", "SHUT OK", 5000) ) return false;
+
+ // single connection at a time
+ if (! sendCheckReply("AT+CIPMUX=0", "OK") ) return false;
+
+ // manually read data
+ if (! sendCheckReply("AT+CIPRXGET=1", "OK") ) return false;
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("AT+CIPSTART=\"TCP\",\"%s\",\"%d\"\r\n", server, port);
+#endif
+
+ mySerial.printf("AT+CIPSTART=\"TCP\",\"%s\",\"%d\"\r\n", server, port);
+
+ if (! expectReply("OK")) return false;
+ if (! expectReply("CONNECT OK")) return false;
+ return true;
+}
+
+bool Adafruit_FONA::TCPclose(void) {
+ return sendCheckReply("AT+CIPCLOSE", "OK");
+}
+
+bool Adafruit_FONA::TCPconnected(void) {
+ if (! sendCheckReply("AT+CIPSTATUS", "OK", 100) ) return false;
+ readline(100);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ return (strcmp(replybuffer, "STATE: CONNECT OK") == 0);
+}
+
+bool Adafruit_FONA::TCPsend(char *packet, uint8_t len) {
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("AT+CIPSEND=%d\r\n", len);
+
+ for (uint16_t i=0; i<len; i++) {
+ printf(" 0x%#02x", packet[i]);
+ }
+ printf("\r\n");
+#endif
+
+
+ mySerial.printf("AT+CIPSEND=%d\r\n", len);
+ readline();
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ if (replybuffer[0] != '>') return false;
+
+ for (uint16_t i=0; i<len; i++) {
+ mySerial.putc(packet[i]);
+ }
+ readline(3000); // wait up to 3 seconds to send the data
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+
+ return (strcmp(replybuffer, "SEND OK") == 0);
+}
+
+uint16_t Adafruit_FONA::TCPavailable(void) {
+ uint16_t avail;
+
+ if (! sendParseReply("AT+CIPRXGET=4", "+CIPRXGET: 4,", &avail, ',', 0) ) return false;
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("%d bytes available\r\n", avail);
+#endif
+
+ return avail;
+}
+
+
+uint16_t Adafruit_FONA::TCPread(uint8_t *buff, uint8_t len) {
+ uint16_t avail;
+
+ mySerial.printf("AT+CIPRXGET=2,%d\r\n", len);
+ readline();
+ if (! parseReply("+CIPRXGET: 2,", &avail, ',', 0)) return false;
+
+ readRaw(avail);
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("%d bytes read\r\n", avail);
+ for (uint8_t i=0;i<avail;i++) {
+ printf(" 0x%#02x", replybuffer[i]);
+ }
+ printf("\r\n");
+#endif
+
+ memcpy(buff, replybuffer, avail);
+
+ return avail;
+}
+
+/********* HTTP LOW LEVEL FUNCTIONS ************************************/
+
+bool Adafruit_FONA::HTTP_init() {
+ return sendCheckReply("AT+HTTPINIT", "OK");
+}
+
+bool Adafruit_FONA::HTTP_term() {
+ return sendCheckReply("AT+HTTPTERM", "OK");
+}
+
+void Adafruit_FONA::HTTP_para_start(const char* parameter, bool quoted) {
+ flushInput();
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t---> AT+HTTPPARA=\"%s\"\r\n", parameter);
+#endif
+
+ mySerial.printf("AT+HTTPPARA=\"%s", parameter);
+ if (quoted)
+ mySerial.printf("\",\"");
+ else
+ mySerial.printf("\",");
+}
+
+bool Adafruit_FONA::HTTP_para_end(bool quoted) {
+ if (quoted)
+ mySerial.printf("\"\r\n");
+ else
+ mySerial.printf("\r\n");
+
+ return expectReply("OK");
+}
+
+bool Adafruit_FONA::HTTP_para(const char* parameter, const char* value) {
+ HTTP_para_start(parameter, true);
+ mySerial.printf(value);
+ return HTTP_para_end(true);
+}
+
+bool Adafruit_FONA::HTTP_para(const char* parameter, int32_t value) {
+ HTTP_para_start(parameter, false);
+ mySerial.printf("%d", value);
+ return HTTP_para_end(false);
+}
+
+bool Adafruit_FONA::HTTP_data(uint32_t size, uint32_t maxTime) {
+ flushInput();
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t---> AT+HTTPDATA=%d,%d\r\n", size, maxTime);
+#endif
+
+ mySerial.printf("AT+HTTPDATA=%d,%d\r\n", size, maxTime);
+
+ return expectReply("DOWNLOAD");
+}
+
+bool Adafruit_FONA::HTTP_action(uint8_t method, uint16_t *status, uint16_t *datalen, int32_t timeout) {
+ // Send request.
+ if (! sendCheckReply("AT+HTTPACTION=", method, "OK"))
+ return false;
+
+ // Parse response status and size.
+ readline(timeout);
+ if (! parseReply("+HTTPACTION:", status, ',', 1))
+ return false;
+ if (! parseReply("+HTTPACTION:", datalen, ',', 2))
+ return false;
+
+ return true;
+}
+
+bool Adafruit_FONA::HTTP_readall(uint16_t *datalen) {
+ getReply("AT+HTTPREAD");
+ if (! parseReply("+HTTPREAD:", datalen, ',', 0))
+ return false;
+
+ return true;
+}
+
+bool Adafruit_FONA::HTTP_ssl(bool onoff) {
+ return sendCheckReply("AT+HTTPSSL=", onoff ? 1 : 0, "OK");
+}
+
+/********* HTTP HIGH LEVEL FUNCTIONS ***************************/
+
+bool Adafruit_FONA::HTTP_GET_start(char *url, uint16_t *status, uint16_t *datalen){
+ if (! HTTP_setup(url))
+ return false;
+
+ // HTTP GET
+ if (! HTTP_action(FONA_HTTP_GET, status, datalen))
+ return false;
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("Status: %d\r\n", *status);
+ printf("Len: %d\r\n", *datalen);
+#endif
+
+ // HTTP response data
+ if (! HTTP_readall(datalen))
+ return false;
+
+ return true;
+}
+
+void Adafruit_FONA::HTTP_GET_end(void) {
+ HTTP_term();
+}
+
+bool Adafruit_FONA::HTTP_POST_start(char *url, const char* contenttype, const uint8_t *postdata, uint16_t postdatalen, uint16_t *status, uint16_t *datalen) {
+ if (! HTTP_setup(url))
+ return false;
+
+ if (! HTTP_para("CONTENT", contenttype)) {
+ return false;
+ }
+
+ // HTTP POST data
+ if (! HTTP_data(postdatalen, 10000))
+ return false;
+ for (uint16_t i = 0; i < postdatalen; i++) {
+ mySerial.putc(postdata[i]);
+ }
+ if (! expectReply("OK"))
+ return false;
+
+ // HTTP POST
+ if (! HTTP_action(FONA_HTTP_POST, status, datalen))
+ return false;
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("Status: %d\r\n", *status);
+ printf("Len: %d\r\n", *datalen);
+#endif
+
+ // HTTP response data
+ if (! HTTP_readall(datalen))
+ return false;
+
+ return true;
+}
+
+void Adafruit_FONA::HTTP_POST_end(void) {
+ HTTP_term();
+}
+
+void Adafruit_FONA::setUserAgent(const char* useragent) {
+ this->useragent = (char*) useragent;
+}
+
+void Adafruit_FONA::setHTTPSRedirect(bool onoff) {
+ httpsredirect = onoff;
+}
+
+/********* HTTP HELPERS ****************************************/
+
+bool Adafruit_FONA::HTTP_setup(char *url) {
+ // Handle any pending
+ HTTP_term();
+
+ // Initialize and set parameters
+ if (! HTTP_init())
+ return false;
+ if (! HTTP_para("CID", 1))
+ return false;
+ if (! HTTP_para("UA", useragent))
+ return false;
+ if (! HTTP_para("URL", url))
+ return false;
+
+ // HTTPS redirect
+ if (httpsredirect) {
+ if (! HTTP_para("REDIR",1))
+ return false;
+
+ if (! HTTP_ssl(true))
+ return false;
+ }
+
+ return true;
+}
+
+
+/********* HELPERS *********************************************/
+
+bool Adafruit_FONA::expectReply(const char* reply, uint16_t timeout) {
+ readline(timeout);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ return (strcmp(replybuffer, reply) == 0);
+}
+
+/********* LOW LEVEL *******************************************/
+
+void Adafruit_FONA::flushInput() {
+ // Read all available serial input to flush pending data.
+ uint16_t timeoutloop = 0;
+ while (timeoutloop++ < 40) {
+ while(readable()) {
+ getc();
+ timeoutloop = 0; // If char was received reset the timer
+ }
+ wait_ms(1);
+ }
+}
+
+uint16_t Adafruit_FONA::readRaw(uint16_t b) {
+ uint16_t idx = 0;
+
+ while (b && (idx < sizeof(replybuffer)-1)) {
+ if (readable()) {
+ replybuffer[idx] = getc();
+ idx++;
+ b--;
+ }
+ }
+ replybuffer[idx] = 0;
+
+ return idx;
+}
+
+// This function just reads the output from FONA after an AT command is sent to it
+uint8_t Adafruit_FONA::readline(uint16_t timeout, bool multiline) {
+ uint16_t replyidx = 0;
+
+ while (timeout--) {
+ if (replyidx >= 254) {
+ break;
+ }
+
+ while(readable()) {
+ char c = getc();
+ if (c == '\r') continue;
+ if (c == 0xA) {
+ if (replyidx == 0) // the first 0x0A is ignored
+ continue;
+
+ if (!multiline) {
+ timeout = 0; // the second 0x0A is the end of the line
+ break;
+ }
+ }
+ replybuffer[replyidx] = c;
+ replyidx++;
+ }
+
+ if (timeout == 0) {
+ break;
+ }
+ wait_ms(1);
+ }
+ replybuffer[replyidx] = 0; // null term
+ return replyidx;
+}
+
+uint8_t Adafruit_FONA::getReply(const char* send, uint16_t timeout) {
+ flushInput();
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t---> %s\r\n", send);
+#endif
+
+ mySerial.printf("%s\r\n",send);
+
+ uint8_t l = readline(timeout);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ return l;
+}
+
+// Send prefix, suffix, and newline. Return response (and also set replybuffer with response).
+uint8_t Adafruit_FONA::getReply(const char* prefix, char* suffix, uint16_t timeout) {
+ flushInput();
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t---> %s%s\r\n", prefix, suffix);
+#endif
+
+ mySerial.printf("%s%s\r\n", prefix, suffix);
+
+ uint8_t l = readline(timeout);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ return l;
+}
+
+// Send prefix, suffix, and newline. Return response (and also set replybuffer with response).
+uint8_t Adafruit_FONA::getReply(const char* prefix, int32_t suffix, uint16_t timeout) {
+ flushInput();
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t---> %s%d\r\n", prefix, suffix);
+#endif
+
+ mySerial.printf("%s%d\r\n", prefix, suffix);
+
+ uint8_t l = readline(timeout);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ return l;
+}
+
+// Send prefix, suffix, suffix2, and newline. Return response (and also set replybuffer with response).
+uint8_t Adafruit_FONA::getReply(const char* prefix, int32_t suffix1, int32_t suffix2, uint16_t timeout) {
+ flushInput();
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t---> %s%d,%d\r\n", prefix, suffix1, suffix2);
+#endif
+
+ mySerial.printf("%s%d,%d\r\n", prefix, suffix1, suffix2);
+
+ uint8_t l = readline(timeout);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ return l;
+}
+
+// Send prefix, ", suffix, ", and newline. Return response (and also set replybuffer with response).
+uint8_t Adafruit_FONA::getReplyQuoted(const char* prefix, const char* suffix, uint16_t timeout) {
+ flushInput();
+
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t---> %s\"%s\"\r\n", prefix, suffix);
+#endif
+
+ mySerial.printf("%s\"%s\"\r\n", prefix, suffix);
+
+ uint8_t l = readline(timeout);
+#ifdef ADAFRUIT_FONA_DEBUG
+ printf("\t<--- %s\r\n", replybuffer);
+#endif
+ return l;
+}
+
+
+bool Adafruit_FONA::sendCheckReply(const char *send, const char *reply, uint16_t timeout) {
+ getReply(send, timeout);
+
+ return (strcmp(replybuffer, reply) == 0);
+}
+
+// Send prefix, suffix, and newline. Verify FONA response matches reply parameter.
+bool Adafruit_FONA::sendCheckReply(const char* prefix, char *suffix, const char* reply, uint16_t timeout) {
+ getReply(prefix, suffix, timeout);
+ return (strcmp(replybuffer, reply) == 0);
+}
+
+// Send prefix, suffix, and newline. Verify FONA response matches reply parameter.
+bool Adafruit_FONA::sendCheckReply(const char* prefix, int32_t suffix, const char* reply, uint16_t timeout) {
+ getReply(prefix, suffix, timeout);
+ return (strcmp(replybuffer, reply) == 0);
+}
+
+// Send prefix, suffix, suffix2, and newline. Verify FONA response matches reply parameter.
+bool Adafruit_FONA::sendCheckReply(const char* prefix, int32_t suffix1, int32_t suffix2, const char* reply, uint16_t timeout) {
+ getReply(prefix, suffix1, suffix2, timeout);
+ return (strcmp(replybuffer, reply) == 0);
+}
+
+// Send prefix, ", suffix, ", and newline. Verify FONA response matches reply parameter.
+bool Adafruit_FONA::sendCheckReplyQuoted(const char* prefix, const char* suffix, const char* reply, uint16_t timeout) {
+ getReplyQuoted(prefix, suffix, timeout);
+ return (strcmp(replybuffer, reply) == 0);
+}
+
+bool Adafruit_FONA::parseReply(const char* toreply, uint16_t *v, char divider, uint8_t index) {
+ char *p = strstr(replybuffer, toreply); // get the pointer to the voltage
+ if (p == 0) return false;
+ p += strlen(toreply);
+
+ for (uint8_t i=0; i<index;i++) {
+ // increment dividers
+ p = strchr(p, divider);
+ if (!p) return false;
+ p++;
+ }
+
+ *v = atoi(p);
+
+ return true;
+}
+
+bool Adafruit_FONA::parseReply(const char* toreply, char *v, char divider, uint8_t index) {
+ uint8_t i=0;
+ char *p = strstr(replybuffer, toreply);
+ if (p == 0) return false;
+ p+=strlen(toreply);
+
+ for (i=0; i<index;i++) {
+ // increment dividers
+ p = strchr(p, divider);
+ if (!p) return false;
+ p++;
+ }
+
+ for(i=0; i<strlen(p);i++) {
+ if(p[i] == divider)
+ break;
+ v[i] = p[i];
+ }
+
+ v[i] = '\0';
+
+ return true;
+}
+
+// Parse a quoted string in the response fields and copy its value (without quotes)
+// to the specified character array (v). Only up to maxlen characters are copied
+// into the result buffer, so make sure to pass a large enough buffer to handle the
+// response.
+bool Adafruit_FONA::parseReplyQuoted(const char* toreply, char* v, int maxlen, char divider, uint8_t index) {
+ uint8_t i=0, j;
+ // Verify response starts with toreply.
+ char *p = strstr(replybuffer, toreply);
+ if (p == 0) return false;
+ p+=strlen(toreply);
+
+ // Find location of desired response field.
+ for (i=0; i<index;i++) {
+ // increment dividers
+ p = strchr(p, divider);
+ if (!p) return false;
+ p++;
+ }
+
+ // Copy characters from response field into result string.
+ for(i=0, j=0; j<maxlen && i<strlen(p); ++i) {
+ // Stop if a divier is found.
+ if(p[i] == divider)
+ break;
+ // Skip any quotation marks.
+ else if(p[i] == '"')
+ continue;
+ v[j++] = p[i];
+ }
+
+ // Add a null terminator if result string buffer was not filled.
+ if (j < maxlen)
+ v[j] = '\0';
+
+ return true;
+}
+
+bool Adafruit_FONA::sendParseReply(const char* tosend, const char* toreply, uint16_t *v, char divider, uint8_t index) {
+ getReply(tosend);
+
+ if (! parseReply(toreply, v, divider, index)) return false;
+
+ readline(); // eat 'OK'
+
+ return true;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_FONA.h Tue May 02 03:13:27 2017 +0000
@@ -0,0 +1,542 @@
+/***************************************************
+ 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
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BACKUP_main.txt Tue May 02 03:13:27 2017 +0000
@@ -0,0 +1,954 @@
+/***************************************************
+ 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
+ ****************************************************/
+
+ /*
+ * Modified by Jesse Baker & George Tzintzarov 03/30/2016 for use in mbed LPC1768
+ */
+
+/*
+THIS CODE IS STILL IN PROGRESS!
+
+Open up the serial console on the Arduino at 4800 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 just before the main "while (true)" loop.
+*/
+
+#include <string.h> //// BY JONATHAN: For strcpy()
+#include <ctype.h>
+//#include "SoftSerial.h" I dont think we need this
+#include "Adafruit_FONA.h"
+#include "emic2.h"
+
+#define FONA_RST p12
+#define FONA_TX p13
+#define FONA_RX p14
+#define FONA_RI p11
+
+// this is a large buffer for replies
+char replybuffer[255];
+char smsText[255], smsPhoneNo[11]; ///// By Jonathan: Text to send to Text -> Speech chip & phone # to send to
+
+int count; // by Jonathan
+
+
+Serial pcSerial(USBTX, USBRX);
+Adafruit_FONA fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
+//uLCD_4DGL uLCD(p28,p27,p30);
+
+// Turn on a LED when somebody call the FONA
+DigitalOut led1(LED1);
+emic2 myTTS(p9, p10);
+
+class FonaEventListener : public Adafruit_FONA::EventListener {
+ virtual void onRing() {
+ led1 = 1;
+ }
+
+ virtual void onNoCarrier() {
+ led1 = 0;
+ }
+};
+FonaEventListener fonaEventListener;
+
+// Functions defined after main()
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
+void printMenu(void);
+void flushSerial();
+char readBlocking();
+uint16_t readnumber();
+long map(long x, long in_min, long in_max, long out_min, long out_max);
+
+int main() {
+ myTTS.volume(5);
+ myTTS.voice(0);
+ pcSerial.baud(9600);
+ wait(1);
+ pcSerial.printf("\r\n");
+
+ pcSerial.printf("FONA basic test\r\n");
+ pcSerial.printf("Initializing....(May take 3 seconds)\r\n");
+
+ // See if the FONA is responding
+ if (! fona.begin(9600)) {
+ pcSerial.printf("Couldn't find FONA\r\n");
+ while (1);
+ }
+ fona.setEventListener(&fonaEventListener);
+ pcSerial.printf("FONA is OK\r\n");
+
+ // Print SIM card IMEI number.
+ char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
+ uint8_t imeiLen = fona.getIMEI(imei);
+ if (imeiLen > 0) {
+ pcSerial.printf("SIM card IMEI: %s\r\n", 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("your APN", "your username", "your password");
+ //fona.setGPRSNetworkSettings("web.pt.lu", "", "");
+
+ // 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();
+
+
+ while (true) {
+
+ pcSerial.printf("FONA> ");
+ // if nothing is available on the pcSearial port but there is something on the fona serial, then print it (flush it) to the pc Serial
+
+ /*
+ while (! pcSerial.readable() ) {
+ if (fona.readable()) {
+ pcSerial.putc(fona.getc()); /////// RESPONSIBLE FOR DETECTING RECV'D TXT///////
+ }
+ } */
+
+ //////////////////// By Jonathan: Edited version of while() above
+ while (! pcSerial.readable()) {
+ if (fona.readable()) {
+
+ //// Printf that incoming SMS detected
+ pcSerial.putc(fona.getc());
+
+
+ // ----------------------------------------------------------------//
+
+ // read an SMS + send -> TTS chip
+ flushSerial();
+ pcSerial.printf("\r\nReading SMS #1\r\n");
+
+ // Retrieve SMS sender address/phone number.
+ if (! fona.getSMSSender(1, replybuffer, 250)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("FROM: %s\r\n", replybuffer);
+ for (int i = 0; i < 10; i++) { /////// BY JONATHAN to store phone # to respond to
+ smsPhoneNo[i] = replybuffer[i + 2]; // chop off the "+1" from phone # returned by replybuffer
+ }
+ smsPhoneNo[10] = '\0'; // null terminate.... NECESSARY??
+ pcSerial.printf("FROM: %s\r\n", smsPhoneNo);
+
+ // Retrieve SMS value.
+ uint16_t smslen;
+ if (! fona.readSMS(1, replybuffer, 250, &smslen)) { // pass in buffer and max len!
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("***** SMS #1 (%d) bytes *****\r\n", smslen);
+ pcSerial.printf("%s\r\n", replybuffer);
+ pcSerial.printf("*****\r\n");
+
+
+
+ //char message[255]; // CHANGED BY JONATHAN. 141 -> 255
+ char myString[255];
+
+ for (int i = 0; i < 255; i++) {
+ myString[i] = replybuffer[i + 5]; // chop of the "Alexa string"
+ }
+
+ strcpy(smsText, "Uh lex uh "); //Pronunciation Correction.
+ strcat(smsText, myString);
+ myTTS.speakf("S%s\r", smsText); // Send text message to the text to speech module.
+
+
+ // ----------------------------------------------------------------//
+
+ // send an SMS back!
+ char message[255];
+
+ strcpy(message, "");
+
+ flushSerial();
+
+ pcSerial.printf("Replying to %s\r\n", smsPhoneNo);
+
+
+ if(strstr(replybuffer, "how old are you")) { // if reply buffer contains that string
+ strcpy(message, "I'm 2 in human years, 14 in dog years, and 25 in cat years. I think AI years are marked in nanoseconds, so that makes me, like, a scrillion!");
+ }
+ else if(strstr(replybuffer, "what is the world population")) {
+ strcpy(message, "The population of the world is about 7 Billion 400 Million.");
+ }
+ else if(strstr(replybuffer, "integral of x squared")) {
+ strcpy(message, "The integral of x squared is one third x cubed plus a constant.");
+ }
+ else if(strstr(replybuffer, "discrete co sine transform")) {
+ strcpy(message, "The discrete cosine transform expresses a finite sequence of data points in terms of a sum of cosine function oscillating at different frequencies.");
+ }
+ else {
+ strcpy(message, "Sorry, command not recognized.");
+ }
+
+
+
+ // message[255] = '\0';
+
+ pcSerial.printf("%s\r\n", message);
+ if (!fona.sendSMS(smsPhoneNo, message))
+ pcSerial.printf("Failed\r\n");
+ else
+ pcSerial.printf("Sent!\r\n");
+
+ // ----------------------------------------------------------------//
+
+ // delete an SMS after response sent back
+ flushSerial();
+ pcSerial.printf("\r\nDeleting SMS #1\r\n");
+ if (fona.deleteSMS(1)) // delete SMS #1
+ pcSerial.printf("OK!\r\n");
+ else
+ pcSerial.printf("Couldn't delete\r\n");
+
+ } // end if
+ } // end while
+
+
+
+ // Above while() by Jonathan //
+
+
+
+ // get the input command from the terminal
+ char command = pcSerial.getc();
+ pcSerial.printf("%c\r\n", command); //loops back to COM port
+
+
+ switch (command) {
+ case '?': {
+ printMenu();
+ break;
+ }
+
+ case 'a': {
+ // read the ADC
+ uint16_t adc;
+ if (! fona.getADCVoltage(&adc)) {
+ pcSerial.printf("Failed to read ADC\r\n");
+ } else {
+ pcSerial.printf("ADC = %d mV\r\n", adc);
+ }
+ break;
+ }
+
+ case 'b': {
+ // read the battery voltage and percentage
+ uint16_t vbat;
+ if (! fona.getBattVoltage(&vbat)) {
+ pcSerial.printf("Failed to read Batt\r\n");
+ } else {
+ pcSerial.printf("VBat = %d mV\r\n", vbat);
+ }
+
+ if (! fona.getBattPercent(&vbat)) {
+ pcSerial.printf("Failed to read Batt\r\n");
+ } else {
+ pcSerial.printf("VPct = %d%%\r\n", vbat);
+ }
+
+ break;
+ }
+
+ case 'U': {
+ // Unlock the SIM with a PIN code
+ char PIN[5];
+ flushSerial();
+ pcSerial.printf("Enter 4-digit PIN\r\n");
+ readline(PIN, 3);
+ pcSerial.printf("%s\r\n", PIN);
+ pcSerial.printf("Unlocking SIM card: ");
+ if (! fona.unlockSIM(PIN)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ case 'C': {
+ // read the CCID
+ fona.getSIMCCID(replybuffer); // make sure replybuffer is at least 21 bytes!
+ pcSerial.printf("SIM CCID = %s\r\n", replybuffer);
+ break;
+ }
+
+ case 'i': {
+ // 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);
+ }
+ pcSerial.printf("%d dBm\r\n", r);
+
+ break;
+ }
+
+ case 'n': {
+ // read the network/cellular status
+ uint8_t n = fona.getNetworkStatus();
+ pcSerial.printf("Network status %d: ", n);
+ if (n == 0) pcSerial.printf("Not registered\r\n");
+ if (n == 1) pcSerial.printf("Registered (home)\r\n");
+ if (n == 2) pcSerial.printf("Not registered (searching)\r\n");
+ if (n == 3) pcSerial.printf("Denied\r\n");
+ if (n == 4) pcSerial.printf("Unknown\r\n");
+ if (n == 5) pcSerial.printf("Registered roaming\r\n");
+ break;
+ }
+
+ /*** Audio ***/
+ case 'v': {
+ // set volume
+ flushSerial();
+ pcSerial.printf("Set Vol %%");
+ uint8_t vol = readnumber();
+ pcSerial.printf("\r\n");
+ if (! fona.setVolume(vol)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ case 'V': {
+ uint8_t v = fona.getVolume();
+ pcSerial.printf("%d%%\r\n", v);
+
+ break;
+ }
+
+ case 'H': {
+ // Set Headphone output
+ if (! fona.setAudio(FONA_HEADSETAUDIO)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ fona.setMicVolume(FONA_HEADSETAUDIO, 15);
+ break;
+ }
+ case 'e': {
+ // Set External output
+ if (! fona.setAudio(FONA_EXTAUDIO)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+
+ fona.setMicVolume(FONA_EXTAUDIO, 10);
+ break;
+ }
+
+ case 'T': {
+ // play tone
+ flushSerial();
+ pcSerial.printf("Play tone #");
+ uint8_t kittone = readnumber();
+ pcSerial.printf("\r\n");
+ // play for 1 second (1000 ms)
+ if (! fona.playToolkitTone(kittone, 1000)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ /*** FM Radio ***/
+
+ case 'f': {
+ // get freq
+ flushSerial();
+ pcSerial.printf("FM Freq (eg 1011 == 101.1 MHz): ");
+ uint16_t station = readnumber();
+ pcSerial.printf("\r\n");
+ // FM radio ON using headset
+ if (fona.FMradio(true, FONA_HEADSETAUDIO)) {
+ pcSerial.printf("Opened\r\n");
+ }
+ if (! fona.tuneFMradio(station)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("Tuned\r\n");
+ }
+ break;
+ }
+ case 'F': {
+ // FM radio off
+ if (! fona.FMradio(false)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+ case 'm': {
+ // Set FM volume.
+ flushSerial();
+ pcSerial.printf("Set FM Vol [0-6]:");
+ uint8_t vol = readnumber();
+ pcSerial.printf("\r\n");
+ if (!fona.setFMVolume(vol)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+ case 'M': {
+ // Get FM volume.
+ int8_t fmvol = fona.getFMVolume();
+ if (fmvol < 0) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("FM volume: %d\r\n", fmvol);
+ }
+ break;
+ }
+ case 'q': {
+ // Get FM station signal level (in decibels).
+ flushSerial();
+ pcSerial.printf("FM Freq (eg 1011 == 101.1 MHz): ");
+ uint16_t station = readnumber();
+ pcSerial.printf("\r\n");
+ int8_t level = fona.getFMSignalLevel(station);
+ if (level < 0) {
+ pcSerial.printf("Failed! Make sure FM radio is on (tuned to station).\r\n");
+ } else {
+ pcSerial.printf("Signal level (dB): %d\r\n", level);
+ }
+ break;
+ }
+
+ /*** PWM ***/
+
+ case 'P': {
+ // PWM Buzzer output @ 2KHz max
+ flushSerial();
+ pcSerial.printf("PWM Freq, 0 = Off, (1-2000): ");
+ uint16_t freq = readnumber();
+ pcSerial.printf("\r\n");
+ if (! fona.setPWM(freq)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ /*** Call ***/
+ case 'c': {
+ // call a phone!
+ char number[10];
+ flushSerial();
+ pcSerial.printf("Call #");
+ readline(number, 9);
+ pcSerial.printf("\r\n");
+ pcSerial.printf("Calling %s\r\n", number);
+ if (!fona.callPhone(number)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("Sent!\r\n");
+ }
+
+ break;
+ }
+ case 'h': {
+ // hang up!
+ if (! fona.hangUp()) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ case 'p': {
+ // pick up!
+ if (! fona.pickUp()) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ /*** SMS ***/
+
+ case 'N': {
+ // read the number of SMS's!
+ int8_t smsnum = fona.getNumSMS();
+ if (smsnum < 0) {
+ pcSerial.printf("Could not read # SMS\r\n");
+ } else {
+ pcSerial.printf("%d SMS's on SIM card!\r\n", smsnum);
+ }
+ break;
+ }
+ case 'r': {
+ // read an SMS
+ flushSerial();
+ pcSerial.printf("Read #");
+ uint8_t smsn = readnumber();
+ pcSerial.printf("\r\nReading SMS #%d\r\n", smsn);
+
+ // Retrieve SMS sender address/phone number.
+ if (! fona.getSMSSender(smsn, replybuffer, 250)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("FROM: %s\r\n", replybuffer);
+
+ // Retrieve SMS value.
+ uint16_t smslen;
+ if (! fona.readSMS(smsn, replybuffer, 250, &smslen)) { // pass in buffer and max len!
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("***** SMS #%d (%d) bytes *****\r\n", smsn, smslen);
+ pcSerial.printf("%s\r\n", replybuffer);
+ pcSerial.printf("*****\r\n");
+
+ break;
+ }
+ case 'R': {
+ // read all SMS
+ int8_t smsnum = fona.getNumSMS();
+ uint16_t smslen;
+ for (int8_t smsn=1; smsn<=smsnum; smsn++) {
+ pcSerial.printf("\r\nReading SMS #%d\r\n", smsn);
+ if (!fona.readSMS(smsn, replybuffer, 250, &smslen)) { // pass in buffer and max len!
+ pcSerial.printf("Failed!\r\n");
+ 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) {
+ pcSerial.printf("[empty slot]\r\n");
+ smsnum++;
+ continue;
+ }
+
+ pcSerial.printf("***** SMS #%d (%d) bytes *****\r\n", smsn, smslen);
+ pcSerial.printf("%s\r\n", replybuffer);
+ pcSerial.printf("*****\r\n");
+ }
+ break;
+ }
+
+ case 'd': {
+ // delete an SMS
+ flushSerial();
+ pcSerial.printf("Delete #");
+ uint8_t smsn = readnumber();
+
+ pcSerial.printf("\r\nDeleting SMS #%d\r\n", smsn);
+ if (fona.deleteSMS(smsn)) {
+ pcSerial.printf("OK!\r\n");
+ } else {
+ pcSerial.printf("Couldn't delete\r\n");
+ }
+ break;
+ }
+
+ case 's': {
+ // send an SMS!
+ char sendto[10], message[141],currChar; // 'currChar' by Jonathan
+ count = 0; // reset
+
+ flushSerial();
+ pcSerial.printf("Send to #");
+ //currChar = pcSerial.getc();
+ readline(sendto, 9);
+ pcSerial.printf("%s\r\n", sendto);
+ pcSerial.printf("Type out one-line message (140 char): ");
+
+ count = 0;
+ while (1) // whole while loop added by jonathan... WORKS PERFECTLY for sending texts to phone
+ {
+
+ pcSerial.putc(currChar = pcSerial.getc()); // local echo
+ if (currChar == '\r')
+ {
+ pcSerial.printf("breaking\r\n");
+ message[count] = '\0'; // null terminate... NECESSARY??
+ break;
+ }
+ message[count] = currChar; // fill in char array
+ count++; // global var update
+ //pcSerial.printf("\n%d\n", count);
+ }
+
+ //readline(message, count); // edited by JONATHAN (140 -> 'count'). THEN COMPLETELY COMMENTED OUT, b/c I write directly to message[] above
+ //pcSerial.printf("\n%d\n", count); // added by jonathan
+
+
+ pcSerial.printf("%s\r\n", message);
+ if (!fona.sendSMS(sendto, message)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("Sent!\r\n");
+ }
+
+ break;
+ }
+
+ /*** Time ***/
+
+ case 'y': {
+ // enable network time sync
+ if (!fona.enableNetworkTimeSync(true))
+ pcSerial.printf("Failed to enable\r\n");
+ break;
+ }
+
+ case 'Y': {
+ // enable NTP time sync
+ if (!fona.enableNTPTimeSync(true, "pool.ntp.org"))
+ pcSerial.printf("Failed to enable\r\n");
+ break;
+ }
+
+ case 't': {
+ // read the time
+ char buffer[23];
+
+ fona.getTime(buffer, 23); // make sure replybuffer is at least 23 bytes!
+ pcSerial.printf("Time = %s\r\n", buffer);
+ break;
+ }
+
+ /*********************************** GPS (SIM808 only) */
+
+ case 'o': {
+ // turn GPS off
+ if (!fona.enableGPS(false))
+ pcSerial.printf("Failed to turn off\r\n");
+ break;
+ }
+ case 'O': {
+ // turn GPS on
+ if (!fona.enableGPS(true))
+ pcSerial.printf("Failed to turn on\r\n");
+ break;
+ }
+ case 'x': {
+ int8_t stat;
+ // check GPS fix
+ stat = fona.GPSstatus();
+ if (stat < 0)
+ pcSerial.printf("Failed to query\r\n");
+ if (stat == 0) pcSerial.printf("GPS off\r\n");
+ if (stat == 1) pcSerial.printf("No fix\r\n");
+ if (stat == 2) pcSerial.printf("2D fix\r\n");
+ if (stat == 3) pcSerial.printf("3D fix\r\n");
+ break;
+ }
+
+ case 'L': {
+ // check for GPS location
+ char gpsdata[80];
+ fona.getGPS(0, gpsdata, 80);
+ pcSerial.printf("Reply in format: mode,longitude,latitude,altitude,utctime(yyyymmddHHMMSS),ttff,satellites,speed,course\r\n");
+ pcSerial.printf("%s\r\n", gpsdata);
+
+ break;
+ }
+
+ case 'E': {
+ flushSerial();
+ pcSerial.printf("GPS NMEA output sentences (0 = off, 34 = RMC+GGA, 255 = all)\r\n");
+ uint8_t nmeaout = readnumber();
+
+ // turn on NMEA output
+ fona.enableGPSNMEA(nmeaout);
+
+ break;
+ }
+
+ /*********************************** GPRS */
+
+ case 'g': {
+ // turn GPRS off
+ if (!fona.enableGPRS(false))
+ pcSerial.printf("Failed to turn off\r\n");
+ break;
+ }
+ case 'G': {
+ // turn GPRS on
+ if (!fona.enableGPRS(true))
+ pcSerial.printf("Failed to turn on\r\n");
+ break;
+ }
+ case 'l': {
+ // check for GSMLOC (requires GPRS)
+ uint16_t returncode;
+
+ if (!fona.getGSMLoc(&returncode, replybuffer, 250))
+ pcSerial.printf("Failed!\r\n");
+ if (returncode == 0) {
+ pcSerial.printf("%s\r\n", replybuffer);
+ } else {
+ pcSerial.printf("Fail code #%d\r\n", returncode);
+ }
+
+ break;
+ }
+ case 'w': {
+ // read website URL
+ uint16_t statuscode;
+ int16_t length;
+ char url[80];
+
+ flushSerial();
+ pcSerial.printf("NOTE: in beta! Use small webpages to read!\r\n");
+ pcSerial.printf("URL to read (e.g. www.adafruit.com/testwifi/index.html):\r\n");
+ pcSerial.printf("http://"); readline(url, 79);
+ pcSerial.printf("%s\r\n", url);
+
+ pcSerial.printf("****\r\n");
+ if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ while (length > 0) {
+ while (fona.readable()) {
+ char c = fona.getc();
+ pcSerial.putc(c);
+ length--;
+ if (! length) break;
+ }
+ }
+ pcSerial.printf("\r\n****\r\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();
+ pcSerial.printf("NOTE: in beta! Use simple websites to post!\r\n");
+ pcSerial.printf("URL to post (e.g. httpbin.org/post):\r\n");
+ pcSerial.printf("http://"); readline(url, 79);
+ pcSerial.printf("%s\r\n", url);
+ pcSerial.printf("Data to post (e.g. \"foo\" or \"{\"simple\":\"json\"}\"):\r\n");
+ readline(data, 79);
+ pcSerial.printf("%s\r\n", data);
+
+ pcSerial.printf("****\r\n");
+ if (!fona.HTTP_POST_start(url, "text/plain", (uint8_t *) data, strlen(data), &statuscode, (uint16_t *)&length)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ while (length > 0) {
+ while (fona.readable()) {
+ char c = fona.getc();
+ pcSerial.putc(c);
+ length--;
+ if (! length) break;
+ }
+ }
+ pcSerial.printf("\r\n****\r\n");
+ fona.HTTP_POST_end();
+ break;
+ }
+ /*****************************************/
+
+ case 'S': {
+ pcSerial.printf("Creating SERIAL TUBE\r\n");
+ while (1) {
+ while (pcSerial.readable()) {
+ wait_ms(1);
+ fona.putc(pcSerial.getc());
+ }
+ if (fona.readable()) {
+ pcSerial.putc(fona.getc());
+ }
+ }
+ }
+
+ default: {
+ pcSerial.printf("Unknown command\r\n");
+ printMenu();
+ break;
+ }
+ } // end switch
+ // flush input
+ flushSerial();
+ while (fona.readable()) {
+ pcSerial.putc(fona.getc());
+ }
+ } // end while()
+}
+
+void printMenu(void) {
+ pcSerial.printf("-------------------------------------\r\n");
+ pcSerial.printf("[?] Print this menu\r\n");
+ pcSerial.printf("[a] read the ADC (2.8V max)\r\n");
+ pcSerial.printf("[b] read the Battery V and %% charged\r\n");
+ pcSerial.printf("[C] read the SIM CCID\r\n");
+ pcSerial.printf("[U] Unlock SIM with PIN code\r\n");
+ pcSerial.printf("[i] read RSSI\r\n");
+ pcSerial.printf("[n] get Network status\r\n");
+ pcSerial.printf("[v] set audio Volume\r\n");
+ pcSerial.printf("[V] get Volume\r\n");
+ pcSerial.printf("[H] set Headphone audio\r\n");
+ pcSerial.printf("[e] set External audio\r\n");
+ pcSerial.printf("[T] play audio Tone\r\n");
+ pcSerial.printf("[P] PWM/Buzzer out\r\n");
+
+ // FM (SIM800 only)
+ pcSerial.printf("[f] tune FM radio\r\n");
+ pcSerial.printf("[F] turn off FM\r\n");
+ pcSerial.printf("[m] set FM volume\r\n");
+ pcSerial.printf("[M] get FM volume\r\n");
+ pcSerial.printf("[q] get FM station signal level\r\n");
+
+ // Phone
+ pcSerial.printf("[c] make phone Call\r\n");
+ pcSerial.printf("[h] Hang up phone\r\n");
+ pcSerial.printf("[p] Pick up phone\r\n");
+
+ // SMS
+ pcSerial.printf("[N] Number of SMSs\r\n");
+ pcSerial.printf("[r] Read SMS #\r\n");
+ pcSerial.printf("[R] Read All SMS\r\n");
+ pcSerial.printf("[d] Delete SMS #\r\n");
+ pcSerial.printf("[s] Send SMS\r\n");
+
+ // Time
+ pcSerial.printf("[y] Enable network time sync\r\n");
+ pcSerial.printf("[Y] Enable NTP time sync (GPRS)\r\n");
+ pcSerial.printf("[t] Get network time\r\n");
+
+ // GPRS
+ pcSerial.printf("[G] Enable GPRS\r\n");
+ pcSerial.printf("[g] Disable GPRS\r\n");
+ pcSerial.printf("[l] Query GSMLOC (GPRS)\r\n");
+ pcSerial.printf("[w] Read webpage (GPRS)\r\n");
+ pcSerial.printf("[W] Post to website (GPRS)\r\n");
+
+ // GPS
+ pcSerial.printf("[O] Turn GPS on (SIM808)\r\n");
+ pcSerial.printf("[o] Turn GPS off (SIM808)\r\n");
+ pcSerial.printf("[x] GPS fix status (SIM808)\r\n");
+ pcSerial.printf("[L] Query GPS location (SIM808)\r\n");
+ pcSerial.printf("[E] Raw NMEA out (SIM808)\r\n");
+
+ pcSerial.printf("[S] create Serial passthru tunnel\r\n");
+ pcSerial.printf("-------------------------------------\r\n");
+ pcSerial.printf("\r\n");
+}
+
+void flushSerial() {
+ while (pcSerial.readable())
+ pcSerial.getc();
+}
+
+char readBlocking() {
+ while (!pcSerial.readable());
+ return pcSerial.getc();
+}
+
+uint16_t readnumber() {
+ uint16_t x = 0;
+ char c;
+ while (! isdigit(c = readBlocking())) {
+ //pcSerial.putc(c);
+ }
+ pcSerial.putc(c);
+ x = c - '0';
+ while (isdigit(c = readBlocking())) {
+ pcSerial.putc(c);
+ x *= 10;
+ x += c - '0';
+ }
+ return x;
+}
+
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
+ uint16_t buffidx = 0;
+ bool timeoutvalid = true;
+ if (timeout == 0) timeoutvalid = false;
+
+ while (true) {
+ if (buffidx > maxbuff) {
+ //pcSerial.printf("SPACE\r\n");
+ break;
+ }
+
+ while(pcSerial.readable()) {
+ char c = pcSerial.getc();
+
+ //pcSerial.printf("%02x#%c\r\n", c, c);
+
+ if (c == '\r')
+ continue;
+
+
+ if (c == '\r') { /////////////////////////////////////////// CHANGED BY JONATHAN: (0XA -> '\r')
+ 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++;
+
+ count++; ///////////////////////// ADED BY JONATHAN
+ }
+
+ if (timeoutvalid && timeout == 0) {
+ //pcSerial.printf("TIMEOUT\r\n");
+ break;
+ }
+ wait_ms(1);
+ }
+ buff[buffidx] = 0; // null term
+ return buffidx;
+}
+
+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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/UPDATED_BACKUP_main.txt Tue May 02 03:13:27 2017 +0000
@@ -0,0 +1,1234 @@
+// Author: Alexander Mussa, Jonathan Osei-Owusu
+// Purpose: Integrate ESP8266 WiFi Chip with Adafruit FONA Cellular Module to send text commands to Amazon Echo Dot
+// 4180 Final Project
+
+/***************************************************
+ This is an example for our Adafruit FONA Cellular Module + ESP8266 WiFi Chip
+
+ 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
+ ****************************************************/
+
+ /*
+ * Modified by Jesse Baker & George Tzintzarov 03/30/2016 for use in mbed LPC1768
+ */
+
+/*
+THIS CODE IS STILL IN PROGRESS!
+
+Open up the serial console on the Arduino at 4800 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 just before the main "while (true)" loop.
+*/
+
+#include <string.h> //// BY JONATHAN: For strcpy()
+#include <ctype.h>
+//#include "SoftSerial.h" I dont think we need this
+#include "Adafruit_FONA.h"
+#include "emic2.h"
+
+#define FONA_RST p12
+#define FONA_TX p13
+#define FONA_RX p14
+#define FONA_RI p11
+
+// this is a large buffer for replies
+char replybuffer[255];
+char smsText[255], smsPhoneNo[11]; ///// By Jonathan: Text to send to Text -> Speech chip & phone # to send to
+
+int myCount; // by Jonathan
+
+
+Serial pcSerial(USBTX, USBRX);
+Adafruit_FONA fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
+//uLCD_4DGL uLCD(p28,p27,p30);
+
+// Turn on a LED when somebody call the FONA
+DigitalOut led1(LED1);
+emic2 myTTS(p9, p10);
+
+///// ---------------- Below are global vars and functions for ESP2886 chip -------------//////////
+
+Serial esp(p28, p27); // tx, rx
+DigitalOut reset(p26);
+DigitalOut led4(LED4);
+Timer t;
+
+int count,ended,timeout;
+char buf[2024];
+char snd[1024];
+
+char myText[1024]; //////////////// by Jonathan (string to post to web server)
+
+char ssid[32] = "Brocano"; // enter WiFi router ssid inside the quotes
+char pwd [32] = "habitacion"; // enter WiFi router password inside the quotes
+
+void SendCMD(),getreply(),ESPconfig(),ESPsetbaudrate();
+ void dev_recv()
+{
+ led1 = !led1;
+ while(esp.readable()) {
+ pcSerial.putc(esp.getc());
+ }
+}
+
+ //////// JONATHAN: CODE TO EDIIIIT ////////////////
+void pc_recv() //////// CODE TO EDIT TO INPUT TEXT FROM TERMINAL -> WEBSITE //////
+{
+ led4 = !led4;
+ char currChar;
+ myText[0] = '\0'; // clear text from char array
+ int i = 0;
+ while(pcSerial.readable()) {
+ currChar = pcSerial.getc();
+ pcSerial.putc(currChar); // Added by Jonathan. local echo
+ myText[i++] = currChar;
+ }
+}
+
+
+
+
+
+
+//// ---------------------End ESP8226 Global region ------------------------------////
+
+
+
+class FonaEventListener : public Adafruit_FONA::EventListener {
+ virtual void onRing() {
+ led1 = 1;
+ }
+
+ virtual void onNoCarrier() {
+ led1 = 0;
+ }
+};
+FonaEventListener fonaEventListener;
+
+// Functions defined after main()
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
+void printMenu(void);
+void flushSerial();
+char readBlocking();
+uint16_t readnumber();
+long map(long x, long in_min, long in_max, long out_min, long out_max);
+
+int main() {
+ myTTS.volume(5);
+ myTTS.voice(0);
+ pcSerial.baud(9600);
+ wait(1);
+ pcSerial.printf("\r\n");
+
+ //// ------------------- Setting up ESP8266 WiFi Below --------------- ///
+
+ reset=0; //hardware reset for 8266
+ pcSerial.printf("\f\n\r-------------ESP8266 Hardware Reset-------------\n\r");
+ wait(0.5);
+ reset=1;
+ timeout=2;
+ getreply();
+
+ esp.baud(9600); // change this to the new ESP8266 baudrate if it is changed at any time.
+
+ //ESPsetbaudrate(); //****************** include this routine to set a different ESP8266 baudrate ******************
+
+ ESPconfig(); //****************** include Config to set the ESP8266 configuration ***********************
+
+
+
+ pcSerial.attach(&pc_recv, Serial::RxIrq);
+ esp.attach(&dev_recv, Serial::RxIrq);
+
+
+
+
+ //// ---------------------Setting up FONA GSM Chip Below ------------------- ////
+
+
+ pcSerial.printf("FONA basic test\r\n");
+ pcSerial.printf("Initializing....(May take 3 seconds)\r\n");
+
+ // See if the FONA is responding
+ if (! fona.begin(9600)) {
+ pcSerial.printf("Couldn't find FONA\r\n");
+ while (1);
+ }
+ fona.setEventListener(&fonaEventListener);
+ pcSerial.printf("FONA is OK\r\n");
+
+ // Print SIM card IMEI number.
+ char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
+ uint8_t imeiLen = fona.getIMEI(imei);
+ if (imeiLen > 0) {
+ pcSerial.printf("SIM card IMEI: %s\r\n", 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("your APN", "your username", "your password");
+ //fona.setGPRSNetworkSettings("web.pt.lu", "", "");
+
+ // 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();
+
+
+ while (true) {
+
+ pcSerial.printf("FONA> ");
+ // if nothing is available on the pcSearial port but there is something on the fona serial, then print it (flush it) to the pc Serial
+
+ /*
+ while (! pcSerial.readable() ) {
+ if (fona.readable()) {
+ pcSerial.putc(fona.getc()); /////// RESPONSIBLE FOR DETECTING RECV'D TXT///////
+ }
+ } */
+
+ //////////////////// By Jonathan: Edited version of while() above
+ while (! pcSerial.readable()) {
+ if (fona.readable()) {
+
+ //// Printf that incoming SMS detected
+ pcSerial.putc(fona.getc());
+
+
+ // ----------------------------------------------------------------//
+
+ // read an SMS + send -> TTS chip
+ flushSerial();
+ pcSerial.printf("\r\nReading SMS #1\r\n");
+
+ // Retrieve SMS sender address/phone number.
+ if (! fona.getSMSSender(1, replybuffer, 250)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("FROM: %s\r\n", replybuffer);
+ for (int i = 0; i < 10; i++) { /////// BY JONATHAN to store phone # to respond to
+ smsPhoneNo[i] = replybuffer[i + 2]; // chop off the "+1" from phone # returned by replybuffer
+ }
+ smsPhoneNo[10] = '\0'; // null terminate.... NECESSARY??
+ pcSerial.printf("FROM: %s\r\n", smsPhoneNo);
+
+ // Retrieve SMS value.
+ uint16_t smslen;
+ if (! fona.readSMS(1, replybuffer, 250, &smslen)) { // pass in buffer and max len!
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("***** SMS #1 (%d) bytes *****\r\n", smslen);
+ pcSerial.printf("%s\r\n", replybuffer);
+ pcSerial.printf("*****\r\n");
+
+
+
+ //char message[255]; // CHANGED BY JONATHAN. 141 -> 255
+ char myString[255];
+
+ for (int i = 0; i < 255; i++) {
+ myString[i] = replybuffer[i + 5]; // chop of the "Alexa string"
+ }
+
+ strcpy(smsText, "Uh lex uh "); //Pronunciation Correction.
+ strcat(smsText, myString);
+ myTTS.speakf("S%s\r", smsText); // Send text message to the text to speech module.
+
+
+ // ----------------------------------------------------------------//
+
+ // send an SMS back!
+ char message[255];
+
+ strcpy(message, "");
+
+ flushSerial();
+
+ pcSerial.printf("Replying to %s\r\n", smsPhoneNo);
+
+
+ if(strstr(replybuffer, "how old are you")) { // if reply buffer contains that string
+ strcpy(message, "I'm 2 in human years, 14 in dog years, and 25 in cat years. I think AI years are marked in nanoseconds, so that makes me, like, a scrillion!");
+ }
+ else if(strstr(replybuffer, "what is the world population")) {
+ strcpy(message, "The population of the world is about 7 Billion 400 Million.");
+ }
+ else if(strstr(replybuffer, "integral of x squared")) {
+ strcpy(message, "The integral of x squared is one third x cubed plus a constant.");
+ }
+ else if(strstr(replybuffer, "discrete co sine transform")) {
+ strcpy(message, "The discrete cosine transform expresses a finite sequence of data points in terms of a sum of cosine function oscillating at different frequencies.");
+ }
+ else {
+ strcpy(message, "Sorry, command not recognized.");
+ }
+
+
+
+ // message[255] = '\0';
+
+ pcSerial.printf("%s\r\n", message);
+ if (!fona.sendSMS(smsPhoneNo, message))
+ pcSerial.printf("Failed\r\n");
+ else
+ pcSerial.printf("Sent!\r\n");
+
+ // ----------------------------------------------------------------//
+
+ // delete an SMS after response sent back
+ flushSerial();
+ pcSerial.printf("\r\nDeleting SMS #1\r\n");
+ if (fona.deleteSMS(1)) // delete SMS #1
+ pcSerial.printf("OK!\r\n");
+ else
+ pcSerial.printf("Couldn't delete\r\n");
+
+ } // end if
+ } // end while
+
+
+
+ // Above while() by Jonathan //
+
+
+
+ // get the input command from the terminal
+ char command = pcSerial.getc();
+ pcSerial.printf("%c\r\n", command); //loops back to COM port
+
+
+ switch (command) {
+ case '?': {
+ printMenu();
+ break;
+ }
+
+ case 'a': {
+ // read the ADC
+ uint16_t adc;
+ if (! fona.getADCVoltage(&adc)) {
+ pcSerial.printf("Failed to read ADC\r\n");
+ } else {
+ pcSerial.printf("ADC = %d mV\r\n", adc);
+ }
+ break;
+ }
+
+ case 'b': {
+ // read the battery voltage and percentage
+ uint16_t vbat;
+ if (! fona.getBattVoltage(&vbat)) {
+ pcSerial.printf("Failed to read Batt\r\n");
+ } else {
+ pcSerial.printf("VBat = %d mV\r\n", vbat);
+ }
+
+ if (! fona.getBattPercent(&vbat)) {
+ pcSerial.printf("Failed to read Batt\r\n");
+ } else {
+ pcSerial.printf("VPct = %d%%\r\n", vbat);
+ }
+
+ break;
+ }
+
+ case 'U': {
+ // Unlock the SIM with a PIN code
+ char PIN[5];
+ flushSerial();
+ pcSerial.printf("Enter 4-digit PIN\r\n");
+ readline(PIN, 3);
+ pcSerial.printf("%s\r\n", PIN);
+ pcSerial.printf("Unlocking SIM card: ");
+ if (! fona.unlockSIM(PIN)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ case 'C': {
+ // read the CCID
+ fona.getSIMCCID(replybuffer); // make sure replybuffer is at least 21 bytes!
+ pcSerial.printf("SIM CCID = %s\r\n", replybuffer);
+ break;
+ }
+
+ case 'i': {
+ // 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);
+ }
+ pcSerial.printf("%d dBm\r\n", r);
+
+ break;
+ }
+
+ case 'n': {
+ // read the network/cellular status
+ uint8_t n = fona.getNetworkStatus();
+ pcSerial.printf("Network status %d: ", n);
+ if (n == 0) pcSerial.printf("Not registered\r\n");
+ if (n == 1) pcSerial.printf("Registered (home)\r\n");
+ if (n == 2) pcSerial.printf("Not registered (searching)\r\n");
+ if (n == 3) pcSerial.printf("Denied\r\n");
+ if (n == 4) pcSerial.printf("Unknown\r\n");
+ if (n == 5) pcSerial.printf("Registered roaming\r\n");
+ break;
+ }
+
+ /*** Audio ***/
+ case 'v': {
+ // set volume
+ flushSerial();
+ pcSerial.printf("Set Vol %%");
+ uint8_t vol = readnumber();
+ pcSerial.printf("\r\n");
+ if (! fona.setVolume(vol)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ case 'V': {
+ uint8_t v = fona.getVolume();
+ pcSerial.printf("%d%%\r\n", v);
+
+ break;
+ }
+
+ case 'H': {
+ // Set Headphone output
+ if (! fona.setAudio(FONA_HEADSETAUDIO)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ fona.setMicVolume(FONA_HEADSETAUDIO, 15);
+ break;
+ }
+ case 'e': {
+ // Set External output
+ if (! fona.setAudio(FONA_EXTAUDIO)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+
+ fona.setMicVolume(FONA_EXTAUDIO, 10);
+ break;
+ }
+
+ case 'T': {
+ // play tone
+ flushSerial();
+ pcSerial.printf("Play tone #");
+ uint8_t kittone = readnumber();
+ pcSerial.printf("\r\n");
+ // play for 1 second (1000 ms)
+ if (! fona.playToolkitTone(kittone, 1000)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ /*** FM Radio ***/
+
+ case 'f': {
+ // get freq
+ flushSerial();
+ pcSerial.printf("FM Freq (eg 1011 == 101.1 MHz): ");
+ uint16_t station = readnumber();
+ pcSerial.printf("\r\n");
+ // FM radio ON using headset
+ if (fona.FMradio(true, FONA_HEADSETAUDIO)) {
+ pcSerial.printf("Opened\r\n");
+ }
+ if (! fona.tuneFMradio(station)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("Tuned\r\n");
+ }
+ break;
+ }
+ case 'F': {
+ // FM radio off
+ if (! fona.FMradio(false)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+ case 'm': {
+ // Set FM volume.
+ flushSerial();
+ pcSerial.printf("Set FM Vol [0-6]:");
+ uint8_t vol = readnumber();
+ pcSerial.printf("\r\n");
+ if (!fona.setFMVolume(vol)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+ case 'M': {
+ // Get FM volume.
+ int8_t fmvol = fona.getFMVolume();
+ if (fmvol < 0) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("FM volume: %d\r\n", fmvol);
+ }
+ break;
+ }
+ case 'q': {
+ // Get FM station signal level (in decibels).
+ flushSerial();
+ pcSerial.printf("FM Freq (eg 1011 == 101.1 MHz): ");
+ uint16_t station = readnumber();
+ pcSerial.printf("\r\n");
+ int8_t level = fona.getFMSignalLevel(station);
+ if (level < 0) {
+ pcSerial.printf("Failed! Make sure FM radio is on (tuned to station).\r\n");
+ } else {
+ pcSerial.printf("Signal level (dB): %d\r\n", level);
+ }
+ break;
+ }
+
+ /*** PWM ***/
+
+ case 'P': {
+ // PWM Buzzer output @ 2KHz max
+ flushSerial();
+ pcSerial.printf("PWM Freq, 0 = Off, (1-2000): ");
+ uint16_t freq = readnumber();
+ pcSerial.printf("\r\n");
+ if (! fona.setPWM(freq)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ /*** Call ***/
+ case 'c': {
+ // call a phone!
+ char number[10];
+ flushSerial();
+ pcSerial.printf("Call #");
+ readline(number, 9);
+ pcSerial.printf("\r\n");
+ pcSerial.printf("Calling %s\r\n", number);
+ if (!fona.callPhone(number)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("Sent!\r\n");
+ }
+
+ break;
+ }
+ case 'h': {
+ // hang up!
+ if (! fona.hangUp()) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ case 'p': {
+ // pick up!
+ if (! fona.pickUp()) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("OK!\r\n");
+ }
+ break;
+ }
+
+ /*** SMS ***/
+
+ case 'N': {
+ // read the number of SMS's!
+ int8_t smsnum = fona.getNumSMS();
+ if (smsnum < 0) {
+ pcSerial.printf("Could not read # SMS\r\n");
+ } else {
+ pcSerial.printf("%d SMS's on SIM card!\r\n", smsnum);
+ }
+ break;
+ }
+ case 'r': {
+ // read an SMS
+ flushSerial();
+ pcSerial.printf("Read #");
+ uint8_t smsn = readnumber();
+ pcSerial.printf("\r\nReading SMS #%d\r\n", smsn);
+
+ // Retrieve SMS sender address/phone number.
+ if (! fona.getSMSSender(smsn, replybuffer, 250)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("FROM: %s\r\n", replybuffer);
+
+ // Retrieve SMS value.
+ uint16_t smslen;
+ if (! fona.readSMS(smsn, replybuffer, 250, &smslen)) { // pass in buffer and max len!
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("***** SMS #%d (%d) bytes *****\r\n", smsn, smslen);
+ pcSerial.printf("%s\r\n", replybuffer);
+ pcSerial.printf("*****\r\n");
+
+ break;
+ }
+ case 'R': {
+ // read all SMS
+ int8_t smsnum = fona.getNumSMS();
+ uint16_t smslen;
+ for (int8_t smsn=1; smsn<=smsnum; smsn++) {
+ pcSerial.printf("\r\nReading SMS #%d\r\n", smsn);
+ if (!fona.readSMS(smsn, replybuffer, 250, &smslen)) { // pass in buffer and max len!
+ pcSerial.printf("Failed!\r\n");
+ 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) {
+ pcSerial.printf("[empty slot]\r\n");
+ smsnum++;
+ continue;
+ }
+
+ pcSerial.printf("***** SMS #%d (%d) bytes *****\r\n", smsn, smslen);
+ pcSerial.printf("%s\r\n", replybuffer);
+ pcSerial.printf("*****\r\n");
+ }
+ break;
+ }
+
+ case 'd': {
+ // delete an SMS
+ flushSerial();
+ pcSerial.printf("Delete #");
+ uint8_t smsn = readnumber();
+
+ pcSerial.printf("\r\nDeleting SMS #%d\r\n", smsn);
+ if (fona.deleteSMS(smsn)) {
+ pcSerial.printf("OK!\r\n");
+ } else {
+ pcSerial.printf("Couldn't delete\r\n");
+ }
+ break;
+ }
+
+ case 's': {
+ // send an SMS!
+ char sendto[10], message[141],currChar; // 'currChar' by Jonathan
+ myCount = 0; // reset
+
+ flushSerial();
+ pcSerial.printf("Send to #");
+ //currChar = pcSerial.getc();
+ readline(sendto, 9);
+ pcSerial.printf("%s\r\n", sendto);
+ pcSerial.printf("Type out one-line message (140 char): ");
+
+ myCount = 0;
+ while (1) // whole while loop added by jonathan... WORKS PERFECTLY for sending texts to phone
+ {
+
+ pcSerial.putc(currChar = pcSerial.getc()); // local echo
+ if (currChar == '\r')
+ {
+ pcSerial.printf("breaking\r\n");
+ message[myCount] = '\0'; // null terminate... NECESSARY??
+ break;
+ }
+ message[myCount] = currChar; // fill in char array
+ myCount++; // global var update
+ //pcSerial.printf("\n%d\n", myCount);
+ }
+
+ //readline(message, myCount); // edited by JONATHAN (140 -> 'myCount'). THEN COMPLETELY COMMENTED OUT, b/c I write directly to message[] above
+ //pcSerial.printf("\n%d\n", myCount); // added by jonathan
+
+
+ pcSerial.printf("%s\r\n", message);
+ if (!fona.sendSMS(sendto, message)) {
+ pcSerial.printf("Failed\r\n");
+ } else {
+ pcSerial.printf("Sent!\r\n");
+ }
+
+ break;
+ }
+
+ /*** Time ***/
+
+ case 'y': {
+ // enable network time sync
+ if (!fona.enableNetworkTimeSync(true))
+ pcSerial.printf("Failed to enable\r\n");
+ break;
+ }
+
+ case 'Y': {
+ // enable NTP time sync
+ if (!fona.enableNTPTimeSync(true, "pool.ntp.org"))
+ pcSerial.printf("Failed to enable\r\n");
+ break;
+ }
+
+ case 't': {
+ // read the time
+ char buffer[23];
+
+ fona.getTime(buffer, 23); // make sure replybuffer is at least 23 bytes!
+ pcSerial.printf("Time = %s\r\n", buffer);
+ break;
+ }
+
+ /*********************************** GPS (SIM808 only) */
+
+ case 'o': {
+ // turn GPS off
+ if (!fona.enableGPS(false))
+ pcSerial.printf("Failed to turn off\r\n");
+ break;
+ }
+ case 'O': {
+ // turn GPS on
+ if (!fona.enableGPS(true))
+ pcSerial.printf("Failed to turn on\r\n");
+ break;
+ }
+ case 'x': {
+ int8_t stat;
+ // check GPS fix
+ stat = fona.GPSstatus();
+ if (stat < 0)
+ pcSerial.printf("Failed to query\r\n");
+ if (stat == 0) pcSerial.printf("GPS off\r\n");
+ if (stat == 1) pcSerial.printf("No fix\r\n");
+ if (stat == 2) pcSerial.printf("2D fix\r\n");
+ if (stat == 3) pcSerial.printf("3D fix\r\n");
+ break;
+ }
+
+ case 'L': {
+ // check for GPS location
+ char gpsdata[80];
+ fona.getGPS(0, gpsdata, 80);
+ pcSerial.printf("Reply in format: mode,longitude,latitude,altitude,utctime(yyyymmddHHMMSS),ttff,satellites,speed,course\r\n");
+ pcSerial.printf("%s\r\n", gpsdata);
+
+ break;
+ }
+
+ case 'E': {
+ flushSerial();
+ pcSerial.printf("GPS NMEA output sentences (0 = off, 34 = RMC+GGA, 255 = all)\r\n");
+ uint8_t nmeaout = readnumber();
+
+ // turn on NMEA output
+ fona.enableGPSNMEA(nmeaout);
+
+ break;
+ }
+
+ /*********************************** GPRS */
+
+ case 'g': {
+ // turn GPRS off
+ if (!fona.enableGPRS(false))
+ pcSerial.printf("Failed to turn off\r\n");
+ break;
+ }
+ case 'G': {
+ // turn GPRS on
+ if (!fona.enableGPRS(true))
+ pcSerial.printf("Failed to turn on\r\n");
+ break;
+ }
+ case 'l': {
+ // check for GSMLOC (requires GPRS)
+ uint16_t returncode;
+
+ if (!fona.getGSMLoc(&returncode, replybuffer, 250))
+ pcSerial.printf("Failed!\r\n");
+ if (returncode == 0) {
+ pcSerial.printf("%s\r\n", replybuffer);
+ } else {
+ pcSerial.printf("Fail code #%d\r\n", returncode);
+ }
+
+ break;
+ }
+ case 'w': {
+ // read website URL
+ uint16_t statuscode;
+ int16_t length;
+ char url[80];
+
+ flushSerial();
+ pcSerial.printf("NOTE: in beta! Use small webpages to read!\r\n");
+ pcSerial.printf("URL to read (e.g. www.adafruit.com/testwifi/index.html):\r\n");
+ pcSerial.printf("http://"); readline(url, 79);
+ pcSerial.printf("%s\r\n", url);
+
+ pcSerial.printf("****\r\n");
+ if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ while (length > 0) {
+ while (fona.readable()) {
+ char c = fona.getc();
+ pcSerial.putc(c);
+ length--;
+ if (! length) break;
+ }
+ }
+ pcSerial.printf("\r\n****\r\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();
+ pcSerial.printf("NOTE: in beta! Use simple websites to post!\r\n");
+ pcSerial.printf("URL to post (e.g. httpbin.org/post):\r\n");
+ pcSerial.printf("http://"); readline(url, 79);
+ pcSerial.printf("%s\r\n", url);
+ pcSerial.printf("Data to post (e.g. \"foo\" or \"{\"simple\":\"json\"}\"):\r\n");
+ readline(data, 79);
+ pcSerial.printf("%s\r\n", data);
+
+ pcSerial.printf("****\r\n");
+ if (!fona.HTTP_POST_start(url, "text/plain", (uint8_t *) data, strlen(data), &statuscode, (uint16_t *)&length)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ while (length > 0) {
+ while (fona.readable()) {
+ char c = fona.getc();
+ pcSerial.putc(c);
+ length--;
+ if (! length) break;
+ }
+ }
+ pcSerial.printf("\r\n****\r\n");
+ fona.HTTP_POST_end();
+ break;
+ }
+ /*****************************************/
+
+ case 'S': {
+ pcSerial.printf("Creating SERIAL TUBE\r\n");
+ while (1) {
+ while (pcSerial.readable()) {
+ wait_ms(1);
+ fona.putc(pcSerial.getc());
+ }
+ if (fona.readable()) {
+ pcSerial.putc(fona.getc());
+ }
+ }
+ }
+
+ default: {
+ pcSerial.printf("Unknown command\r\n");
+ printMenu();
+ break;
+ }
+ } // end switch
+ // flush input
+ flushSerial();
+ while (fona.readable()) {
+ pcSerial.putc(fona.getc());
+ }
+ } // end while()
+} // end main
+
+void printMenu(void) {
+ pcSerial.printf("-------------------------------------\r\n");
+ pcSerial.printf("[?] Print this menu\r\n");
+ pcSerial.printf("[a] read the ADC (2.8V max)\r\n");
+ pcSerial.printf("[b] read the Battery V and %% charged\r\n");
+ pcSerial.printf("[C] read the SIM CCID\r\n");
+ pcSerial.printf("[U] Unlock SIM with PIN code\r\n");
+ pcSerial.printf("[i] read RSSI\r\n");
+ pcSerial.printf("[n] get Network status\r\n");
+ pcSerial.printf("[v] set audio Volume\r\n");
+ pcSerial.printf("[V] get Volume\r\n");
+ pcSerial.printf("[H] set Headphone audio\r\n");
+ pcSerial.printf("[e] set External audio\r\n");
+ pcSerial.printf("[T] play audio Tone\r\n");
+ pcSerial.printf("[P] PWM/Buzzer out\r\n");
+
+ // FM (SIM800 only)
+ pcSerial.printf("[f] tune FM radio\r\n");
+ pcSerial.printf("[F] turn off FM\r\n");
+ pcSerial.printf("[m] set FM volume\r\n");
+ pcSerial.printf("[M] get FM volume\r\n");
+ pcSerial.printf("[q] get FM station signal level\r\n");
+
+ // Phone
+ pcSerial.printf("[c] make phone Call\r\n");
+ pcSerial.printf("[h] Hang up phone\r\n");
+ pcSerial.printf("[p] Pick up phone\r\n");
+
+ // SMS
+ pcSerial.printf("[N] Number of SMSs\r\n");
+ pcSerial.printf("[r] Read SMS #\r\n");
+ pcSerial.printf("[R] Read All SMS\r\n");
+ pcSerial.printf("[d] Delete SMS #\r\n");
+ pcSerial.printf("[s] Send SMS\r\n");
+
+ // Time
+ pcSerial.printf("[y] Enable network time sync\r\n");
+ pcSerial.printf("[Y] Enable NTP time sync (GPRS)\r\n");
+ pcSerial.printf("[t] Get network time\r\n");
+
+ // GPRS
+ pcSerial.printf("[G] Enable GPRS\r\n");
+ pcSerial.printf("[g] Disable GPRS\r\n");
+ pcSerial.printf("[l] Query GSMLOC (GPRS)\r\n");
+ pcSerial.printf("[w] Read webpage (GPRS)\r\n");
+ pcSerial.printf("[W] Post to website (GPRS)\r\n");
+
+ // GPS
+ pcSerial.printf("[O] Turn GPS on (SIM808)\r\n");
+ pcSerial.printf("[o] Turn GPS off (SIM808)\r\n");
+ pcSerial.printf("[x] GPS fix status (SIM808)\r\n");
+ pcSerial.printf("[L] Query GPS location (SIM808)\r\n");
+ pcSerial.printf("[E] Raw NMEA out (SIM808)\r\n");
+
+ pcSerial.printf("[S] create Serial passthru tunnel\r\n");
+ pcSerial.printf("-------------------------------------\r\n");
+ pcSerial.printf("\r\n");
+}
+
+void flushSerial() {
+ while (pcSerial.readable())
+ pcSerial.getc();
+}
+
+char readBlocking() {
+ while (!pcSerial.readable());
+ return pcSerial.getc();
+}
+
+uint16_t readnumber() {
+ uint16_t x = 0;
+ char c;
+ while (! isdigit(c = readBlocking())) {
+ //pcSerial.putc(c);
+ }
+ pcSerial.putc(c);
+ x = c - '0';
+ while (isdigit(c = readBlocking())) {
+ pcSerial.putc(c);
+ x *= 10;
+ x += c - '0';
+ }
+ return x;
+}
+
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
+ uint16_t buffidx = 0;
+ bool timeoutvalid = true;
+ if (timeout == 0) timeoutvalid = false;
+
+ while (true) {
+ if (buffidx > maxbuff) {
+ //pcSerial.printf("SPACE\r\n");
+ break;
+ }
+
+ while(pcSerial.readable()) {
+ char c = pcSerial.getc();
+
+ //pcSerial.printf("%02x#%c\r\n", c, c);
+
+ if (c == '\r')
+ continue;
+
+
+ if (c == '\r') { /////////////////////////////////////////// CHANGED BY JONATHAN: (0XA -> '\r')
+ 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++;
+
+ myCount++; ///////////////////////// ADED BY JONATHAN
+ }
+
+ if (timeoutvalid && timeout == 0) {
+ //pcSerial.printf("TIMEOUT\r\n");
+ break;
+ }
+ wait_ms(1);
+ }
+ buff[buffidx] = 0; // null term
+ return buffidx;
+}
+
+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;
+}
+
+
+///// ------------------- Below is ESP8266 WiFi Chip Config + Setup COde -------------------- ////
+// Sets new ESP8266 baurate, change the esp.baud(xxxxx) to match your new setting once this has been executed
+void ESPsetbaudrate()
+{
+ strcpy(snd, "AT+CIOBAUD=115200\r\n"); // change the numeric value to the required baudrate
+ SendCMD();
+}
+
+ void ESPstart() {
+ wait(3);
+ pcSerial.printf("\f---------- Starting ESP Config ----------\r\n\n");
+ strcpy(snd,".\r\n.\r\n");
+ SendCMD();
+}
+
+void ESPreset() {
+ wait(1);
+ pcSerial.printf("---------- Reset & get Firmware ----------\r\n");
+ strcpy(snd,"node.restart()\r\n");
+ SendCMD();
+ timeout=5;
+ getreply();
+ pcSerial.printf(buf);
+}
+
+void ESPversion() {
+ wait(1);
+ pcSerial.printf("\n---------- Get Version ----------\r\n");
+ strcpy(snd,"print(node.info())\r\n");
+ SendCMD();
+ timeout=4;
+ getreply();
+ pcSerial.printf(buf);
+}
+
+void ESPmode() {
+ wait(2);
+
+ // set CWMODE to 1=Station,2=AP,3=BOTH, default mode 1 (Station)
+ pcSerial.printf("\n---------- Setting Mode ----------\r\n");
+ strcpy(snd, "wifi.setmode(wifi.STATION)\r\n");
+ SendCMD();
+ timeout=4;
+ getreply();
+ pcSerial.printf(buf);
+}
+
+void ESPconnect() {
+ pcSerial.printf("\n---------- Connecting to AP ----------\r\n");
+ pcSerial.printf("ssid = %s pwd = %s\r\n",ssid,pwd);
+ strcpy(snd, "wifi.sta.config(\"");
+ strcat(snd, ssid);
+ strcat(snd, "\",\"");
+ strcat(snd, pwd);
+ strcat(snd, "\")\r\n");
+ SendCMD();
+ timeout=10;
+ getreply();
+ pcSerial.printf(buf);
+ wait(2);
+}
+
+void ESPip() {
+ pcSerial.printf("\n---------- Get chip's IP ----------\r\n");
+
+ strcpy(snd, "print(wifi.sta.getip())\r\n");
+ SendCMD(); // get device IP
+ timeout=3;
+ getreply();
+ pcSerial.printf(buf);
+
+ wait(1);
+}
+
+void ESPstatus() {
+ pcSerial.printf("\n---------- Get Connection Status ----------\r\n");
+ strcpy(snd, "print(wifi.sta.status())\r\n");
+ SendCMD();
+ timeout=5;
+ getreply();
+ pcSerial.printf(buf);
+
+ pcSerial.printf("\n\n\n If you get a valid (non zero) IP, ESP8266 has been set up.\r\n");
+ pcSerial.printf(" Run this if you want to reconfig the ESP8266 at any time.\r\n");
+ pcSerial.printf(" It saves the SSID and password settings internally\r\n");
+ wait(5);
+}
+
+// +++++++++++++++++++++++++++++++++ This is for ESP8266 config only, run this once to set up the ESP8266 +++++++++++++++
+void ESPconfig()
+{
+ ESPstart();
+ ESPreset();
+ ESPversion();
+ ESPmode();
+ ESPconnect();
+ ESPip();
+ ESPstatus();
+
+ /*
+ pcSerial.printf("\n---------- Connecting to website -----------\r\n");
+
+ strcpy(snd, "conn=net.createConnection(net.TCP, 0)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:on(\"receive\",function(conn,payload)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "end)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:connect(80,\"https://sites.google.com/site/4180echo/home\")");
+ SendCMD();
+ wait(1);
+
+ strcpy("conn:on(\"connection\", function(conn, payload)");
+ SendCMD();
+ wait(1);
+ */
+
+
+
+
+
+ pcSerial.printf("\n---------- Setting up http server ----------\r\n");
+ strcpy(snd, "srv=net.createServer(net.TCP)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "srv:listen(80,function(conn)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "conn:on(\"receive\",function(conn,payload)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "print(payload)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:send(\"<!DOCTYPE html>\")\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:send(\"<html>\")\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:send(\"<h1> Hi Jonathan!</h1>\")\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:send(\"<h2> test</h2>\")\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:send(\"</html>\")\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "end)\r\n");
+ SendCMD();
+ wait(1);
+
+ strcpy(snd, "conn:on(\"sent\",function(conn) conn:close() end)\r\n");
+ SendCMD();
+ wait(1);
+ strcpy(snd, "end)\r\n");
+ SendCMD();
+ wait(1);
+ timeout=17;
+ getreply();
+ pcSerial.printf(buf);
+ pcSerial.printf("\r\nDONE");
+}
+
+void SendCMD()
+{
+ esp.printf("%s", snd);
+}
+
+void getreply()
+{
+ memset(buf, '\0', sizeof(buf));
+ t.start();
+ ended=0;
+ count=0;
+ while(!ended) {
+ if(esp.readable()) {
+ buf[count] = esp.getc();
+ count++;
+ }
+ if(t.read() > timeout) {
+ ended = 1;
+ t.stop();
+ t.reset();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emic2.lib Tue May 02 03:13:27 2017 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/4180_1/code/emic2/#b95ede38e19d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue May 02 03:13:27 2017 +0000
@@ -0,0 +1,668 @@
+// By: Jonathan Osei-Owusu, Alex Mussa
+// 4180 Final Project
+
+// Goal: ESP8266 static page WEB server to send text queries to Alexa via Mbed and TExt-to-Speech module.
+// WEB server accessible from any network.
+// Also uses FONA chip to allow Alexa text queries via SMS.
+
+
+#include "mbed.h"
+#include "emic2.h"
+#include <string.h>
+#include <ctype.h>
+#include "Adafruit_FONA.h"
+
+/////// ------ Begin FONA Global Region ----- ////////
+
+#define FONA_RST p12
+#define FONA_TX p13
+#define FONA_RX p14
+#define FONA_RI p11
+
+// this is a large buffer for replies
+char replybuffer[255];
+char smsText[255], smsPhoneNo[11]; ///// By Jonathan: Text to send to Text -> Speech chip & phone # to send to
+int count; // by Jonathan
+Serial pcSerial(USBTX, USBRX);
+Adafruit_FONA fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
+void replySMS(char*);
+
+// Turn on a LED when somebody call the FONA
+emic2 myTTS(p9, p10);
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+class FonaEventListener : public Adafruit_FONA::EventListener {
+ virtual void onRing() {
+ led1 = 1;
+ }
+
+ virtual void onNoCarrier() {
+ led1 = 0;
+ }
+};
+FonaEventListener fonaEventListener;
+
+// Functions defined after main()
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);
+void printMenu(void);
+void flushSerial();
+char readBlocking();
+uint16_t readnumber();
+long map(long x, long in_min, long in_max, long out_min, long out_max);
+
+/////// ------ End FONA Global Region ----- ////////
+
+
+////// ------- Begin ESP Global Region -------- //////
+
+Serial esp(p28, p27); // tx, rx
+
+// some test values to show on web page
+AnalogIn Ain1(p18);
+AnalogIn Ain2(p19);
+
+/*
+char ssid[32] = "hsd"; // enter WiFi router ssid inside the quotes
+char pwd [32] = "austin123"; // enter WiFi router password inside the quotes
+*/
+float temperature, AdcIn, Ht;
+float R1=100000, R2=10000; // resistor values to give a 10:1 reduction of measured AnalogIn voltage
+char Vcc[10];
+char Temp[10];
+
+// things for sending/receiving data over serial
+volatile int tx_in=0;
+volatile int tx_out=0;
+volatile int rx_in=0;
+volatile int rx_out=0;
+const int buffer_size = 4095;
+char tx_buffer[buffer_size+1];
+char rx_buffer[buffer_size+1];
+void Tx_interrupt();
+void Rx_interrupt();
+void send_line();
+void read_line();
+
+int DataRX;
+int update;
+int espCount;
+char cmdbuff[1024];
+char replybuff[4096];
+char webdata[4096]; // This may need to be bigger depending on WEB browser used
+char webbuff[4096]; // Currently using 1986 characters, Increase this if more web page data added
+char timebuf[30];
+void SendCMD(),getreply(),ReadWebData(),startserver();
+void gettime(),setRTC(),gettemp(),getbattery();
+char rx_line[1024];
+int port =80; // set server port
+int SERVtimeout =5; // set server timeout in seconds in case link breaks.
+struct tm t;
+// manual set RTC values
+int minute =00; // 0-59
+int hour =12; // 2-23
+int dayofmonth =26; // 1-31
+int month =8; // 1-12
+int year =15; // last 2 digits
+
+
+//// -------- End ESP Global region -------- /////
+
+int main()
+{
+ myTTS.volume(5);
+ myTTS.voice(0);
+
+ pcSerial.baud(9600);
+ esp.baud(9600);
+ wait(1);
+
+ ////---------------- Begin FONA init setup Region -------//
+
+ pcSerial.printf("\r\n");
+
+ pcSerial.printf("FONA basic test\r\n");
+ pcSerial.printf("Initializing....(May take 3 seconds)\r\n");
+
+ // See if the FONA is responding
+ if (! fona.begin(9600)) {
+ pcSerial.printf("Couldn't find FONA\r\n");
+ while (1);
+ }
+ fona.setEventListener(&fonaEventListener);
+ pcSerial.printf("FONA is OK\r\n");
+
+ // Print SIM card IMEI number.
+ char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
+ uint8_t imeiLen = fona.getIMEI(imei);
+ if (imeiLen > 0) {
+ pcSerial.printf("SIM card IMEI: %s\r\n", imei);
+ }
+
+ ////----- End FONA init setup region -----////
+
+
+ ////----- Begin ESP init setup region ----////
+
+ led1 = 0, led2 = 0, led3 = 0, led4 = 0;
+ // Setup a serial interrupt function to receive data
+ esp.attach(&Rx_interrupt, Serial::RxIrq);
+ // Setup a serial interrupt function to transmit data
+ esp.attach(&Tx_interrupt, Serial::TxIrq);
+ if (time(NULL) < 1420070400) {
+ setRTC();
+ }
+ startserver();
+ DataRX=0;
+ espCount=0;
+ wait(3);
+
+ ////----- End ESP init setup region ----////
+
+ while(1) {
+ ////---- Begin ESP loop ----////
+ if(DataRX==1) {
+ ReadWebData();
+ esp.attach(&Rx_interrupt, Serial::RxIrq);
+ }
+ if(update==1) // update time, hit count, and analog levels in the HUZZAH chip
+ {
+ // get new values
+ gettime();
+ gettemp();
+ getbattery();
+ espCount++;
+ // send new values
+ sprintf(cmdbuff, "espCount,time,analog1,analog2=%d,\"%s\",\"%s\",\"%s\"\r\n",espCount,timebuf,Temp,Vcc);
+ SendCMD();
+ getreply();
+ update=0;
+ }
+ ////---- End ESP loop ----////
+
+ ////---- Begin FONA loop ----////
+
+ //pcSerial.printf("FONA waiting for SMS...\r\n");
+
+ //while (! pcSerial.readable()) {
+ //if (fona.readable()) {
+ while (fona.readable() && ! pcSerial.readable()) {
+ //// Printf that incoming SMS detected
+ pcSerial.putc(fona.getc());
+
+
+ // ----------------------------------------------------------------//
+
+ // read an SMS + send -> TTS chip
+ flushSerial();
+ pcSerial.printf("\r\nReading SMS #1\r\n");
+
+ // Retrieve SMS sender address/phone number.
+ if (! fona.getSMSSender(1, replybuffer, 250)) {
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("FROM: %s\r\n", replybuffer);
+ for (int i = 0; i < 10; i++) { /////// BY JONATHAN to store phone # to respond to
+ smsPhoneNo[i] = replybuffer[i + 2]; // chop off the "+1" from phone # returned by replybuffer
+ }
+ smsPhoneNo[10] = '\0'; // null terminate.... NECESSARY??
+ pcSerial.printf("FROM: %s\r\n", smsPhoneNo);
+
+ // Retrieve SMS value.
+ uint16_t smslen;
+ if (! fona.readSMS(1, replybuffer, 250, &smslen)) { // pass in buffer and max len!
+ pcSerial.printf("Failed!\r\n");
+ break;
+ }
+ pcSerial.printf("***** SMS #1 (%d) bytes *****\r\n", smslen);
+ pcSerial.printf("%s\r\n", replybuffer);
+ pcSerial.printf("*****\r\n");
+
+
+
+ //char message[255]; // CHANGED BY JONATHAN. 141 -> 255
+ char myString[255];
+
+ for (int i = 0; i < 255; i++) {
+ myString[i] = replybuffer[i + 5]; // chop of the "Alexa string"
+ }
+
+ strcpy(smsText, "Uh lex uh "); //Pronunciation Correction.
+ strcat(smsText, myString);
+ pcSerial.printf("DEBUG::%s\r\n", smsText);
+ myTTS.speakf("S%s\r", smsText); // Send text message to the text to speech module.
+
+
+ // ----------------------------------------------------------------//
+
+ // Send SMS back!
+ replySMS(replybuffer);
+
+ // ----------------------------------------------------------------//
+
+ // delete an SMS after response sent back
+ flushSerial();
+ pcSerial.printf("\r\nDeleting SMS #1\r\n");
+ if (fona.deleteSMS(1)) // delete SMS #1
+ pcSerial.printf("OK!\r\n");
+ else
+ pcSerial.printf("Couldn't delete\r\n");
+
+ // } // end if
+ } // end inner fona.readable() while
+
+ ////---- End FONA loop ----////
+
+ } // end outer loop
+} // end main
+
+
+//
+void replySMS(char* inMsg)
+{
+ // send an SMS back!
+ char message[255];
+
+ strcpy(message, "");
+
+ flushSerial();
+
+ pcSerial.printf("Replying to %s\r\n", smsPhoneNo);
+
+
+ if(strstr(inMsg, "how old are you")) { // if reply buffer contains that string
+ strcpy(message, "I'm 2 in human years, 14 in dog years, and 25 in cat years. I think AI years are marked in nanoseconds, so that makes me, like, a scrillion!");
+ }
+ else if(strstr(inMsg, "what is the world population")) {
+ strcpy(message, "The population of the world is about 7 Billion 400 Million.");
+ }
+ else if(strstr(inMsg, "integral of x squared")) {
+ strcpy(message, "The integral of x squared is one third x cubed plus a constant.");
+ }
+ else if(strstr(inMsg, "discrete co sine transform")) {
+ strcpy(message, "The discrete cosine transform expresses a finite sequence of data points in terms of a sum of cosine function oscillating at different frequencies.");
+ }
+ else {
+ strcpy(message, "Sorry, command not recognized.");
+ }
+
+ pcSerial.printf("%s\r\n", message);
+ if (!fona.sendSMS(smsPhoneNo, message))
+ pcSerial.printf("Failed\r\n");
+ else
+ pcSerial.printf("Sent!\r\n");
+
+}
+
+// Reads and processes GET and POST web data
+void ReadWebData()
+{
+ wait_ms(200);
+ esp.attach(NULL,Serial::RxIrq);
+ DataRX=0;
+ memset(webdata, '\0', sizeof(webdata));
+ strcpy(webdata, rx_buffer);
+ memset(rx_buffer, '\0', sizeof(rx_buffer));
+ rx_in = 0;
+ rx_out = 0;
+ // check web data for form information
+ if( strstr(webdata, "check=age") != NULL ) { ///////// JONATHAN ::: 'led1v' -> 'age'
+ strcpy(smsText, "Uh lex uh, how old are you?");
+ led1=!led1;
+ myTTS.speakf("S%s\r", smsText); // Send text message to the text to speech module.
+ }
+ if( strstr(webdata, "check=population") != NULL ) {
+ strcpy(smsText, "Uh lex uh, what is the world population?");
+ led2=!led2;
+ myTTS.speakf("S%s\r", smsText);
+ }
+ if( strstr(webdata, "check=integral") != NULL ) {
+ strcpy(smsText, "Uh lex uh, what is the integral of x squared?");
+ led3=!led3;
+ myTTS.speakf("S%s\r", smsText);
+ }
+ if( strstr(webdata, "check=dct") != NULL ) {
+ strcpy(smsText, "Uh lex uh, what is the discrete co sine transform?");
+ led4=!led4;
+ myTTS.speakf("S%s\r", smsText);
+ }
+ if( strstr(webdata, "POST") != NULL ) { // set update flag if POST request
+ update=1;
+ }
+ if( strstr(webdata, "GET") != NULL && strstr(webdata, "favicon") == NULL ) { // set update flag for GET request but do not want to update for favicon requests
+ update=1;
+ }
+}
+// Starts webserver
+void startserver()
+{
+ gettime();
+ gettemp();
+ getbattery();
+ pcSerial.printf("++++++++++ Resetting ESP ++++++++++\r\n");
+ strcpy(cmdbuff,"node.restart()\r\n");
+ SendCMD();
+ wait(2);
+ getreply();
+
+ pcSerial.printf("\n++++++++++ Starting Server ++++++++++\r\n> ");
+
+ // initial values
+ sprintf(cmdbuff, "espCount,time,analog1,analog2=0,\"%s\",\"%s\",\"%s\"\r\n",timebuf,Temp,Vcc);
+ SendCMD();
+ getreply();
+ wait(0.5);
+
+ //create server
+ sprintf(cmdbuff, "srv=net.createServer(net.TCP,%d)\r\n",SERVtimeout);
+ SendCMD();
+ getreply();
+ wait(0.5);
+ strcpy(cmdbuff,"srv:listen(80,function(conn)\r\n");
+ SendCMD();
+ getreply();
+ wait(0.3);
+ strcpy(cmdbuff,"conn:on(\"receive\",function(conn,payload) \r\n");
+ SendCMD();
+ getreply();
+ wait(0.3);
+
+ //print data to mbed
+ strcpy(cmdbuff,"print(payload)\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+
+ //web page data
+ strcpy(cmdbuff,"conn:send('<!DOCTYPE html><html><body><h1>Alexa Server</h1>')\r\n");
+ SendCMD();
+ getreply();
+ wait(0.4);
+ strcpy(cmdbuff,"conn:send('Hit count: '..espCount..'')\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff,"conn:send('<br>Last hit (based on mbed RTC time): '..time..'<br><hr>')\r\n");
+ SendCMD();
+ getreply();
+ wait(0.4);
+ strcpy(cmdbuff,"conn:send('<form method=\"POST\"')\r\n");
+ SendCMD();
+ getreply();
+ wait(0.3);
+ strcpy(cmdbuff, "conn:send('<p><input type=\"checkbox\" name=\"check\" value=\"x\"> Data Sent')\r\n");
+ SendCMD();
+ getreply();
+ wait(0.3);
+
+ // end web page data
+ strcpy(cmdbuff, "conn:on(\"sent\",function(conn) conn:close() end)\r\n"); // close current connection
+ SendCMD();
+ getreply();
+ wait(0.3);
+ strcpy(cmdbuff, "end)\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff, "end)\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+
+ strcpy(cmdbuff, "tmr.alarm(0, 1000, 1, function()\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff, "if wifi.sta.getip() == nil then\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff, "print(\"Connecting to AP...\\n\")\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff, "else\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff, "ip, nm, gw=wifi.sta.getip()\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff,"print(\"IP Address: \",ip)\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff,"tmr.stop(0)\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff,"end\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+ strcpy(cmdbuff,"end)\r\n");
+ SendCMD();
+ getreply();
+ wait(0.2);
+
+ pcSerial.printf("\n\n++++++++++ Ready ++++++++++\r\n\n");
+}
+
+////------- Begin ESP Helper Functions Region ------////
+// ESP Command data send
+void SendCMD()
+{
+ int i;
+ char temp_char;
+ bool empty;
+ i = 0;
+// Start Critical Section - don't interrupt while changing global buffer variables
+ NVIC_DisableIRQ(UART1_IRQn);
+ empty = (tx_in == tx_out);
+ while ((i==0) || (cmdbuff[i-1] != '\n')) {
+// Wait if buffer full
+ if (((tx_in + 1) % buffer_size) == tx_out) {
+// End Critical Section - need to let interrupt routine empty buffer by sending
+ NVIC_EnableIRQ(UART1_IRQn);
+ while (((tx_in + 1) % buffer_size) == tx_out) {
+ }
+// Start Critical Section - don't interrupt while changing global buffer variables
+ NVIC_DisableIRQ(UART1_IRQn);
+ }
+ tx_buffer[tx_in] = cmdbuff[i];
+ i++;
+ tx_in = (tx_in + 1) % buffer_size;
+ }
+ if (esp.writeable() && (empty)) {
+ temp_char = tx_buffer[tx_out];
+ tx_out = (tx_out + 1) % buffer_size;
+// Send first character to start tx interrupts, if stopped
+ esp.putc(temp_char);
+ }
+// End Critical Section
+ NVIC_EnableIRQ(UART1_IRQn);
+ return;
+}
+
+// Get Command and ESP status replies
+void getreply()
+{
+ read_line();
+ sscanf(rx_line,replybuff);
+}
+
+// Read a line from the large rx buffer from rx interrupt routine
+void read_line() {
+ int i;
+ i = 0;
+// Start Critical Section - don't interrupt while changing global buffer variables
+ NVIC_DisableIRQ(UART1_IRQn);
+// Loop reading rx buffer characters until end of line character
+ while ((i==0) || (rx_line[i-1] != '\r')) {
+// Wait if buffer empty
+ if (rx_in == rx_out) {
+// End Critical Section - need to allow rx interrupt to get new characters for buffer
+ NVIC_EnableIRQ(UART1_IRQn);
+ while (rx_in == rx_out) {
+ }
+// Start Critical Section - don't interrupt while changing global buffer variables
+ NVIC_DisableIRQ(UART1_IRQn);
+ }
+ rx_line[i] = rx_buffer[rx_out];
+ i++;
+ rx_out = (rx_out + 1) % buffer_size;
+ }
+// End Critical Section
+ NVIC_EnableIRQ(UART1_IRQn);
+ rx_line[i-1] = 0;
+ return;
+}
+
+
+// Interupt Routine to read in data from serial port
+void Rx_interrupt() {
+ DataRX=1;
+ //led3=1;
+// Loop just in case more than one character is in UART's receive FIFO buffer
+// Stop if buffer full
+ while ((esp.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
+ rx_buffer[rx_in] = esp.getc();
+// Uncomment to Echo to USB serial to watch data flow
+ pcSerial.putc(rx_buffer[rx_in]);
+ rx_in = (rx_in + 1) % buffer_size;
+ }
+ //led3=0;
+ return;
+}
+
+
+// Interupt Routine to write out data to serial port
+void Tx_interrupt() {
+ //led2=1;
+// Loop to fill more than one character in UART's transmit FIFO buffer
+// Stop if buffer empty
+ while ((esp.writeable()) && (tx_in != tx_out)) {
+ esp.putc(tx_buffer[tx_out]);
+ tx_out = (tx_out + 1) % buffer_size;
+ }
+ //led2=0;
+ return;
+}
+
+void gettime()
+{
+ time_t seconds = time(NULL);
+ strftime(timebuf,50,"%H:%M:%S %a %d %b %y", localtime(&seconds));
+}
+
+void setRTC()
+{
+ t.tm_sec = (0); // 0-59
+ t.tm_min = (minute); // 0-59
+ t.tm_hour = (hour); // 0-23
+ t.tm_mday = (dayofmonth); // 1-31
+ t.tm_mon = (month-1); // 0-11 "0" = Jan, -1 added for Mbed RCT clock format
+ t.tm_year = ((year)+100); // year since 1900, current DCF year + 100 + 1900 = correct year
+ set_time(mktime(&t)); // set RTC clock
+}
+// Analog in example
+void getbattery()
+{
+ AdcIn=Ain1.read();
+ Ht = (AdcIn*3.3); // set the numeric to the exact MCU analog reference voltage for greater accuracy
+ sprintf(Vcc,"%2.3f",Ht);
+}
+// Temperature example
+void gettemp()
+{
+
+ AdcIn=Ain2.read();
+ Ht = (AdcIn*3.3); // set the numeric to the exact MCU analog reference voltage for greater accuracy
+ sprintf(Temp,"%2.3f",Ht);
+}
+
+////------ End ESP Helper Functions Region ------////
+
+////------ Begin FONA Helper Functions Region ------////
+
+void flushSerial() {
+ while (pcSerial.readable())
+ pcSerial.getc();
+}
+
+char readBlocking() {
+ while (!pcSerial.readable());
+ return pcSerial.getc();
+}
+
+uint16_t readnumber() {
+ uint16_t x = 0;
+ char c;
+ while (! isdigit(c = readBlocking())) {
+ //pcSerial.putc(c);
+ }
+ pcSerial.putc(c);
+ x = c - '0';
+ while (isdigit(c = readBlocking())) {
+ pcSerial.putc(c);
+ x *= 10;
+ x += c - '0';
+ }
+ return x;
+}
+
+uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
+ uint16_t buffidx = 0;
+ bool timeoutvalid = true;
+ if (timeout == 0) timeoutvalid = false;
+
+ while (true) {
+ if (buffidx > maxbuff) {
+ //pcSerial.printf("SPACE\r\n");
+ break;
+ }
+
+ while(pcSerial.readable()) {
+ char c = pcSerial.getc();
+
+ //pcSerial.printf("%02x#%c\r\n", c, c);
+
+ if (c == '\r')
+ continue;
+
+
+ if (c == '\r') { /////////////////////////////////////////// CHANGED BY JONATHAN: (0XA -> '\r')
+ 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++;
+
+ count++; ///////////////////////// ADED BY JONATHAN
+ }
+
+ if (timeoutvalid && timeout == 0) {
+ //pcSerial.printf("TIMEOUT\r\n");
+ break;
+ }
+ wait_ms(1);
+ }
+ buff[buffidx] = 0; // null term
+ return buffidx;
+}
+
+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;
+}
+
+////------ End FONA Helper Functions Region ------////
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue May 02 03:13:27 2017 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/mbed_official/code/mbed/builds/794e51388b66 \ No newline at end of file