SIM800L implementation

Dependencies:   mbed BufferedSerial

Committer:
toanatron
Date:
Sat May 09 20:09:37 2020 +0000
Revision:
1:16fdeb024e42
Parent:
0:c9d0008613d6
update;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kchhouk 0:c9d0008613d6 1 #include "mbed.h"
toanatron 1:16fdeb024e42 2 #include <iostream>
toanatron 1:16fdeb024e42 3 #include <string.h>
toanatron 1:16fdeb024e42 4 #include <stdio.h>
toanatron 1:16fdeb024e42 5 #include <sstream>
toanatron 1:16fdeb024e42 6 #include <vector>
toanatron 1:16fdeb024e42 7 #include "BufferedSerial.h"
kchhouk 0:c9d0008613d6 8
kchhouk 0:c9d0008613d6 9 #define CTRL_Z 26 //Attach at the end of this message string
toanatron 1:16fdeb024e42 10 Timer mytime;
kchhouk 0:c9d0008613d6 11
toanatron 1:16fdeb024e42 12 DigitalOut led1(P4_4);
toanatron 1:16fdeb024e42 13 DigitalOut rescueLED(P4_4); // Offboard GREEN LED
kchhouk 0:c9d0008613d6 14
kchhouk 0:c9d0008613d6 15 long GSMBAUD = 9600;
toanatron 1:16fdeb024e42 16
toanatron 1:16fdeb024e42 17 /*
toanatron 1:16fdeb024e42 18 * Function: read_message
toanatron 1:16fdeb024e42 19 * ------------------------------------------------------------------------------------------------------
toanatron 1:16fdeb024e42 20 * Decipher any message inside the SIM800L buffer (UART2) to see what is sent back after sending commands
toanatron 1:16fdeb024e42 21 * Typical response are "OK" "ERROR" ">" and "$RECEIVED"
toanatron 1:16fdeb024e42 22 * "$RECEIVED" is an automated response sent from TWILIO server
toanatron 1:16fdeb024e42 23 * Each SIM800L command depends on a special response before continuing to the next command
toanatron 1:16fdeb024e42 24 * @param response - the string that is back from the SIM800L
toanatron 1:16fdeb024e42 25 * @param responseCheck - a flag used to determine if the message sent back was read
toanatron 1:16fdeb024e42 26 * @papram SIM800L - the buffered serial used between uC and SIM800L P(3_0) and P(3_1)
toanatron 1:16fdeb024e42 27 * @return (void) - none
toanatron 1:16fdeb024e42 28 * ------------------------------------------------------------------------------------------------------
toanatron 1:16fdeb024e42 29 */
toanatron 1:16fdeb024e42 30 void read_message(char *response, int *responseCheck, BufferedSerial *SIM800L, int blockSymbol, int request){
toanatron 1:16fdeb024e42 31 char buff[20];
toanatron 1:16fdeb024e42 32 int loop = 1;
toanatron 1:16fdeb024e42 33 int checkMsg = 1;
toanatron 1:16fdeb024e42 34 uint32_t timeSaved = mytime.read_ms();
toanatron 1:16fdeb024e42 35 int flagc = 0;
toanatron 1:16fdeb024e42 36 memset(buff, 0, sizeof(buff));
toanatron 1:16fdeb024e42 37 while(loop){
toanatron 1:16fdeb024e42 38 if(mytime.read_ms() - timeSaved > 13000){
toanatron 1:16fdeb024e42 39 strcpy(buff,"ERROR");
toanatron 1:16fdeb024e42 40 checkMsg = 0;
toanatron 1:16fdeb024e42 41 break;
toanatron 1:16fdeb024e42 42 }
toanatron 1:16fdeb024e42 43 if(SIM800L->readable() > 0){
toanatron 1:16fdeb024e42 44 char tmp = SIM800L->getc();
toanatron 1:16fdeb024e42 45 if(request && tmp != '$')continue;
toanatron 1:16fdeb024e42 46 if(tmp == 'O' || tmp == '$' || tmp == 'E' || tmp == '>'){
toanatron 1:16fdeb024e42 47 if(blockSymbol && tmp =='>')continue;
toanatron 1:16fdeb024e42 48 flagc = 1;
toanatron 1:16fdeb024e42 49 if(tmp == '>'){
toanatron 1:16fdeb024e42 50 strncat(buff, &tmp, sizeof(tmp));
toanatron 1:16fdeb024e42 51 break;
toanatron 1:16fdeb024e42 52 }
toanatron 1:16fdeb024e42 53 while(tmp != '\n'){
toanatron 1:16fdeb024e42 54 if(flagc && tmp != ' ' && tmp != '\r'){
toanatron 1:16fdeb024e42 55 strncat(buff, &tmp, sizeof(tmp));
toanatron 1:16fdeb024e42 56 flagc = 0;
toanatron 1:16fdeb024e42 57 }
toanatron 1:16fdeb024e42 58 if(SIM800L->readable() > 0){
toanatron 1:16fdeb024e42 59 tmp = SIM800L->getc();
toanatron 1:16fdeb024e42 60 flagc = 1;
toanatron 1:16fdeb024e42 61 }
toanatron 1:16fdeb024e42 62 }
toanatron 1:16fdeb024e42 63 loop = 0;
toanatron 1:16fdeb024e42 64 }
toanatron 1:16fdeb024e42 65 }
toanatron 1:16fdeb024e42 66 }
toanatron 1:16fdeb024e42 67 /*
toanatron 1:16fdeb024e42 68 * Update flag used to check if message was good
toanatron 1:16fdeb024e42 69 * Copy response into a buffer to be determined what message was sent
toanatron 1:16fdeb024e42 70 * clear memory used
toanatron 1:16fdeb024e42 71 */
toanatron 1:16fdeb024e42 72 if(!checkMsg){
toanatron 1:16fdeb024e42 73 *responseCheck = 0;
toanatron 1:16fdeb024e42 74 }else{
toanatron 1:16fdeb024e42 75 *responseCheck = 1;
toanatron 1:16fdeb024e42 76 }
toanatron 1:16fdeb024e42 77 strcpy(response, buff);
toanatron 1:16fdeb024e42 78 memset(buff, 0, sizeof(buff));
toanatron 1:16fdeb024e42 79 }
toanatron 1:16fdeb024e42 80
toanatron 1:16fdeb024e42 81
toanatron 1:16fdeb024e42 82 /*
toanatron 1:16fdeb024e42 83 * Function: sendEmergencyLocation
toanatron 1:16fdeb024e42 84 * ------------------------------------------------------------------------------------------------------
toanatron 1:16fdeb024e42 85 * Send the location of the user to the TWILIO server to ask for assistance
toanatron 1:16fdeb024e42 86 * Send a sequency of command to the GSM module (SIM800L)
toanatron 1:16fdeb024e42 87 * A received message is also checked to make sure TWILIO had received the message, if not resend the message
toanatron 1:16fdeb024e42 88 * A green LED is also turned on when the message was deemed to be received by TWILIO
toanatron 1:16fdeb024e42 89 * @param loc - the current location of the user
toanatron 1:16fdeb024e42 90 * @param bpm - the heart rate of the user in beats per min
toanatron 1:16fdeb024e42 91 * @ return (void) - none
toanatron 1:16fdeb024e42 92 */
toanatron 1:16fdeb024e42 93 void sendEmergencyLocation(char *loc, int bpm){
toanatron 1:16fdeb024e42 94 BufferedSerial *SIM800L = new BufferedSerial(P3_1, P3_0);
toanatron 1:16fdeb024e42 95 SIM800L->baud(9600);
toanatron 1:16fdeb024e42 96 char buff[100];
toanatron 1:16fdeb024e42 97 int checkResponse = 0; // Check if the response of the GSM module was valid
toanatron 1:16fdeb024e42 98 int blockSymbol = 0; // Block the symbol ">" from being read when processing
toanatron 1:16fdeb024e42 99 int checkProcess = 1; // condition used to determine if the TWILIO had received the SOS message and if all the commands worked properly
toanatron 1:16fdeb024e42 100 int request = 0;
toanatron 1:16fdeb024e42 101 /*
toanatron 1:16fdeb024e42 102 * Each command sent has an expected message sent back in response
toanatron 1:16fdeb024e42 103 * These messages are checked before continuing
toanatron 1:16fdeb024e42 104 * After all commands are sent and $RECEIVED is sent back from TWILIO clear serial buffer and turn on GREEN LED
toanatron 1:16fdeb024e42 105 */
toanatron 1:16fdeb024e42 106 while(checkProcess){
toanatron 1:16fdeb024e42 107 int request = 0;
toanatron 1:16fdeb024e42 108 SIM800L->printf("AT\r\n"); // handshake with GSM module
toanatron 1:16fdeb024e42 109 read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
toanatron 1:16fdeb024e42 110 if(!checkResponse)continue;
toanatron 1:16fdeb024e42 111 if(!strcmp(buff,"OK")){ // expected message
toanatron 1:16fdeb024e42 112 wait(0.1f);
toanatron 1:16fdeb024e42 113 }else continue;
toanatron 1:16fdeb024e42 114
toanatron 1:16fdeb024e42 115 SIM800L->printf("AT+CMGF=1\r\n"); // Set the text mode of the GSM
toanatron 1:16fdeb024e42 116 read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
toanatron 1:16fdeb024e42 117 if(!checkResponse)continue;
toanatron 1:16fdeb024e42 118 if(!strcmp("OK", buff)){
toanatron 1:16fdeb024e42 119 wait(0.1f);
toanatron 1:16fdeb024e42 120 }else continue;
toanatron 1:16fdeb024e42 121
toanatron 1:16fdeb024e42 122 blockSymbol = 0;
toanatron 1:16fdeb024e42 123 SIM800L->printf("AT+CNMI=1,2,0,0,0\r\n"); // Set the receiving mode of the GSM module
toanatron 1:16fdeb024e42 124 read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
toanatron 1:16fdeb024e42 125 if(!checkResponse)continue;
toanatron 1:16fdeb024e42 126 if(!strcmp("OK", buff)){ // expected message
toanatron 1:16fdeb024e42 127 wait(0.1f);
toanatron 1:16fdeb024e42 128 }else continue;
toanatron 1:16fdeb024e42 129
toanatron 1:16fdeb024e42 130 SIM800L->printf("AT+CMGS=\"1##########\"\r\n"); // communicate to SIM800L to respond OK
toanatron 1:16fdeb024e42 131 read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
toanatron 1:16fdeb024e42 132 if(!checkResponse)continue;
toanatron 1:16fdeb024e42 133 if(strcmp(">", buff) == 0){ // expected message
toanatron 1:16fdeb024e42 134 wait(0.1f);
toanatron 1:16fdeb024e42 135 }else continue;
toanatron 1:16fdeb024e42 136
toanatron 1:16fdeb024e42 137 blockSymbol = 1;
toanatron 1:16fdeb024e42 138 SIM800L->printf("%s BPM:%d %c\r\n",loc,bpm,CTRL_Z); // communicate to SIM800L to respond OK
toanatron 1:16fdeb024e42 139 read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
toanatron 1:16fdeb024e42 140 if(!checkResponse)continue;
toanatron 1:16fdeb024e42 141 if(!strcmp("OK", buff)){ // expected message
toanatron 1:16fdeb024e42 142 wait(0.1f);
toanatron 1:16fdeb024e42 143 }else continue;
toanatron 1:16fdeb024e42 144
toanatron 1:16fdeb024e42 145 blockSymbol = 0;
toanatron 1:16fdeb024e42 146 request = 1;
toanatron 1:16fdeb024e42 147 read_message(buff, &checkResponse,SIM800L, blockSymbol, request);
toanatron 1:16fdeb024e42 148 if(!checkResponse)continue;
toanatron 1:16fdeb024e42 149 if(strcmp("$RECEIVED", buff) == 0){ // expected message
toanatron 1:16fdeb024e42 150 wait(0.1f);
toanatron 1:16fdeb024e42 151 rescueLED = 0;
toanatron 1:16fdeb024e42 152 checkProcess = 0;
toanatron 1:16fdeb024e42 153 }else continue;
toanatron 1:16fdeb024e42 154 SIM800L->printf("AT+CMGF=0\r\n"); // set to the default mode on the SIM800L
toanatron 1:16fdeb024e42 155 wait(0.1f);
toanatron 1:16fdeb024e42 156 }
toanatron 1:16fdeb024e42 157 delete SIM800L;
toanatron 1:16fdeb024e42 158 }
kchhouk 0:c9d0008613d6 159
kchhouk 0:c9d0008613d6 160 int main(){
toanatron 1:16fdeb024e42 161 char loc[50] = "https://www.google.com/maps/place/38 47\'26.16\"N+77 27'44.91\"W";
toanatron 1:16fdeb024e42 162 int bpm = 100;
toanatron 1:16fdeb024e42 163 // Send a dummy location/bpm to a phone number
toanatron 1:16fdeb024e42 164 sendEmergencyLocation(loc,bpm);
kchhouk 0:c9d0008613d6 165 }
kchhouk 0:c9d0008613d6 166