SIM800L implementation

Dependencies:   mbed BufferedSerial

GSMProgramAutomation.cpp

Committer:
toanatron
Date:
2020-05-09
Revision:
1:16fdeb024e42
Parent:
0:c9d0008613d6

File content as of revision 1:16fdeb024e42:

#include "mbed.h"
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <sstream>
#include <vector>
#include "BufferedSerial.h"

#define CTRL_Z      26      //Attach at the end of this message string
Timer mytime;

DigitalOut led1(P4_4);
DigitalOut rescueLED(P4_4);                     // Offboard GREEN LED

long GSMBAUD = 9600;

/* 
 * Function: read_message
 * ------------------------------------------------------------------------------------------------------
 * Decipher any message inside the SIM800L buffer (UART2) to see what is sent back after sending commands
 * Typical response are "OK" "ERROR" ">" and "$RECEIVED"
 * "$RECEIVED" is an automated response sent from TWILIO server
 * Each SIM800L command depends on a special response before continuing to the next command
 * @param response - the string that is back from the SIM800L
 * @param responseCheck - a flag used to determine if the message sent back was read
 * @papram SIM800L - the buffered serial used between uC and SIM800L P(3_0) and P(3_1) 
 * @return (void) - none
 * ------------------------------------------------------------------------------------------------------
 */
void read_message(char *response, int *responseCheck, BufferedSerial *SIM800L, int blockSymbol, int request){
    char buff[20];
    int loop = 1;
    int checkMsg = 1;
    uint32_t timeSaved = mytime.read_ms();
    int flagc = 0;
    memset(buff, 0, sizeof(buff));
    while(loop){
        if(mytime.read_ms() - timeSaved > 13000){
            strcpy(buff,"ERROR");  
            checkMsg = 0;
            break;
        }    
        if(SIM800L->readable() > 0){
            char tmp = SIM800L->getc();
            if(request && tmp != '$')continue;
            if(tmp == 'O' || tmp == '$' || tmp == 'E' || tmp == '>'){
                if(blockSymbol && tmp =='>')continue;
                flagc = 1;
                if(tmp == '>'){
                    strncat(buff, &tmp, sizeof(tmp));
                    break;
                }
                while(tmp != '\n'){
                    if(flagc && tmp != ' ' && tmp != '\r'){
                        strncat(buff, &tmp, sizeof(tmp));
                        flagc = 0;
                    }
                    if(SIM800L->readable() > 0){
                        tmp = SIM800L->getc();
                        flagc = 1;
                    }
                }
                loop = 0;
            }
        }
    }
    /*
     * Update flag used to check if message was good
     * Copy response into a buffer to be determined what message was sent
     * clear memory used
     */
     if(!checkMsg){
         *responseCheck = 0;
     }else{
         *responseCheck = 1;
     }
     strcpy(response, buff);
     memset(buff, 0, sizeof(buff));
}


/* 
 * Function: sendEmergencyLocation
 * ------------------------------------------------------------------------------------------------------
 * Send the location of the user to the TWILIO server to ask for assistance
 * Send a sequency of command to the GSM module (SIM800L)
 * A received message is also checked to make sure TWILIO had received the message, if not resend the message
 * A green LED is also turned on when the message was deemed to be received by TWILIO
 * @param loc - the current location of the user
 * @param bpm - the heart rate of the user in beats per min
 * @ return (void) - none
 */
void sendEmergencyLocation(char *loc, int bpm){
    BufferedSerial *SIM800L = new BufferedSerial(P3_1, P3_0);
    SIM800L->baud(9600); 
    char buff[100];
    int checkResponse = 0;      // Check if the response of the GSM module was valid
    int blockSymbol = 0;        // Block the symbol ">" from being read when processing
    int checkProcess = 1;       // condition used to determine if the TWILIO had received the SOS message and if all the commands worked properly
    int request = 0;
    /*
     * Each command sent has an expected message sent back in response
     * These messages are checked before continuing
     * After all commands are sent and $RECEIVED is sent back from TWILIO clear serial buffer and turn on GREEN LED
     */
    while(checkProcess){
        int request = 0;
        SIM800L->printf("AT\r\n");               // handshake with GSM module
        read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
        if(!checkResponse)continue;
        if(!strcmp(buff,"OK")){                 // expected message
            wait(0.1f);
        }else continue;

        SIM800L->printf("AT+CMGF=1\r\n");             // Set the text mode of the GSM
        read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
        if(!checkResponse)continue;
        if(!strcmp("OK", buff)){
            wait(0.1f);
        }else continue;
        
        blockSymbol = 0;
        SIM800L->printf("AT+CNMI=1,2,0,0,0\r\n");             // Set the receiving mode of the GSM module
        read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
        if(!checkResponse)continue;
        if(!strcmp("OK", buff)){                // expected message
            wait(0.1f);
        }else continue;
    
        SIM800L->printf("AT+CMGS=\"1##########\"\r\n");             // communicate to SIM800L to respond OK
        read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
        if(!checkResponse)continue;
        if(strcmp(">", buff) == 0){             // expected message
            wait(0.1f);
        }else continue;

        blockSymbol = 1;
        SIM800L->printf("%s BPM:%d %c\r\n",loc,bpm,CTRL_Z);             // communicate to SIM800L to respond OK
        read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
        if(!checkResponse)continue;
        if(!strcmp("OK", buff)){                // expected message
            wait(0.1f);
        }else continue;
    
        blockSymbol = 0;
        request = 1;
        read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
        if(!checkResponse)continue;
        if(strcmp("$RECEIVED", buff) == 0){     // expected message
            wait(0.1f);
            rescueLED = 0;
            checkProcess = 0;
        }else continue;
        SIM800L->printf("AT+CMGF=0\r\n");     // set to the default mode on the SIM800L
        wait(0.1f);
    }
    delete SIM800L;
}

int main(){
char loc[50] = "https://www.google.com/maps/place/38 47\'26.16\"N+77 27'44.91\"W";
int bpm = 100;
// Send a dummy location/bpm to a phone number
sendEmergencyLocation(loc,bpm);
}