uses pushing box to publish to google spreadsheets with a state machine instead of a while loop

Dependents:   DCS_FINAL_CODE

Fork of GSM_PUSHING_BOX_STATE_MACHINE by DCS_TEAM

Revision:
32:424896b5adbe
Parent:
30:421aae087064
Child:
33:2ae9a4eb6433
--- a/GSMLibrary.cpp	Tue Apr 28 03:03:19 2015 +0000
+++ b/GSMLibrary.cpp	Wed Oct 21 19:44:15 2015 +0000
@@ -1,57 +1,44 @@
 //Libraries
 #include "GSMLibrary.h"
-#include "gsmqueue.h"
+//#include "gsmqueue.h"
 #include <string.h>
-
+#include "GPRSInterface.h"
+#include "gsmqueue.h"
 //Global defines
 #define TIMEOUTLIMIT SECONDS_TIMEOUT/TIME_CONST  //Defines how many "ticks" of the GSM will constitute "timeout" of our "watchdog timer"
-
-//Extra defines for transmitter
-#define START_SMS_TRANSMISSION "START"
-#define STOP_SMS_TRANSMISSION "STOP"
-#define GPS_SMS_TRANSMISSION "GPS"
-#define RECEIVER_PHONE_NUMBER "\"+13853357314\""
-#define AT_CMGS "AT+CMGS=" RECEIVER_PHONE_NUMBER    //Begin sending SMS with this send command and the phone number
-#define NUM_SIZE 25 //Size of a temporary variable to help with concatenation of strings
-#define BEGIN_SENSOR_DATA "$"   //$ and % are parsed by using regex by the GUI for the receiver and indicate the start and end of data received
-#define END_SENSOR_DATA  "%"
-
-//Define AT commands to send
-#define AT_OK "AT"                  //Ask GSM if everything is 'ok'
-#define AT_CSQ "AT+CSQ"             //Check signal strength
-#define AT_CREG "AT+CREG?"          //Check if GSM is registered on cellular network
-#define AT_CNMI "AT+CNMI=2,0,0,0,0" //Turn off the notification that is normally received when text messages are received
-#define AT_CMGF "AT+CMGF=1"         //Turn on "text message mode" so we can characters (rather than PDU mode in which you send bytes)
-#define AT_READ_MSG "AT+CMGL=\"REC UNREAD\"" //Read received messages that have not yet been read
-#define AT_DEL_R_MSGS "AT+QMGDA=\"DEL READ\""   //Delete read messages
-
-//Define expected responses for AT commands
-//Please notice that after ":" the gsm will usually send aditional information
-#define AT_OK_RESPONSE "OK" //Response after sending "AT" message
-#define AT_CSQ_RESPONSE "+CSQ:" //+CSQ: <arg1>,<arg2> where <arg1> is signal strength arg1 = 0-30 where a number below 10 means low signal strength and 99 is not knwn or detectable signal and arg2 is bit error rate form 0-7, 99 will represent error 
-#define AT_CREG_RESPONSE "+CREG:"//+CREG: <arg1>,<arg2> where <arg1> = 0-2(see AT command descriptions), <arg2> =  0-5, 0 not registered to nework and not looking for one. 1 is conected to network, 2 is not conected but searching
-#define AT_CNMI_RESPONSE "OK"
-#define AT_CMGF_RESPONSE "OK"
-#define AT_CMGS_RESPONSE ">"  //Received after you give the GSM the phone number. (We mistakenly thought it was received a second time after SMS was sent... this is not true!)
-#define AT_SENDSMS_RESPONSE "+CMGS:" // +CMGS: <id> this will include the message id, or CMS ERROR for error.
-#define AT_DEL_R_MSGS_RESPONSE "OK"
+#define NUM_SIZE 250
 
 //External variables
 extern Serial pc;   //To print output to computer
-extern Serial gsm;  //To communicate with GSM
+//extern Serial gsm;  //To communicate with GSM
 extern uint8_t buffer[BUFFER_LENGTH];   //DMA queue
+/**************************************************
+ **          GPRS                                 **
+ **************************************************/
+/**
+ * D1 - TX pin (RX on the WiFi side)
+ * D0 - RX pin (TX on the WiFi side)
+ * 19200 - Baud rate
+ * "apn" - APN name
+ * "username" - APN username
+ * "password" - APN passowrd
+ */
+GPRSInterface eth(D1,D0, 19200, "ndo","","");
 
 //Internal variables
 gsm_states gsm_current_state = GSM_INITIALIZE;
 int timeout_count = 0;
-char state_chars[] = "iosntmRPWD";  //For debugging - 1 char to represent each state: init, ok, signalstrength, network, turn off notifications, messagemode, read, phone, writesms, del
+char state_chars[] = "iSJICS";  //For debugging - 1 char to represent each state: init, ok, signalstrength, network, turn off notifications, messagemode, read, phone, writesms, del
+char* serverIP;
+TCPSocketConnection sock;
 
 //Extras for transmitter
+char gsm_msg[250]; //String storing SMS message that will be sent (add 250 length to give leeway)
+char gsm_header[250]; //for the http header information
+char num[NUM_SIZE];   //Temporary string storage to help with concatenation of strings
 char send = false;  //if true => we will send something (only if send_enable is true)
 char send_enable = false;   //Sending start and stop commands to GSM via SMS changes this variable. If true, we will send SMS messages of our data received
-char undeleted_msgs = true; //At the beginning assume we have undeleted messages
-char gsm_msg[MAX_SMS_LENGTH + 250]; //String storing SMS message that will be sent (add 250 length to give leeway)
-char num[NUM_SIZE];   //Temporary string storage to help with concatenation of strings
+
 
 //"Tick" of the GSM (i.e. this is a state machine)
 void gsm_tick()
@@ -62,7 +49,7 @@
         //gsm_printState();   //&debug
         //printQueue();   //&debug
         gsm_nextStateLogic();   //Next state
-        gsm_mealyOutputs(); //Mealy outputs. This state machine is a little different because Mealy outputs come after the next state logic
+        //gsm_mealyOutputs(); //Mealy outputs. This state machine is a little different because Mealy outputs come after the next state logic
     }
 }
 
@@ -85,38 +72,60 @@
 }
 
 //Have the GSM send data - L = long, S = short, hh/mm/ss for time, "lat ns" for latitute, "lon we" for longitude
-void gsm_send_data(float L, float Lref, float S, float Sref, int hh, int mm, int ss, float lat, char ns, float lon, char we)
+void gsm_send_data(float L, float Lref, int hh, int mm, int ss, float lat, char ns, float lon, char we)
 {
-    if (!gsm_ready())   //Don't send if gsm not ready
-        return;
-    
     //Concatenate data
     gsm_msg[0] = NULL;
-    strcat(gsm_msg, BEGIN_SENSOR_DATA);
-    snprintf(num, NUM_SIZE, "%f,", L);
+    gsm_header[0] = NULL;
+    int contentLength = 0;
+    snprintf(num, NUM_SIZE, "&phone=%s", "3852368101");
+    contentLength += strlen(num);
     strcat(gsm_msg, num);
-    snprintf(num, NUM_SIZE, "%f,", Lref);
+    snprintf(num, NUM_SIZE, "&data=%f", L);
+    contentLength += strlen(num);
     strcat(gsm_msg, num);
-    snprintf(num, NUM_SIZE, "%f,", S);
+    snprintf(num, NUM_SIZE, "&dataRef=%f", Lref);
+    contentLength += strlen(num);
     strcat(gsm_msg, num);
-    snprintf(num, NUM_SIZE, "%f,", Sref);
+    snprintf(num, NUM_SIZE, "&dataRatio=%f", (Lref ? (L/Lref) : 0));
+    contentLength += strlen(num);
     strcat(gsm_msg, num);
-    snprintf(num, NUM_SIZE, "%d:%d:%d,", hh, mm, ss);   //If there is no data from GPS, the time will just be "0:0:0" (that is okay)
+    snprintf(num, NUM_SIZE, "&time=%02d:%02d:%02d", hh, mm, ss);   //If there is no data from GPS, the time will just be "00:00:00" (that is okay)
+    contentLength += strlen(num);
     strcat(gsm_msg, num);
     if (ns != NULL) //If there is a gps fix (i.e. the gps has data on our location), ns will be set
     { 
-        snprintf(num, NUM_SIZE, "%.4f,%.4f", (ns == 'N') ? lat : -lat, (we == 'E') ? lon : -lon);   //Use + or - rather than N/S, E/W
+        snprintf(num, NUM_SIZE, "&latitude=%.4f&longitude=%.4f", (ns == 'N') ? lat : -lat, (we == 'E') ? lon : -lon);   //Use + or - rather than N/S, E/W
+        contentLength += strlen(num);
         strcat(gsm_msg, num);
     }
-        else strcat(gsm_msg, "0,0");    //Otherwise just send 0's for latitude and longitude
-    strcat(gsm_msg, END_SENSOR_DATA);
+    else {
+        snprintf(num, NUM_SIZE,"&latitude=0&longitude=0");
+        strcat(gsm_msg, num);    //Otherwise just send 0's for latitude and longitude
+        contentLength += strlen(num);
+    }
+
     
+    //header information    
+    snprintf(num, NUM_SIZE, "%s", "POST /pushingbox?devid=v941C443DE0C7B14");
+    strcat(gsm_header, num);
+    strcat(gsm_header, gsm_msg);
+    snprintf(num, NUM_SIZE, "%s"," HTTP/1.1\r\n");
+    strcat(gsm_header, num);
+    snprintf(num, NUM_SIZE, "%s","Host: api.pushingbox.com\r\n");
+    strcat(gsm_header, num);
+    snprintf(num, NUM_SIZE, "%s","Connection: close\r\n");
+    strcat(gsm_header, num);
+    snprintf(num, NUM_SIZE, "%s","User-Agent: FRDM-KD64\r\n");
+    strcat(gsm_header, num);
+    //must have two blank lines after so the server knows that this is the end of headers
+    snprintf(num, NUM_SIZE, "Content-Length: %d\r\n\r\n", contentLength);
+    strcat(gsm_header, num);
     send = true;    //Mark that we are currently sending a message
-    strcat(gsm_msg, SMS_END_CHAR);  //Add SMS end char
 }
  
-//Return true if gsm is ready to send sms
-//This only occurs if send = false (not currently sending a message) AND gsm received start sequence
+//Return true if gsm is ready to send via tcp
+//This only occurs if gsm received start sequence and responded appropriately
 bool gsm_ready()
 {
     return ((!send) && send_enable) ? true : false;
@@ -126,12 +135,7 @@
 //It does not reset send_enable
 void gsm_reset()
 {
-    //If we are in the middle of sending a text message, we need to "escape" out of this mode by sending the escape character
-    if (gsm_current_state == GSM_AT_CMGS)
-        sendCommand(SMS_ESCAPE_CHAR);
-    
     gsm_current_state = GSM_INITIALIZE;
-    undeleted_msgs = true;
     send = false;
 }
  
@@ -146,127 +150,71 @@
     {
         case GSM_INITIALIZE:
             timeout_count = 0;  //No AT commands have been sent: this will send the first one
-            gsm_current_state = GSM_AT_OK;
-            break;
-        case GSM_AT_OK:
-            if (findInQueue(AT_OK_RESPONSE, true))
-                gsm_current_state = GSM_AT_CSQ;
-            break;
-        case GSM_AT_CSQ:
-            if(findInQueue(AT_CSQ_RESPONSE, true))
-                gsm_current_state = GSM_AT_CREG;
-            break;
-        case GSM_AT_CREG:
-            if(findInQueue(AT_CREG_RESPONSE, true))
-            {
-                parseInt(); //After the CREG response we receive two integers. The second should be '1' (see AT_CREG_RESPONSE #define)
-                if(parseInt() == 1)
-                    gsm_current_state = GSM_AT_CNMI;
-            } 
+            printf(">>>INIT\r\n");
+            if (eth.init() != NULL) {
+                printf(">>> Could not initialise. Halting!\n");
+                exit(0);
+            }
+            gsm_current_state = GSM_CHECK_SIM;
             break;
-        case GSM_AT_CNMI:
-            if(findInQueue(AT_CNMI_RESPONSE, true))
-                gsm_current_state = GSM_AT_CMGF;
-            break;  
-        case GSM_AT_CMGF:
-            if(findInQueue(AT_CMGF_RESPONSE, true))
-                gsm_current_state = GSM_READ_MSG;
+        case GSM_CHECK_SIM:
+            printf(">>>CHECK SIM\r\n");
+            if (eth.preInit() == true){
+                gsm_current_state = GSM_JOIN;
+            }
             break;
-        case GSM_READ_MSG:
-            if(send_enable) //If we are currently sending SMS, check if we need to stop transmission of SMS
-            {
-                if(findInQueue(STOP_SMS_TRANSMISSION, true))  //Always stop sending if stop sequence received by SMS
-                {
-                    undeleted_msgs = true;
-                    send_enable = false;    //Set send_enable to indicate we will stop sending SMS
-                }
-                else if (send) //Only continue sending if we didn't find stop sequence AND user requested that we send sms
-                    gsm_current_state = GSM_AT_CMGS;    //Continue sending SMS (change state accordingly)
-                //Implicit: otherwise we will continue checking text messages in this state.
+        case GSM_JOIN:
+            printf(">>>JOIN\r\n");
+            int join = eth.connect();
+            if (join == false || join < 0){
+                //stay here
             }
-            else    //If we are not yet sending SMS, check if we need to start transmission of SMS
-            {
-                if(findInQueue(START_SMS_TRANSMISSION, true))
-                {
-                    undeleted_msgs = true;
-                    send_enable = true; //Now we are in send SMS mode: whenever 'send' variable is set to true we will send an SMS
-                    if (send) //Only begin sending a new SMS if user requested that we send SMS (i.e. there is data to send)
-                        gsm_current_state = GSM_AT_CMGS;    //Start sending SMS (change state accordingly)
-                }
+            else{
+                //possibly send this sms to the main box at the lab
+                //eth.send_SMS("17066311506", eth.getIPAddress());
+                gsm_current_state = GSM_SERVER_IP;
             }
             break;
-        case GSM_AT_CMGS:
-            if(findInQueue(AT_CMGS_RESPONSE, true))
-                gsm_current_state = GSM_AT_SENDSMS;
-            break;
-        case GSM_AT_SENDSMS:
-            if(findInQueue(AT_SENDSMS_RESPONSE, true))
+        case GSM_SERVER_IP:
+            printf(">>>SERVER IP\r\n");
+            serverIP = "api.pushingbox.com";
+            if(serverIP != NULL)
             {
-                //pc.printf("(Wid%i)",parseInt());//&debug
-                timeout_count = 0;  //Reset timeout count
-                send = false;   //Indicate we are done sending the text message
-                if (undeleted_msgs) //Check if we need to delete read messages
-                    gsm_current_state = GSM_DEL_R_MSGS; //Only delete messages if there are unread messages
-                else
-                {
-                    gsm_current_state = GSM_READ_MSG;   //Otherwise skip the delete messages state; go read text messages again
-                    //pc.printf("(Dnone)");//&debug 
-                }
+                gsm_current_state = GSM_CONNECT;
+            }
+            else{
+                gsm_current_state = GSM_JOIN;
+            } 
+            break;
+        case GSM_CONNECT:
+            printf("\r\n>>>CONNECT TO: %s\r\n", serverIP);
+            //sock.set_blocking(true,5000);
+            if (sock.connect(serverIP,80) == true){
+                gsm_current_state = GSM_SEND;
+            }
+            else{
+                gsm_current_state = GSM_CONNECT;   
             }
-            else
-            {
-                //pc.printf("(Werr)"); //&debug
-                gsm_current_state = GSM_AT_CMGS;    //If failed, try resending the message (i.e. continue until timeout)
+            break;  
+        case GSM_SEND:
+            printf(">>>READY TO SEND\r\n");
+            if(send){
+            if(sock.send_all(gsm_header, sizeof(gsm_header)-1)){
+                printf("Data succesfully sent to server\r\n");
+                //close the connection so others can send too
+                //wait(2);
+                //eth.disconnect();
+            }
+            else{
+                printf("Reconnecting to Server...\r\n");
+                send = false;
+                gsm_current_state = GSM_CONNECT;
+            }
             }
             break;
-        case GSM_DEL_R_MSGS:
-            if (findInQueue(AT_DEL_R_MSGS_RESPONSE, true))
-            {
-                undeleted_msgs = false;
-                //pc.printf("(Dsucc)");   //&debug
-            }
-            //else
-                //pc.printf("(Derr)");    //&debug
-            gsm_current_state = GSM_READ_MSG;
-            break;
-        default:
-            pc.printf("This is a state error\r\n");
-    }
-}
- 
-//Mealy output logic ------------------------------------------------------
-void gsm_mealyOutputs()
-{
-    switch(gsm_current_state)
-    {
-        case GSM_INITIALIZE:
-            break;
-        case GSM_AT_OK:
-            sendCommand(AT_OK);
-            break;
-        case GSM_AT_CSQ:
-            sendCommand(AT_CSQ);
-            break;
-        case GSM_AT_CREG:
-            sendCommand(AT_CREG);
-            break;
-        case GSM_AT_CNMI:
-            sendCommand(AT_CNMI);
-            break; 
-        case GSM_AT_CMGF:
-            sendCommand(AT_CMGF);
-            break;         
-        case GSM_READ_MSG:
-            sendCommand(AT_READ_MSG);
-            break; 
-        case GSM_AT_CMGS:   
-            sendCommand(AT_CMGS);
-            break;
-        case GSM_AT_SENDSMS:
-            sendCommand(gsm_msg); //end char included
-            break;
-        case GSM_DEL_R_MSGS:
-            sendCommand(AT_DEL_R_MSGS);
+        case GSM_WAIT:
+            //check for text message from server asking for data
+            gsm_current_state = GSM_SEND;
             break;
         default:
             pc.printf("This is a state error\r\n");