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
GSMLibrary.cpp
- Committer:
- DeWayneDennis
- Date:
- 2015-11-06
- Revision:
- 33:2ae9a4eb6433
- Parent:
- 32:424896b5adbe
- Child:
- 34:5345174bfb30
File content as of revision 33:2ae9a4eb6433:
//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 ** **************************************************/ /** * 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 */ //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; //Extras for transmitter char gsm_msg[250]; //String storing SMS message that will be sent (add 250 length to give leeway) char gsm_header[500]; //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 int contentLength; int waitTicks = 0; //"Tick" of the GSM (i.e. this is a state machine) void gsm_tick() { //Don't do anything, unless i) we received a response from the GSM, ii) the watchdog timer timed out, or iii) or we are initializing the GSM //if (queueHasResponse() || gsm_timeOut() || gsm_current_state == GSM_INITIALIZE) { //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 } } //Prints the current state. To save time printing, simply prints 1 character to indicate the current state. 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_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) { //Concatenate data gsm_msg[0] = NULL; gsm_header[0] = NULL; contentLength = 0; //entry.453067166=$phone$ snprintf(num, NUM_SIZE, "entry.453067166=%s", eth.getPhoneNumber()); //snprintf(num, NUM_SIZE, "phone=%s", "3852368101"); contentLength += strlen(num); strcat(gsm_msg, num); //&entry.724220743=$data$ snprintf(num, NUM_SIZE, "&entry.724220743=%f", L); //snprintf(num, NUM_SIZE, "&data=%f", L); contentLength += strlen(num); strcat(gsm_msg, num); //&entry.1590868051=$dataRef$ //snprintf(num, NUM_SIZE, "&dataRef=%f", Lref); snprintf(num, NUM_SIZE, "&entry.1590868051=%f", Lref); contentLength += strlen(num); strcat(gsm_msg, num); //&entry.44817253=$dataRatio$ snprintf(num, NUM_SIZE, "&entry.44817253=%f", (Lref ? (L/Lref) : 0)); //snprintf(num, NUM_SIZE, "&dataRatio=%f", (Lref ? (L/Lref) : 0)); contentLength += strlen(num); strcat(gsm_msg, num); //&entry.142778814=$time$ snprintf(num, NUM_SIZE, "&entry.142778814=%02d:%02d:%02d", hh, mm, ss); //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 { //&entry.894229969=$latitude$&entry.1266703316=$longitude$ snprintf(num, NUM_SIZE, "&entry.894229969=%.4f&entry.1266703316=%.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 { //&entry.894229969=$latitude$&entry.1266703316=$longitude$ snprintf(num, NUM_SIZE,"&entry.894229969=0&entry.1266703316=0"); strcat(gsm_msg, num); //Otherwise just send 0's for latitude and longitude contentLength += strlen(num); } //header information //begin get request snprintf(num, NUM_SIZE, "%s", "\r\nGET /index.html?"); strcat(gsm_header, num); //add query parameters strcat(gsm_header, gsm_msg); //add necessary headers snprintf(num, NUM_SIZE, "%s"," HTTP/1.1\r\n"); strcat(gsm_header, num); snprintf(num, NUM_SIZE, "%s","Host: 23.251.149.114\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, "%s","Connection: Keep-Alive\r\n\r\n"); strcat(gsm_header, num); send = true; } //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; } //Reset the gsm. Currently this only resets the state, whether we are currently sending a message, and whether there are messages to delete. //It does not reset send_enable void gsm_reset() { gsm_current_state = GSM_INITIALIZE; send = false; } //Next state logic ----------------------------------------------------- //Note how each state (except init) checks the response received to make sure //GSM has properly executed the command. If the response is correct, it changes //the state so that the next command will be sent in the gsm_mealyOutputs function //below. void gsm_nextStateLogic() { 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"); if (eth.init() != NULL) { printf(">>> Could not initialise. Halting!\n"); exit(0); } gsm_current_state = GSM_CHECK_SIM; break; case GSM_CHECK_SIM: printf(">>>CHECK SIM\r\n"); if (eth.preInit() == true){ gsm_current_state = GSM_JOIN; } break; case GSM_JOIN: printf(">>>JOIN\r\n"); int join = eth.connect(); if (join == false || join < 0){ //stay here gsm_current_state = GSM_JOIN; } 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_SERVER_IP: printf(">>>SERVER IP\r\n"); serverIP = "23.251.149.114"; if(serverIP != NULL) { gsm_current_state = GSM_CONNECT; } else{ gsm_current_state = GSM_JOIN; } break; case GSM_CONNECT: printf("\r\n>>>CONNECT TO: %s\r\n", serverIP); if(sock.connect(serverIP,80)){ printf("Connected\r\n"); gsm_current_state = GSM_SEND; } else{ gsm_current_state = GSM_JOIN; } 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; } 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 printf("Wait Tick...\r\n"); //eth.close(0); //eth.disconnect(); waitTicks--; if(waitTicks == 0) gsm_current_state = GSM_SEND; break; default: 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() { pc.printf("\n\rDMA REGISTERS\n\r"); pc.printf("DMA_MUX: 0x%08x\r\n",DMAMUX_CHCFG0); pc.printf("SADDR0: 0x%08x\r\n",DMA_TCD0_SADDR); pc.printf("DADDR0: 0x%08x\r\n",DMA_TCD0_DADDR); pc.printf("CITER0: 0x%08x\r\n",DMA_TCD0_CITER_ELINKNO); pc.printf("BITER0: 0x%08x\r\n",DMA_TCD0_BITER_ELINKNO); pc.printf("DMA_CR: %08x\r\n", DMA_CR); pc.printf("DMA_ES: %08x\r\n", DMA_ES); pc.printf("DMA_ERQ: %08x\r\n", DMA_ERQ); pc.printf("DMA_EEI: %08x\r\n", DMA_EEI); pc.printf("DMA_CEEI: %02x\r\n", DMA_CEEI); pc.printf("DMA_SEEI: %02x\r\n", DMA_SEEI); pc.printf("DMA_CERQ: %02x\r\n", DMA_CERQ); pc.printf("DMA_SERQ: %02x\r\n", DMA_SERQ); pc.printf("DMA_CDNE: %02x\r\n", DMA_CDNE); pc.printf("DMA_SSRT: %02x\r\n", DMA_SSRT); pc.printf("DMA_CERR: %02x\r\n", DMA_CERR); pc.printf("DMA_CINT: %02x\r\n", DMA_CINT); pc.printf("DMA_INT: %08x\r\n", DMA_INT); pc.printf("DMA_ERR: %08x\r\n", DMA_ERR); pc.printf("DMA_HRS: %08x\r\n", DMA_HRS); pc.printf("DMA_TCD0_DOFF: %08x\r\n",DMA_TCD0_DOFF); pc.printf("\n\rUART REGISTERS\n\r"); pc.printf("UART_BDH_REG: %08x\r\n",UART_BDH_REG(UART3)); pc.printf("UART_C1_REG: %08x\r\n",UART_C1_REG(UART3)); pc.printf("UART_C2_REG: %08x\r\n",UART_C2_REG(UART3)); pc.printf("UART_S1_REG: %08x\r\n",UART_S1_REG(UART3)); pc.printf("UART_s2_REG: %08x\r\n",UART_S2_REG(UART3)); pc.printf("UART_C3_REG: %08x\r\n",UART_C3_REG(UART3)); pc.printf("UART_D_REG: %08x\r\n",UART_D_REG(UART3)); pc.printf("UART_MA1_REG: %08x\r\n",UART_MA1_REG(UART3)); pc.printf("UART_MA2_REG: %08x\r\n",UART_MA2_REG(UART3)); pc.printf("UART_C4_REG: %08x\r\n",UART_C4_REG(UART3)); pc.printf("UART_C5_REG: %08x\r\n",UART_C5_REG(UART3)); pc.printf("UART_ED_REG: %08x\r\n",UART_ED_REG(UART3)); pc.printf("UART_MODEM_REG: %08x\r\n",UART_MODEM_REG(UART3)); pc.printf("UART_IR_REG: %08x\r\n",UART_IR_REG(UART3)); pc.printf("UART_PFIFO_REG: %08x\r\n",UART_PFIFO_REG(UART3)); pc.printf("UART_CFIFO_REG: %08x\r\n",UART_CFIFO_REG(UART3)); pc.printf("UART_SFIFO_REG: %08x\r\n",UART_SFIFO_REG(UART3)); pc.printf("UART_TWFIFO_REG: %08x\r\n",UART_TWFIFO_REG(UART3)); pc.printf("UART_TCFIFO_REG: %08x\r\n",UART_TCFIFO_REG(UART3)); pc.printf("UART_RWFIFO_REG: %08x\r\n",UART_RWFIFO_REG(UART3)); pc.printf("UART_RCFIFO_REG: %08x\r\n",UART_RCFIFO_REG(UART3)); }