uses pushing box to publish to google spreadsheets with a state machine instead of a while loop
Fork of GSM_PUSHING_BOX_STATE_MACHINE by
Diff: GSMLibrary.cpp
- Revision:
- 24:7d2ff444d6d8
- Parent:
- 23:5227fb014aad
- Child:
- 25:9de265c5bb28
--- a/GSMLibrary.cpp Tue Mar 24 18:39:13 2015 +0000 +++ b/GSMLibrary.cpp Sat Apr 11 23:21:46 2015 +0000 @@ -1,30 +1,40 @@ +//Libraries #include "GSMLibrary.h" #include "gsmqueue.h" #include <string.h> -#define TIME_CONST .3 -#define SECONDS_TIMEOUT 40 +//Global defines #define TIMEOUTLIMIT SECONDS_TIMEOUT/TIME_CONST //$change check with main code this will set up condition fior timeout. +#define BEGIN_PHOTODIODE_DATA "CLS:" +#define BEGIN_GPS_DATA "GPS:" -//definition for AT comands +//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 +#define NUM_SIZE 25 + +//definition for AT comands to send #define AT_OK "AT" #define AT_CSQ "AT+CSQ" #define AT_CREG "AT+CREG?" +#define AT_CNMI "AT+CNMI=2,0,0,0,0" #define AT_CMGF "AT+CMGF=1" -#define RECEIVER_PHONE_NUMBER "\"+12083608384\"" -#define AT_CMGS "AT+CMGS=" RECEIVER_PHONE_NUMBER -#define MESSAGE_BODY "stress test\32\32" +#define AT_READ_MSG "AT+CMGL=\"REC UNREAD\"" //make sure device is in txt mode. +#define AT_DEL_R_MSGS "AT+QMGDA=\"DEL READ\"" - -//Definition for AT repsonses +//Definition for AT responses //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 ">" //Message is written aftersymbol -#define AT_SENDSMS_RESPONSE ">" // +CMGS: <id> this will include the message id. CMGS ERROR for error and -#define AT_SUCCESS_RESPONSE "+CMGS:" +#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. CMS ERROR for error. +#define AT_DEL_R_MSGS_RESPONSE "OK" //External variables extern Serial pc; @@ -33,184 +43,238 @@ //Internal variables gsm_states gsm_current_state = GSM_INITIALIZE; -char send = 0; int timeout_count = 0; -char gsm_msg[MAX_MSG_SIZE + 1]; //1 extra for Ctrl+Z +char state_chars[] = "iosntmRPWD"; //init, ok, signalstrength, network, turn off notifications, messagemode, read, phone, writesms, del + +//Extras for transmitter +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 +char undeleted_msgs = true; //At the beginning assume we have undeleted messages +char gsm_msg[MAX_SMS_LENGTH + 250]; //String storing SMS message to send to GSMMaximum (add 250 length to give leeway) +char num[NUM_SIZE]; //Temporary string storage to convert numbers void gsm_tick() { - if (getGSMIdleBit() || gsm_timeOut() || (send && gsm_current_state == GSM_INITIALIZE)) //question with send... + + if (queueHasResponse() || gsm_timeOut() || gsm_current_state == GSM_INITIALIZE) { - resetGSMIdleBit(); //reset GSM idle bit + gsm_printState(); //&debug + printQueue(); //&debug gsm_nextStateLogic(); //Next state gsm_mealyOutputs(); //Mealy outputs - flushQueue(); //Flush the queue } } - - - + +void gsm_printState() +{ + pc.printf("S:%c;", state_chars[gsm_current_state]); +} + //Advance timeout counter; if timeout, return true bool gsm_timeOut() { if(++timeout_count >= TIMEOUTLIMIT){ - timeout_count=0; - gsm_current_state = GSM_INITIALIZE; + timeout_count = 0; + gsm_reset(); return true; } else return false; } -//Have the GSM send a message -void gsm_send_sms(char msg[]) +//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) { - send = 1; - strcpy(gsm_msg,msg); //If we need to optimize later we can do that, but this is more robust - strcat(gsm_msg,"\x1A"); + if (!gsm_ready()) //Don't send if gsm not ready + return; + + //Concatenate photodiode data + gsm_msg[0] = NULL; + strcat(gsm_msg, BEGIN_PHOTODIODE_DATA); + snprintf(num, NUM_SIZE, ",%d:%d:%d,", hh, mm, ss); + strcat(gsm_msg, num); + snprintf(num, NUM_SIZE, "%f,", L); + strcat(gsm_msg, num); + snprintf(num, NUM_SIZE, "%f,", Lref); + strcat(gsm_msg, num); + snprintf(num, NUM_SIZE, "%f,", S); + strcat(gsm_msg, num); + snprintf(num, NUM_SIZE, "%f;\n", Sref); + strcat(gsm_msg, num); + + //Concatenate gps data + strcat(gsm_msg, BEGIN_GPS_DATA); + if (ns != NULL) //If there is a gps fix, ns will be set + { + snprintf(num, NUM_SIZE, ",%.4f%c,%.4f%c;", lat, ns, lon, we); + strcat(gsm_msg, num); + } + else strcat(gsm_msg, ",NONE;"); + + 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 + +//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 bool gsm_ready() { - return (send == 0) ? true : false; + return ((!send) && send_enable) ? true : false; } - -//Reset the gsm + +//Reset the gsm. Currently this only resets the state and whether we are currently sending a message +//It does not reset send_enable or undeleted_msgs void gsm_reset() { + //If we are in the middle of sending a text message, exit this loop + if (gsm_current_state == GSM_AT_CMGS) + sendCommand(SMS_ESCAPE_CHAR); + gsm_current_state = GSM_INITIALIZE; + undeleted_msgs = true; + send = false; } - + //Next state logic ----------------------------------------------------- void gsm_nextStateLogic() { - printQueue(); //$debug - + //printQueue(); //$debug + switch(gsm_current_state) { case GSM_INITIALIZE: - pc.printf("gsm_initialize state\r\n");//&debug timeout_count = 0; - if (send) - gsm_current_state = GSM_AT_OK; //unconditional (check it) + gsm_current_state = GSM_AT_OK; //unconditional (check it) break; case GSM_AT_OK: - pc.printf("inside AT_OK state\r\n");//&debug - if (findInQueue(AT_OK_RESPONSE)) + if (findInQueue(AT_OK_RESPONSE, true)) gsm_current_state = GSM_AT_CSQ; break; case GSM_AT_CSQ: - pc.printf("inside AT_CSQ state \r\n");//&debug - if(findInQueue(AT_CSQ_RESPONSE)) + if(findInQueue(AT_CSQ_RESPONSE, true)) gsm_current_state = GSM_AT_CREG; break; case GSM_AT_CREG: - pc.printf("gsm_creg state\r\n");//&debug - if(findInQueue(AT_CREG_RESPONSE)) + if(findInQueue(AT_CREG_RESPONSE, true)) { - pc.printf("creg parse Int1: %d\r\n",parseInt());//&debug - int q = parseInt(); - pc.printf("creg parse Int2: %d\r\n",q);//&debug - if(q == 1) - gsm_current_state = GSM_AT_CMGF; + parseInt(); + if(parseInt() == 1) + gsm_current_state = GSM_AT_CNMI; } break; + case GSM_AT_CNMI: + if(findInQueue(AT_CNMI_RESPONSE, true)) + gsm_current_state = GSM_AT_CMGF; + break; case GSM_AT_CMGF: - pc.printf("gsm_cmgf state\r\n");//&debug - if(findInQueue(AT_CMGF_RESPONSE)) - gsm_current_state = GSM_AT_CMGS; + if(findInQueue(AT_CMGF_RESPONSE, true)) + gsm_current_state = GSM_READ_MSG; + break; + case GSM_READ_MSG: + if(send_enable) //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. + } + else + { + if(findInQueue(START_SMS_TRANSMISSION, true)) + { + undeleted_msgs = true; + send_enable = true; + if (send) //Only continue sending if we found start sequence AND user requested that we send sms + gsm_current_state = GSM_AT_CMGS; //Start sending SMS (change state accordingly) + } + } break; case GSM_AT_CMGS: - pc.printf("gsm_cmgs state\r\n");//&debug - if(findInQueue(AT_CMGS_RESPONSE)) + if(findInQueue(AT_CMGS_RESPONSE, true)) gsm_current_state = GSM_AT_SENDSMS; break; case GSM_AT_SENDSMS: - pc.printf("gsm_send_sms state\r\n");//&debug - if(findInQueue(AT_SENDSMS_RESPONSE)) //> + if(findInQueue(AT_SENDSMS_RESPONSE, true)) { - //Check if the "successfully sent" has also already been received (most likely - //this won't be the case, but if it has been >500 ms there's a possibility - //we've received both the messages during the same call to our state machine.) - if(findInQueue(AT_SUCCESS_RESPONSE)) + pc.printf("(Wid%i)",parseInt());//&debug + timeout_count = 0; //Reset timeout count + send = 0; //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 no unread messages + else { - pc.printf("Message SENT! msgID: %iY\r\n",parseInt());//&debug - send = 0; - gsm_current_state = GSM_INITIALIZE; //Skip success state (we've received both) + gsm_current_state = GSM_READ_MSG; //Otherwise read text messages again + pc.printf("(Dnone)");//&debug } - else - gsm_current_state = GSM_SUCCESS; //Go to success state } else - gsm_current_state = GSM_AT_CMGS; //Try resending the message (until timeout) + { + pc.printf("(Werr)"); //&debug + gsm_current_state = GSM_AT_CMGS; //If failed, try resending the message (i.e. continue until timeout) + } break; - case GSM_SUCCESS: - pc.printf("gsm_success state\r\n");//&debug - if(findInQueue(AT_SUCCESS_RESPONSE)) + case GSM_DEL_R_MSGS: + if (findInQueue(AT_DEL_R_MSGS_RESPONSE, true)) { - pc.printf("Message SENT! msgID: %iY\r\n",parseInt());//&debug + undeleted_msgs = false; + pc.printf("(Dsucc)"); //&debug } - send = 0; - gsm_current_state = GSM_INITIALIZE; //We will restart regardless of whether it worked + else + pc.printf("(Derr)"); //&debug + gsm_current_state = GSM_READ_MSG; break; default: - pc.printf("This is a state error"); + pc.printf("This is a state error\r\n"); } } - + //Mealy output logic ------------------------------------------------------ void gsm_mealyOutputs() { switch(gsm_current_state) { case GSM_INITIALIZE: - pc.printf("No Mealy initialize state output\r\n");//&debug break; case GSM_AT_OK: - pc.printf("sending AT_OK\r\n");//&debug - gsm.puts(AT_OK); - gsm.puts("\r\n"); + sendCommand(AT_OK); break; case GSM_AT_CSQ: - pc.printf("sending AT_CSQ\r\n");//&debug - gsm.puts(AT_CSQ); - gsm.puts("\r\n"); + sendCommand(AT_CSQ); break; case GSM_AT_CREG: - pc.printf("sending AT_CREG\r\n");//&debug - gsm.puts(AT_CREG); - gsm.puts("\r\n"); + sendCommand(AT_CREG); break; - case GSM_AT_CMGF: - pc.printf("sending AT_CMGF\r\n");//&debug - gsm.puts(AT_CMGF); - gsm.puts("\r\n"); - 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: - pc.printf("sending AT_CMGS\r\n");//&debug - gsm.puts(AT_CMGS); - gsm.puts("\r\n"); + sendCommand(AT_CMGS); break; case GSM_AT_SENDSMS: - pc.printf("sending message\r\n");//&debug - gsm.puts(gsm_msg); //substitute char included - gsm.puts("\r\n"); + sendCommand(gsm_msg); //end char included break; - case GSM_SUCCESS: - pc.printf("No Mealy success state output\r\n");//&debug + case GSM_DEL_R_MSGS: + sendCommand(AT_DEL_R_MSGS); break; default: - pc.printf("This is a state error"); + pc.printf("This is a state error\r\n"); } } - - //Initialize the GSM void gsm_initialize(){ SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //enabling dmamux clock SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; // enebaling dma clock - pc.printf("initializing tregisters...!\r\n"); + pc.printf("initializing DMA...\r\n"); // control register mux, enabling uart3 receive DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(8); @@ -253,11 +317,11 @@ //activate p fifo UART_PFIFO_REG(UART3) |= UART_PFIFO_RXFE_MASK; //RXFE and buffer size of 1 word queueInit(); - pc.printf("Initialization done...\n\r"); + pc.printf("done...\n\r"); } - - - + + + //initialization debuging purposes void print_registers() {