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

Fork of GSM_Library by DCS_TEAM

Files at this revision

API Documentation at this revision

Comitter:
DeWayneDennis
Date:
Wed Oct 21 19:44:15 2015 +0000
Parent:
31:a1e9fd23eb6a
Commit message:
added GSM Library;

Changed in this revision

GSMLibrary.cpp Show annotated file Show diff for this revision Revisions of this file
GSMLibrary.h Show annotated file Show diff for this revision Revisions of this file
gsmqueue.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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");
--- a/GSMLibrary.h	Tue Apr 28 03:03:19 2015 +0000
+++ b/GSMLibrary.h	Wed Oct 21 19:44:15 2015 +0000
@@ -9,15 +9,12 @@
 #define SMS_ESCAPE_CHAR "\x1A"  //Character that can be appended to end of text message to abort sending it
 
 enum gsm_states{GSM_INITIALIZE, 
-                    GSM_AT_OK,      //Make sure communication is established with GSM
-                    GSM_AT_CSQ,     //Check signal strength
-                    GSM_AT_CREG,    //Check if phone is connected to network
-                    GSM_AT_CNMI,    //Turn off incoming SMS notifications
-                    GSM_AT_CMGF,    //Change to text message mode
-                    GSM_READ_MSG,   //Check for new messages.
-                    GSM_AT_CMGS,    //Input phone number and indicate beginning of SMS message body
-                    GSM_AT_SENDSMS, //Write message, finish with SMS_END_CHAR
-                    GSM_DEL_R_MSGS  //Delete unread messages (if present)   
+                    GSM_CHECK_SIM,  //Send initial AT Command and Check SIM Card Status
+                    GSM_JOIN,       //Join the wireless network
+                    GSM_SERVER_IP,  //Get the IP Address for the server
+                    GSM_CONNECT,    //Connect to the server via tcp on specified port
+                    GSM_SEND,       //Send data to server via tcp 
+                    GSM_WAIT        //State to wait between successive data sent to the server 
                 };
 
 //GSM state machine
@@ -25,7 +22,6 @@
 bool gsm_timeOut();
 void gsm_printState();
 void gsm_nextStateLogic();
-void gsm_mealyOutputs();
 
 //Initialize DMA data transfer, and UART3.
 void gsm_initialize();
@@ -34,7 +30,7 @@
 bool gsm_ready();
 
 //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);
 
 //Brings state machine back to initialize state (notice this is a bit different than the initialize function)
 //This will set flags to their initial values and prepare gsm to start anew.
--- a/gsmqueue.cpp	Tue Apr 28 03:03:19 2015 +0000
+++ b/gsmqueue.cpp	Wed Oct 21 19:44:15 2015 +0000
@@ -10,7 +10,7 @@
 
 //External variables
 extern Serial pc;   //Print data to serial connection with computer
-extern Serial gsm;  //UART connection with GSM
+//Serial gsm(D3,D2);  //UART connection with GSM
 
 //Internal variables for a queue (wrap-around implementation)
 //Note that the DMA (direct memory access) stores data in this queue. Therefore, QUEUETAIL is incremented
@@ -41,7 +41,7 @@
     if (size > 0 && size <= MAX_SMS_LENGTH)   //Don't send if too long or negative size
     {
         //Send the command
-        gsm.puts(sPtr);
+        //gsm.puts(sPtr);
         //The increment part below: Effectively "removes" characters we just sent from the buffer
         // by advancing queueHead by size - 1, or size + 2 
         // size - 1 is because SMS_END_CHAR does not show up on the DMA.
@@ -54,7 +54,7 @@
         else
         {
             queueHeadExp = incrementIndex(queueHead, size + 2);
-            gsm.puts("\n"); //make there be a \r\n in what we send (this is perfect.)
+            //gsm.puts("\n"); //make there be a \r\n in what we send (this is perfect.)
             //Why not "\r\n"? Previously we had thought the extra \r was added due to \r\n coming
             // through the command line: scanf only removed the \n as whitespace. However, upon
             // further investigation we realized this behavior occurs because the gsm.puts function