Tutorial: How to use SIM800L GSM Module for Controlling Anything | Arduino

Introduction

In this tutorial, you will be able to use the SIM800L GSM module for controlling anything through SMS. To do that, we just need to parse the incoming SMS from SIM800L through serial communication. In this Arduino sketch, we will be parsing the following:
1. Find the string “CMT:”, then save the sender’s mobile number for the purpose of replying.
2. Find the string “CMD:”, then save the specified commands
3. Find the string “NUM:”, then save the new default mobile number.

After successful parsing, we can process the command and act accordingly.

Circuit Diagram

Video Demonstration

Call To Action

If you have any question regarding this tutorial, please do not hesitate to write it in the comment box.

If you find this tutorial helpful, please consider supporting me by SUBSCRIBING to my Youtube channel: Click this to Subscribe to TechToTinker.

Source Code

  1
  2/*  Date: July 29, 2020
  3 *  Author: George Bantique, TechToTinker Youtube channel
  4 *          https://techtotinker.blogspot.com
  5 *  Tutorial: How to use SIM800L to control anything
  6 *  Description:
  7 *      In this Arduino sketch, you will be able to send specific commands 
  8 *      to control anything. It can also be configured to reply in every sms
  9 *      you send.
 10 *      
 11 *      Here are the breakdown of available option:
 12 *        Send command in this format:
 13 *            CMD: RED 1<
 14 *              - turn ON the red LED
 15 *            CMD: RED 0<
 16 *              - turn OFF the red LED
 17 *            CMD: GRN 1<
 18 *              - turn ON the green LED
 19 *            CMD: GRN 0<
 20 *              - turn OFF the green LED
 21 *            CMD: BLU 1<
 22 *              - turn ON the blue LED
 23 *            CMD: BLU 0<
 24 *              - turn OFF the blue LED
 25 *            CMD: ALL 1<
 26 *              - turn ON all the LED
 27 *            CMD: ALL 0<
 28 *              - turn OFF all the LED
 29 *            CMD: REP 1<
 30 *              - enable the reply for every SMS
 31 *            CMD: REP 0<
 32 *              - disable the reply, but will still reply to the following:
 33 *                CMD: REP 1<
 34 *                CMD: REP 0<
 35 *                CMD: GET S<
 36 *            CMD: GET S<
 37 *              - sends the current states of the LEDs
 38 *            NUM: +ZZxxxxxxxxxx<
 39 *              - changes the current default number
 40 *                ZZ - country code
 41 *                xx - 10-digit number
 42 *      When event is triggered let say in this tutorial, we just use a push button tactile switch    
 43 *      but you can expand it, for example you can use an intruder detection that will send an SMS
 44 *      when an intruder is detected.
 45 *      
 46 *      Please feel free to modify it to adapt to your specific needs, just leave this comments as      
 47 *      credits to me. Thank you and happy tinkering. -George
 48 */
 49#include "SoftwareSerial.h"
 50
 51#define SERIAL_DEBUG          // comment out this to remove serial debug
 52#define SMS_ENABLED           // comment out this to disable sms sending, to save from expenses
 53#define SIMULATE_BY_SERIAL    // comment out this to use the actual SIM800L
 54
 55SoftwareSerial SIM800L(11, 12);  // Arduino D11(as Rx pin) to SIM800L Tx pin
 56                                 // Arduino D12(as Tx pin) to SIM800L Rx pin
 57#define RED_LED   7   // Pin assignments for LED and Switch
 58#define GRN_LED   6
 59#define BLU_LED   5
 60#define SW_PIN    4
 61
 62#define BUFFER_SIZE   127       // incoming data buffer size
 63char bufferData[BUFFER_SIZE];   // holds the char data
 64char bufferIndex;               // holds the position of the char in the buffer
 65
 66// This variable holds the SMS sender mobile number, it will be updated when new sms arrived
 67char sender_num[14] = {'+', '6', '3', '9', '7', '5', '9', '2', '3', '1', '2', '4', '3' };
 68
 69// This variable holds the mobile number of the owner, emergency sms will be sent to this
 70// when the event is triggered lets say the button press
 71char default_num[14] = {'+', '6', '3', '9', '7', '5', '9', '2', '3', '1', '2', '4', '3' };
 72
 73char sender_cmd[7];     // holds the specific command when a new SMS is received
 74
 75bool CMT_OK = false;    // CMT is for processing the SMS senders mobile number
 76int cmt_pos_index = 0;  
 77int cmt_pos_count = 0;
 78
 79bool CMD_OK = false;    // CMD is for processing the parsing the sms command
 80int cmd_pos_index = 0;
 81int cmd_pos_count = 0;
 82
 83bool NUM_OK = false;    // NUM is for processing the CHANGE NUMBER option
 84int num_pos_index = 0;
 85int num_pos_count = 0;
 86
 87bool redLEDState = false;   // holds the state of LEDs
 88bool grnLEDState = false;   //    true:  means ON
 89bool bluLEDState = false;   //    false: means OFF
 90
 91bool newData = false;
 92
 93bool isReplyOn = false;     // hold the settings for sending the status update for every sms 
 94                            //    true:  reply to every sms
 95                            //    false: reply only to some sms request like request for status
 96
 97bool currState = HIGH;            // this variables are for the button debouncing
 98bool prevState = HIGH;
 99unsigned long startMillis = 0;
100unsigned long debounceDelay = 50;
101
102/*
103 *  Function: void setup()
104 *  Purpose:
105 *    This function is for initializations
106 */
107void setup(){
108  Serial.begin(9600);
109  Serial.println("Initializing...");
110  SIM800L.begin(9600);
111  delay(2000);      // gives enough time for the GSM module to bootup
112  initializeGSM();  // set the necessary initializations for the GSM module
113  pinMode(RED_LED, OUTPUT);           // set the pin directions of other pins
114  pinMode(GRN_LED, OUTPUT);
115  pinMode(BLU_LED, OUTPUT);
116  pinMode(SW_PIN, INPUT_PULLUP);
117  digitalWrite(RED_LED, redLEDState); // set the current states of LEDs
118  digitalWrite(GRN_LED, grnLEDState);
119  digitalWrite(BLU_LED, bluLEDState);
120  memset(bufferData, 0, sizeof(bufferData)); // Initialize the string     
121  bufferIndex = 0; 
122  Serial.println("Setup done");
123
124}
125
126/*
127 *  Function: void loop()
128 *  Purpose:
129 *    This is the main loop
130 */
131void loop(){
132  manageButton();
133  manageSIM800();
134  delay(500);
135}
136
137/*
138 *  Function: void initializeGSM()
139 *  Purpose:
140 *    This function is for the SIM800L initializations
141 */
142void initializeGSM() {
143#ifdef SIMULATE_BY_SERIAL
144  Serial.println("AT");                   // Sends an ATTENTION command, reply should be OK
145  Serial.println("AT+CMGF=1");            // Configuration for sending SMS
146  Serial.println("AT+CNMI=1,2,0,0,0");    // Configuration for receiving SMS
147  Serial.println("AT&W");                 // Save the configuration settings
148#else // actual
149  SIM800L.println("AT");                  // Sends an ATTENTION command, reply should be OK
150  delay(1000);
151  SIM800L.println("AT+CMGF=1");           // Configuration for sending SMS
152  delay(1000);
153  SIM800L.println("AT+CNMI=1,2,0,0,0");   // Configuration for receiving SMS
154  delay(1000);
155  Serial.println("AT&W");                 // Save the configuration settings
156  delay(1000);
157#endif // SIMULATE_BY_SERIAL
158}
159
160/*
161 *  Function: void manageButton()
162 *  Purpose:
163 *    This is for polling the state of the button.
164 *    Additional button debouncing is use to prevent
165 *    false button presses.
166 */
167void manageButton() {
168  bool currRead = digitalRead(SW_PIN);  
169
170  if (currState != prevState) {
171    startMillis = millis();
172  }
173  if ((millis() - startMillis) > debounceDelay) {
174    if (currRead != currState) {
175      currState = currRead;
176      if (currState == LOW) {
177#ifdef SERIAL_DEBUG
178        Serial.println("Alert!");
179#endif //SERIAL_DEBUG
180        sendSMS("Alert! Event triggered", default_num);
181      }
182    }
183  }
184  prevState = currState;
185}
186
187/*
188 *  Function: void manageSIM800()
189 *  Purpose:
190 *    This is for parsing the incoming serial data from SIM800L
191 *    so that we can use it for controlling something.
192 */
193void manageSIM800() {
194 
195#ifdef SIMULATE_BY_SERIAL
196  while (Serial.available() > 0) {
197    bufferData[bufferIndex] = Serial.read();
198    // Find the string "CMD:"
199    //    if found, parse the command for processing
200    if( //(bufferData[bufferIndex-3] == 'C') && 
201        //(bufferData[bufferIndex-2] == 'M') && 
202        (bufferData[bufferIndex-1] == 'D') && 
203        (bufferData[bufferIndex] == ':')      )  {               
204      //Serial.println("CMD"); 
205      CMD_OK = true;      
206      memset(sender_cmd, 0, sizeof(sender_cmd));
207      cmd_pos_index = bufferIndex;  // get the position
208      cmd_pos_count = 0;            // reset pos counter   
209    }    
210    // Finds the string "NUM:"
211    //    if found, parse the command for processing
212    if( //(bufferData[bufferIndex-3] == 'N') &&
213        //(bufferData[bufferIndex-2] == 'U') && 
214        (bufferData[bufferIndex-1] == 'M') && 
215        (bufferData[bufferIndex] == ':')      )  {              
216      //Serial.println("NUM"); 
217      NUM_OK = true;
218      memset(default_num, 0, sizeof(default_num));
219      num_pos_index = bufferIndex;  // get the position
220      num_pos_count = 0;            // reset pos counter 
221      
222    } 
223    // Finds the string "CMT:"
224    //    if found, parse the command for processing
225    if( //(bufferData[bufferIndex-3] == 'C') && 
226        //(bufferData[bufferIndex-2] == 'M') && 
227        (bufferData[bufferIndex-1] == 'T') && 
228        (bufferData[bufferIndex] == ':')      )  {            
229      //Serial.println("CMT");  
230      CMT_OK = true;
231      memset(sender_num, 0, sizeof(sender_num));    
232      cmt_pos_index = bufferIndex;  // get the position
233      cmt_pos_count = 0;            // reset pos counter 
234    }    
235    // String "CMT:" is found, 
236    //  parse the sender number for the reply
237    //
238    if ( ( (bufferIndex - cmt_pos_index) > 2 ) && (CMT_OK) ) {
239      if ( cmt_pos_count < 13 ) {
240        sender_num[cmt_pos_count] =  bufferData[bufferIndex];
241        cmt_pos_count++;
242      } else {
243        //Serial.println(sender_num);
244        CMT_OK = false; // done
245      }
246    }
247    
248    // String "NUM:" is found
249    //  parse it then save it as default number then send a reply
250    //
251    if ( ( (bufferIndex - num_pos_index) > 1 ) && (NUM_OK) ) {
252      if ( bufferData[bufferIndex] != '<' ) {
253        default_num[num_pos_count] =  bufferData[bufferIndex];
254        num_pos_count++;
255      } else {
256        char msg[32] = "Default # is now ";
257        sendSMS((strcat( msg, default_num )), sender_num);                          // send it to the recipient number.
258        NUM_OK = false; // done
259        break;
260      }
261    } 
262    // String "CMD:" is found,
263    //  parse the command, then execute the command
264    //
265    if ( ( (bufferIndex - cmd_pos_index) > 1 ) && (CMD_OK)) {
266      if (bufferData[bufferIndex] == '<') {
267        //Serial.println(sender_cmd);
268        processCommand();
269        CMT_OK = false; // done
270        break;
271      } else {
272        sender_cmd[cmd_pos_count] =  bufferData[bufferIndex];
273        cmd_pos_count++;
274      }
275    } 
276    bufferIndex++;                              
277  }           
278
279  memset(bufferData, 0, sizeof(bufferData));    // Initialize the string     
280  bufferIndex = 0;
281#else // actual SIM800L GSM Module
282  while (SIM800L.available() > 0) {
283    bufferData[bufferIndex] = SIM800L.read();
284    // Find the string "CMD:"
285    //    if found, parse the command for processing
286    if( //(bufferData[bufferIndex-3] == 'C') && 
287        //(bufferData[bufferIndex-2] == 'M') && 
288        (bufferData[bufferIndex-1] == 'D') && 
289        (bufferData[bufferIndex] == ':')      )  {               
290      //Serial.println("CMD"); 
291      CMD_OK = true;      
292      memset(sender_cmd, 0, sizeof(sender_cmd));
293      cmd_pos_index = bufferIndex;  // get the position
294      cmd_pos_count = 0;            // reset pos counter   
295    }    
296    // Finds the string "NUM:"
297    //    if found, parse the command for processing
298    if( //(bufferData[bufferIndex-3] == 'N') &&
299        //(bufferData[bufferIndex-2] == 'U') && 
300        (bufferData[bufferIndex-1] == 'M') && 
301        (bufferData[bufferIndex] == ':')      )  {              
302      //Serial.println("NUM"); 
303      NUM_OK = true;
304      memset(default_num, 0, sizeof(default_num));
305      num_pos_index = bufferIndex;  // get the position
306      num_pos_count = 0;            // reset pos counter 
307    } 
308    // Finds the string "CMT:"
309    //    if found, parse the command for processing
310    if( //(bufferData[bufferIndex-3] == 'C') && 
311        //(bufferData[bufferIndex-2] == 'M') && 
312        (bufferData[bufferIndex-1] == 'T') && 
313        (bufferData[bufferIndex] == ':')      )  {            
314      //Serial.println("CMT");  
315      CMT_OK = true;
316      memset(sender_num, 0, sizeof(sender_num));    
317      cmt_pos_index = bufferIndex;  // get the position
318      cmt_pos_count = 0;            // reset pos counter 
319    }    
320    // String "CMT:" is found, 
321    //  parse the sender number for the reply
322    // +CMT: "+639175291539"
323    if ( ( (bufferIndex - cmt_pos_index) > 2 ) && (CMT_OK) ) {
324      if ( cmt_pos_count < 13 ) {
325        sender_num[cmt_pos_count] =  bufferData[bufferIndex];
326        cmt_pos_count++;
327      } else {
328        //Serial.println(sender_num);
329        CMT_OK = false; // done
330      }
331    }
332    // String "NUM:" is found
333    //  parse it then save it as default number then send a reply
334    //
335    if ( ( (bufferIndex - num_pos_index) > 1 ) && (NUM_OK) ) {
336      if ( bufferData[bufferIndex] != '<' ) {
337        default_num[num_pos_count] =  bufferData[bufferIndex];
338        num_pos_count++;
339      } else {
340        char msg[32] = "Default # is now ";
341        sendSMS((strcat( msg, default_num )), sender_num);                          // send it to the recipient number.
342        NUM_OK = false; // done
343        break;
344      }
345    } 
346    // String "CMD:" is found,
347    //  parse the command, then execute the command
348    //  CMD: GRN 0<
349    if ( ( (bufferIndex - cmd_pos_index) > 1 ) && (CMD_OK)) {
350      if (bufferData[bufferIndex] == '<') {
351        //Serial.println(sender_cmd);
352        processCommand();
353        CMT_OK = false; // done
354        break;
355      } else {
356        sender_cmd[cmd_pos_count] =  bufferData[bufferIndex];
357        cmd_pos_count++;
358      }
359    } 
360    bufferIndex++;                              
361  }           
362  memset(bufferData, 0, sizeof(bufferData));    // Initialize the string     
363  bufferIndex = 0;
364#endif //SIMULATE_BY_SERIAL
365}
366
367/*
368 *  Function: void processCommand()
369 *  Purpose:
370 *    This function execute the receive commands via SMS
371 *    CMD: RED 1<
372 */   
373void processCommand() {
374  if        (strcmp(sender_cmd, "RED 1") == 0) {
375    redLEDState = true;
376    if (isReplyOn)
377      sendSMS("Red LED On", sender_num);
378  } else if (strcmp(sender_cmd, "RED 0") == 0) {
379    redLEDState = false;
380    if (isReplyOn)
381      sendSMS("Red LED Off", sender_num);
382  } else if (strcmp(sender_cmd, "GRN 1") == 0) {
383    grnLEDState = true;
384    if (isReplyOn)
385      sendSMS("Green LED On", sender_num);
386  } else if (strcmp(sender_cmd, "GRN 0") == 0) {
387    grnLEDState = false;
388    if (isReplyOn)
389      sendSMS("Green LED Off", sender_num);
390  } else if (strcmp(sender_cmd, "BLU 1") == 0) {
391    bluLEDState = true;
392    if (isReplyOn)
393      sendSMS("Blue LED On", sender_num);
394  } else if (strcmp(sender_cmd, "BLU 0") == 0) {
395    bluLEDState = false;
396    if (isReplyOn)
397      sendSMS("Blue LED Off", sender_num);
398  } else if (strcmp(sender_cmd, "ALL 0") == 0) {
399    redLEDState = false;
400    grnLEDState = false;
401    bluLEDState = false;
402    if (isReplyOn)
403      sendSMS("All LED Off", sender_num);
404  } else if (strcmp(sender_cmd, "ALL 1") == 0) {
405    redLEDState = true;
406    grnLEDState = true;
407    bluLEDState = true;
408    if (isReplyOn)
409      sendSMS("All LED On", sender_num);
410  } else if (strcmp(sender_cmd, "REP 1") == 0) {       // This command is to turn ON the reply to every sms
411    isReplyOn = true;
412#ifdef SMS_ENABLED
413    sendSMS("Reply is now ON", sender_num);
414#endif //SMS_ENABLED
415  } else if (strcmp(sender_cmd, "REP 0") == 0) {      // This command is to turn OFF the reply to every sms
416    isReplyOn = false;
417#ifdef SMS_ENABLED
418    sendSMS("Reply is now OFF", sender_num);
419#endif //SMS_ENABLED
420  } else if (strcmp(sender_cmd, "GET S") == 0) {    // This command sends the current status of all LEDs
421    String statusSMS = "";                               // Create the status reply
422    statusSMS = "Red LED is ";
423    if (redLEDState) {
424      statusSMS += "ON";
425    } else statusSMS += "OFF";
426    statusSMS += ". Green LED is ";
427    if (grnLEDState) {
428      statusSMS += "ON";
429    } else statusSMS += "OFF";
430    statusSMS += ". Blue LED is ";
431    if (bluLEDState) {
432      statusSMS += "ON";
433    } else statusSMS += "OFF";
434#ifdef SMS_ENABLED
435    sendSMS(statusSMS, sender_num);
436#endif //SMS_ENABLED
437  } 
438  digitalWrite(RED_LED, redLEDState);   // Sets the LED states according
439  digitalWrite(GRN_LED, grnLEDState);   //  according to the received
440  digitalWrite(BLU_LED, bluLEDState);   //  commands
441
442}
443
444/*
445 *  Function: void sendSMS(String message, String mobile)
446 *  Purpose:
447 *    This function is use for sending the reply SMS
448 */
449void sendSMS(String message, String mobile) {
450#ifdef SIMULATE_BY_SERIAL
451  Serial.println("AT+CMGS="" + mobile + ""r"); //Mobile phone number to send message
452  Serial.println(message);                        // This is the message to be sent.
453  Serial.println((char)26);                       // ASCII code of CTRL+Z to finalized the sending of sms
454#else // actual
455  //SIM800L.println("AT+CMGF=1");                    //Sets the GSM Module in Text Mode
456  //delay(1000);
457  SIM800L.println("AT+CMGS="" + mobile + ""r"); //Mobile phone number to send message
458  delay(1000);
459  SIM800L.println(message);                        // This is the message to be sent.
460  delay(1000);
461  SIM800L.println((char)26);                       // ASCII code of CTRL+Z to finalized the sending of sms
462  delay(1000);
463#endif // SIMULATE_BY_SERIAL
464}


Posts in this series



No comments yet!

GitHub-flavored Markdown & a sane subset of HTML is supported.