SIM800L implementation
Dependencies: mbed BufferedSerial
GSMProgramAutomation.cpp@1:16fdeb024e42, 2020-05-09 (annotated)
- Committer:
- toanatron
- Date:
- Sat May 09 20:09:37 2020 +0000
- Revision:
- 1:16fdeb024e42
- Parent:
- 0:c9d0008613d6
update;
Who changed what in which revision?
User | Revision | Line number | New 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 |