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
Revision 34:5345174bfb30, committed 2015-12-19
- Comitter:
- DeWayneDennis
- Date:
- Sat Dec 19 21:47:23 2015 +0000
- Parent:
- 33:2ae9a4eb6433
- Commit message:
- Final Code
Changed in this revision
--- a/GSMLibrary.cpp Fri Nov 06 20:49:23 2015 +0000 +++ b/GSMLibrary.cpp Sat Dec 19 21:47:23 2015 +0000 @@ -1,17 +1,14 @@ //Libraries #include "GSMLibrary.h" -//#include "gsmqueue.h" #include <string.h> #include "GPRSInterface.h" -#include "gsmqueue.h" + //Global defines -#define TIMEOUTLIMIT (SECONDS_TIMEOUT / 1) //Defines how many "ticks" of the GSM will constitute "timeout" of our "watchdog timer" #define NUM_SIZE 500 //External variables extern Serial pc; //To print output to computer -//extern Serial gsm; //To communicate with GSM -extern uint8_t buffer[BUFFER_LENGTH]; //DMA queue + GPRSInterface eth(D1,D0, 19200, "ndo","",""); /************************************************** ** GPRS ** @@ -28,7 +25,6 @@ //Internal variables gsm_states gsm_current_state = GSM_INITIALIZE; -int timeout_count = 0; 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; @@ -60,17 +56,6 @@ 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_reset(); - return true; - } - else - return false; -} //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, int hh, int mm, int ss, float lat, char ns, float lon, char we) @@ -121,7 +106,7 @@ //header information //begin get request - snprintf(num, NUM_SIZE, "%s", "\r\nGET /index.html?"); + snprintf(num, NUM_SIZE, "%s", "GET /index.html?"); strcat(gsm_header, num); //add query parameters @@ -136,7 +121,6 @@ snprintf(num, NUM_SIZE, "%s","Connection: Keep-Alive\r\n\r\n"); strcat(gsm_header, num); - send = true; } @@ -152,7 +136,6 @@ void gsm_reset() { gsm_current_state = GSM_INITIALIZE; - send = false; } //Next state logic ----------------------------------------------------- @@ -165,8 +148,7 @@ switch(gsm_current_state) { case GSM_INITIALIZE: - timeout_count = 0; //No AT commands have been sent: this will send the first one - printf(">>>INIT\r\n"); + //printf(">>>INIT\r\n"); if (eth.init() != NULL) { printf(">>> Could not initialise. Halting!\n"); exit(0); @@ -174,13 +156,13 @@ gsm_current_state = GSM_CHECK_SIM; break; case GSM_CHECK_SIM: - printf(">>>CHECK SIM\r\n"); + //printf(">>>CHECK SIM\r\n"); if (eth.preInit() == true){ gsm_current_state = GSM_JOIN; } break; case GSM_JOIN: - printf(">>>JOIN\r\n"); + //printf(">>>JOIN\r\n"); int join = eth.connect(); if (join == false || join < 0){ //stay here @@ -193,7 +175,7 @@ } break; case GSM_SERVER_IP: - printf(">>>SERVER IP\r\n"); + // printf(">>>SERVER IP\r\n"); serverIP = "23.251.149.114"; if(serverIP != NULL) { @@ -204,7 +186,7 @@ } break; case GSM_CONNECT: - printf("\r\n>>>CONNECT TO: %s\r\n", serverIP); + //printf("\r\n>>>CONNECT TO: %s\r\n", serverIP); if(sock.connect(serverIP,80)){ printf("Connected\r\n"); gsm_current_state = GSM_SEND; @@ -214,19 +196,19 @@ } break; case GSM_SEND: - printf(">>>READY TO SEND\r\n"); - waitTicks = 6; - if(sock.send_all(gsm_header, contentLength)){ - printf("Data succesfully sent to server\r\n"); - gsm_current_state = GSM_WAIT; + //printf(">>>READY TO SEND\r\n"); + if(send){ + if(sock.send_all(gsm_header, contentLength)){ + printf("Data succesfully sent to server\r\n"); + gsm_current_state = GSM_SEND; + send = false; + } + else{ + printf("Reconnecting to Server...\r\n"); + gsm_current_state = GSM_CONNECT; + } } - else{ - printf("Reconnecting to Server...\r\n"); - gsm_current_state = GSM_CONNECT; - } - - - //gsm_current_state = GSM_SEND; + break; case GSM_WAIT: //WAIT BETWEEN CONSECUTIVE SENDS @@ -241,58 +223,6 @@ pc.printf("This is a state error\r\n"); } } - -//Initialize the GSM -void gsm_initialize(){ - wait(2.3); //Wait for the GSM to turn on properly before doing this initialization - SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //enabling dmamux clock - SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; // enebaling dma clock - //pc.printf("initializing DMA...\r\n"); - // control register mux, enabling uart3 receive - DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(8); - - // Enable request signal for channel 0 - DMA_ERQ = DMA_ERQ_ERQ0_MASK; - - // select round-robin arbitration priority - DMA_CR |= DMA_CR_ERCA_MASK; - - //enable error interrupt for DMA0 (commented out because we won't use interrupts for our implementation) - //DMA_EEI = DMA_EEI_EEI0_MASK; - - //Address for buffer - DMA_TCD0_SADDR = (uint32_t) &UART_D_REG(UART3_BASE_PTR); - DMA_TCD0_DADDR = (uint32_t) buffer; - // Set an offset for source and destination address - DMA_TCD0_SOFF = 0x00; - DMA_TCD0_DOFF = 0x01; // Destination address offset of 1 byte per transaction - - // Set source and destination data transfer size - DMA_TCD0_ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0); - - // Number of bytes to be transfered in each service request of the channel - DMA_TCD0_NBYTES_MLNO = 0x01; - // Current major iteration count - //DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(BUFFER_LENGTH); - //DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(BUFFER_LENGTH); - // Adjustment value used to restore the source and destiny address to the initial value - // After reading 'len' number of times, the DMA goes back to the beginning by subtracting len*2 from the address (going back to the original address) - DMA_TCD0_SLAST = 0; // Source address adjustment - //DMA_TCD0_DLASTSGA = -BUFFER_LENGTH; // Destination address adjustment - // Setup control and status register - DMA_TCD0_CSR = 0; - - // enable interrupt call at end of major loop - DMA_TCD0_CSR |= DMA_CSR_INTMAJOR_MASK; - - //Activate dma transfer rx interrupt - UART_C2_REG(UART3) |= UART_C2_RIE_MASK; - UART_C5_REG(UART3) |= UART_C5_RDMAS_MASK | UART_C5_ILDMAS_MASK | UART_C5_LBKDDMAS_MASK; - //activate p fifo register - UART_PFIFO_REG(UART3) |= UART_PFIFO_RXFE_MASK; //RXFE and buffer size of 1 word - //queueInit(); - pc.printf("done...\n\r"); -} //For debugging: print registers related to DMA and UART setup void print_registers()
--- a/GSMLibrary.h Fri Nov 06 20:49:23 2015 +0000 +++ b/GSMLibrary.h Sat Dec 19 21:47:23 2015 +0000 @@ -3,8 +3,6 @@ #include "mbed.h" -//#define TIME_CONST 1 //Specify length of each GSM tick (currently called twice every 2 seconds, so an average of every 1 second) -#define SECONDS_TIMEOUT 30 #define SMS_END_CHAR "\x1A" //Character that must be appended to end of text message before it will be sent #define SMS_ESCAPE_CHAR "\x1A" //Character that can be appended to end of text message to abort sending it @@ -19,13 +17,9 @@ //GSM state machine void gsm_tick(); -bool gsm_timeOut(); void gsm_printState(); void gsm_nextStateLogic(); -//Initialize DMA data transfer, and UART3. -void gsm_initialize(); - //returns 1 for ready to send again, 0 for busy. bool gsm_ready();
--- a/gsmqueue.cpp Fri Nov 06 20:49:23 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -#include "gsmqueue.h" -#include "GSMLibrary.h" -#include <string.h> - -/* gsmqueue.cpp - * Contains functions to read from the DMA buffer in a queue fashion - */ - -#define LAST_UNPRINTABLE_CHAR 31 - -//External variables -extern Serial pc; //Print data to serial connection with computer -//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 -//by the DMA and we only read its value. Our queue's purpose is to read data communicated to us -//by the GSM without having to consume processor cycles. Unfortunately when we write data to the Serial -//port, the DMA will still write it to the buffer. For this reason, the sendCommand() function counts -//the number of characters we send over UART so we can ignore those characters in the queue. -char buffer[BUFFER_LENGTH]; //Stores the characters in the queue -char* queueHead; //Queue head - marks where to read from next -char* queueHeadExp; //Expected location of queueHead after gsm.puts() finishes executing - - -//Public functions ------------------------------------------------------------------------------ -//Initialize variables -void queueInit() -{ - //The buffer is initialized in GSMLibrary.cpp - queueHead = QUEUETAIL; - queueHeadExp = queueHead; -} - -//Send gsm a command (don't forget to flush queue and increment past QUEUETAIL -//by the number of characters send) -void sendCommand(char* sPtr) -{ - flushQueue(); //This "removes" any characters remaining in the queue - int size = strlen(sPtr); - if (size > 0 && size <= MAX_SMS_LENGTH) //Don't send if too long or negative size - { - //Send the command - //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. - // size + 2 is for "\n\r" that gets transmitted after we send the command - if (sPtr[size - 1] == SMS_END_CHAR[0]) - { - queueHeadExp = incrementIndex(queueHead, size - 1); - // Don't add "\n" because already included in string (this is when we are sending a message) - } - else - { - queueHeadExp = incrementIndex(queueHead, size + 2); - //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 - // adds a "\r" at the end of your string, independent of whether it was already present - // in the string you sent to it. (Except if you only send "\n", in which case it does - // not follow it with a "\r".) Thus we need to simply add "\n" because the "\r" is - // already added by the gsm.puts command. - } - //pc.printf("C:%s\r\n", sPtr); //&debug - to know we have sent this message - } - else //Else: error message - { - //pc.printf("Error: AT command exceeded maximum length"); - gsm_reset(); - } -} - -//Return true if GSM has sent complete response already -//If GSM is idle and queue is not empty, return true -//If the last command was successfully sent, advance queueHead to queueHeadExp -bool queueHasResponse() -{ - if (getGSMIdleBit()) - { //If tail has advanced past the end of our last sent command, queue has new data - int dataReceived = queueSize(QUEUETAIL) - queueSize(queueHeadExp); - if (dataReceived >= 0) - queueHead = queueHeadExp; //Upon equality, last command was successfully sent - return (dataReceived > 0); //Data received only if characters present beyond "equality" point - } - else - return false; //Still busy; wait until transmission ended -} - -//Find an occurrence of the given string in the buffer. -//If advanceQueueHead is true, advance queueHead just until a matching string is found. -//The given string terminates in NULL (\0) -bool findInQueue(char* str, bool advanceQueueHead) -{ - //Check that string to find is not empty - if (*str == NULL) return false; - - char* head = queueHead; - while (head != QUEUETAIL) - { - //Does the character match the begin char? - if (*head == *str){ - //Check the remaining characters - char* sPos = str; - char* qPos = 0; - for (qPos = head; qPos != QUEUETAIL; qPos = incrementIndex(qPos)){ - //Compare the next char - if (*qPos == *sPos) - { - ++sPos; //Increment index (prefix incrementation). - if (*sPos == NULL) //If finished, update head, return true. - { - head = incrementIndex(qPos); - if (advanceQueueHead) - queueHead = head; - return true; - } - } - else //Not equal, so exit for loop and try again at a different location - break; - } - } - //Increment queue index for next iteration - head = incrementIndex(head); - } - //We never succeeded, so return false - if (advanceQueueHead) - queueHead = head; - return false; -} - -//Parse through characters until first integer is found -//Advance qHead until you reach the next non-numeric character -//Does not read negative integers; returns -1 if unsuccessful -int parseInt() -{ - //Check if queue is empty first - if (queueHead == QUEUETAIL) return -1; - - //Advance to first numeric character - while (!isNumeric(queueHead)) - { - queueHead = incrementIndex(queueHead); - if (queueHead == QUEUETAIL) return -1; - } - - //Continue until first non-numeric character - int val = 0; - while (queueHead != QUEUETAIL && isNumeric(queueHead)) - { - val *= 10; - val += (int)(*queueHead - '0'); - queueHead = incrementIndex(queueHead); - } - return val; -} - -//$debug - print queue elements -void printQueue() -{ - char* qPos = queueHead; - pc.printf("Q:"); - while (qPos != QUEUETAIL) - { - //Print the current character - if (*qPos <= LAST_UNPRINTABLE_CHAR) - { - if (*qPos == '\n') - pc.printf("\\n"); - else if (*qPos == '\r') - pc.printf("\\r"); - else - pc.printf("\0%x", *qPos); - } - else - pc.printf("%C",*qPos); - - - //Increment index - qPos = incrementIndex(qPos); - } -} - - -//Internal functions --------------------------------------------------------------------------------- - -//Get the GSM DMA idle bit (if 1, indicates we already received a response) -bool getGSMIdleBit() -{ - return (UART_S1_IDLE_MASK & UART_S1_REG(UART3)) >> UART_S1_IDLE_SHIFT; -} - -//Returns true if the character is numeric -bool isNumeric(char* qPos) -{ - return ('0' <= *qPos && *qPos <= '9'); -} - -//Increment queue position by 1 (Note: this function is only used by gsmqueue.cpp) -char* incrementIndex(char* pointerToIncrement) -{ - if((pointerToIncrement + 1) < (buffer + BUFFER_LENGTH)) - return (pointerToIncrement + 1); - else - return buffer; -} - -//Increment queue position by n (Note: this function is only used by gsmqueue.cpp) -char* incrementIndex(char* pointerToIncrement, int n) -{ - int initialIndex = pointerToIncrement - buffer; - int incrementedIndex = (initialIndex + n) % BUFFER_LENGTH; - return incrementedIndex + buffer; -} - -//Get size of the queue from reference point of tail parameter -int queueSize(char* tail) -{ - int headDiff = queueHead - buffer; - int tailDiff = tail - buffer; - return (tailDiff + BUFFER_LENGTH - headDiff) % BUFFER_LENGTH; -} - -//Clear queue (Note: this function is only used by gsmqueue.cpp) -void flushQueue() -{ - queueHead = QUEUETAIL; -} -
--- a/gsmqueue.h Fri Nov 06 20:49:23 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -#ifndef GSMQUEUE_H -#define GSMQUEUE_H - -/* gsmqueue.h - * Contains functions to read from the DMA buffer in a queue fashion - */ - -//Memory block of char size alocated for DMA -#define BUFFER_LENGTH 2000 -#define MAX_SMS_LENGTH 700 //Absolute SMS length max = 900 (let's do 700 to be safe) -#define QUEUETAIL (char*)DMA_TCD0_DADDR - - -//Public functions ------------------------------------------------------------------------------ -//Initialize variables -void queueInit(); - -//Send gsm a command -void sendCommand(char* sPtr); - -//Return 1 if queue has data and the GSM is done transmitting its response -bool queueHasResponse(); - -//Find an occurrence of the given string in the buffer. -//If advanceQueueHead is true, advance queueHead just until a matching string is found. -bool findInQueue(char* str, bool advanceQueueHead); - -//Parse through characters until first integer is found -int parseInt(); - -//Print queue elements -void printQueue(); //for debugging - - -//Internal functions ------------------------------------------------------------------------------ -//Get the GSM DMA idle bit (if 1, indicates we aren't in the process of receiving a response) -bool getGSMIdleBit(); - -//Returns true if the character is numeric -bool isNumeric(char* qPos); - -//Increment queue position by 1 (Note: this function is only used by gsmqueue.cpp) -char* incrementIndex(char* pointerToIncrement); - -//Increment queue position by n (Note: this function is only used by gsmqueue.cpp) -char* incrementIndex(char* pointerToIncrement, int n); - -//Get size of the queue from reference point of tail parameter -int queueSize(char* tail); - -//Clear queue (Note: this function is only used by gsmqueue.cpp) -void flushQueue(); - -#endif \ No newline at end of file