SIM800 – Controlling Arduino with SMS (IoT Backup Route)

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInDigg thisShare on RedditPin on PinterestPrint this pageEmail this to someone

This post further discusses on extracting commands sent to an Arduino in form of an SMS, using SIM800 module. Discussed setup can be used as a backup route to an IoT device, enabling access in case of a failure in the primary network connectivity.

A backup route to be used in case your internet connections went down or maybe “the thief” took down the router first, leaving no way for you to connect with your master mind IoT security system. (wink)

This is the continuation of a previous post titled “Quickstart SIM800 (SIM800L) with Arduino“, which is recommended for anyone new to SIM800.

Reading Incoming SMS

Looking an AT command manual for SIM800 we found in the previous post it is clear that “ AT+CMGL “REC UNREAD” 0 ” can be used to list all the unread SMS messages. Using the index obtained by “CMGL”, it is possible to use “AT+CMGR <index> 0” to read contents of each unread message. But with this approach, it is necessary to pull messages stored in SIM periodically. This can be very inefficient in case of a system that does not get commands very frequently. If Arduino is running off of a battery above check will drain the battery pretty fast. Moreover, commands sent will not apply immediately.

Due to above limitations and inefficiencies, it is best to use “AT+CNMI” command (“New SMS Message Indications”) to get notified of any new incoming SMS message. Trying “AT+CNMI 1,2,0,0,0” on Arduino IDE “Serial Monitor” results in below, upon SMS arrival :

AT1

 

Enhanced Sample

With below code it is possible to process incoming “New SMS Message Indications” in form of “+CMT”, check the next line for the actual message content and do a certain action based on the command received. For simplicity, below code will only turn ON and OFF the LED built into Arduino (digital pin 13).

It is obvious that same logic can be applied even to operate an A/C powered device (using a relay).

Below sample is available for download at : http://www.ayomaonline.com/?download=SIM800SMS

#include <gprs.h>
#include <softwareserial.h>

#define TIMEOUT    5000
#define LED_PIN    13

bool ledStatus;
GPRS gprs;

void setup() {
  Serial.begin(9600);
  while(!Serial);

  Serial.println("Starting SIM800 SMS Command Processor");
  gprs.preInit();
  delay(1000);

  while(0 != gprs.init()) {
      delay(1000);
      Serial.print("init error\r\n");
  }  

  //Set SMS mode to ASCII
  if(0 != gprs.sendCmdAndWaitForResp("AT+CMGF=1\r\n", "OK", TIMEOUT)) {
    ERROR("ERROR:CNMI");
    return;
  }
  
  //Start listening to New SMS Message Indications 
  if(0 != gprs.sendCmdAndWaitForResp("AT+CNMI=1,2,0,0,0\r\n", "OK", TIMEOUT)) {
    ERROR("ERROR:CNMI");
    return;
  }

  Serial.println("Init success");
}

//Variable to hold last line of serial output from SIM800
char currentLine[500] = "";
int currentLineIndex = 0;

//Boolean to be set to true if message notificaion was found and next
//line of serial output is the actual SMS message content
bool nextLineIsMessage = false;

void loop() {
  //Write current status to LED pin
  digitalWrite(LED_PIN, ledStatus);
  
  //If there is serial output from SIM800
  if(gprs.serialSIM800.available()){
    char lastCharRead = gprs.serialSIM800.read();
    //Read each character from serial output until \r or \n is reached (which denotes end of line)
    if(lastCharRead == '\r' || lastCharRead == '\n'){
        String lastLine = String(currentLine);
        
        //If last line read +CMT, New SMS Message Indications was received. 
        //Hence, next line is the message content.
        if(lastLine.startsWith("+CMT:")){
          
          Serial.println(lastLine);
          nextLineIsMessage = true;
          
        } else if (lastLine.length() > 0) {
          
          if(nextLineIsMessage) {
            Serial.println(lastLine);
            
            //Read message content and set status according to SMS content
            if(lastLine.indexOf("LED ON") >= 0){
              ledStatus = 1;
            } else if(lastLine.indexOf("LED OFF") >= 0) {
              ledStatus = 0;
            }
            
            nextLineIsMessage = false;
          }
          
        }
        
        //Clear char array for next line of read
        for( int i = 0; i < sizeof(currentLine);  ++i ) {
         currentLine[i] = (char)0;
        }
        currentLineIndex = 0;
    } else {
      currentLine[currentLineIndex++] = lastCharRead;
    }
  }
}

Turning LED ON :

ST1

?????

Turning LED OFF :

ST2

?????????????

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInDigg thisShare on RedditPin on PinterestPrint this pageEmail this to someone

14 comments on “SIM800 – Controlling Arduino with SMS (IoT Backup Route)

  1. RAF March 24, 2016 9:48 PM

    hi, I’m having a problem with $gt; and &lt, it says “‘gt’ was not declared in this scope” when I try to upload the code, do you know what could be the problem?

    • Ayoma April 19, 2016 2:22 PM

      Hi RAF,

      If I understood your problem properly, your browser might have copied the code with the HTML encoding. Can you replace all “&gt” with “>” signs and “&lt” with “<" signs. Maybe there are other encoded items as well. Let me know if you find other errors. If so, I will provide a text file with code for you to download. Regards, Ayoma

  2. Stefan April 22, 2016 7:10 PM

    After replace all “&gt” with “>” signs and “&lt” with “<" signs
    is it exit for verify the sketch from row 83 to row 88

    exit status 1 row83
    expected ')' before ';' token
    84: error: 'i' was not declared in this scope
    90: error: expected declaration before '}' token
    exit status 1
    expected unqualified-id before 'else'

    can you please load up the working code ,

    Thank you anyway for your simm800 post's
    /Stefan

    • Ayoma April 29, 2016 2:28 PM

      Looks like I’ll have to change the syntax highlighter soon 🙂 I have corrected the post and added additional download link for the code. Please note that this is continuation of “Quickstart SIM800 (SIM800L) with Arduino” (linked on top of the post). You will need Seeeduino_GPRS library (https://github.com/Seeed-Studio/Seeeduino_GPRS) to get this working. Read through the first post for relevant details.

  3. Ankur Chaudhari July 20, 2016 2:14 PM

    SIM800 moduel showing power check failed! error after “Starting SIM….”

  4. amir August 5, 2016 8:47 PM

    Hi rx and tx pins are connected to what I base ?

  5. Luis August 10, 2016 7:51 AM

    where can i get the gprs.h???

  6. Gurcharan Singh October 12, 2016 10:21 PM

    hello sir,

    Thank your sir for the code, the code provided by you is working …sir i have a question assume i have two numbers (number1 & number 2) if i send command from number1 the led should on..but if i send LED ON command from number2 the led should not on …then how could we edit the code to worked like that?
    please reply soon..

  7. Amal October 21, 2016 12:20 AM

    thanks for your codes.
    to delete the all sms i used below codes
    //if(0 != gprs.sendCmdAndWaitForResp(“AT+CMGD=1,4\r\n”, “OK”, TIMEOUT))
    //{Serial.println(“SMS was deleted”);}
    //else
    // {Serial.println(“SMS was not deleted”);}

    but it was not work out.
    what is the problem behind that.
    thanks

  8. Amal October 21, 2016 1:02 AM

    Oh finally AT+CMGDA=1 was work out with below codes
    if(0 != gprs.sendCmdAndWaitForResp(“AT+CMGDA=1\r\n”, “OK”, 5))
    {Serial.println(“SMS was deleted”);}
    else
    {Serial.println(“SMS was not deleted”);}
    it takes some times to delete sms, so then set timeout=5 //timerEnd – timerStart > 1000 * timeout

  9. Salam November 12, 2016 8:22 PM

    Hi. Ayoma
    I used your code on Arduino ouno and all things is right just when I send on or off led, no action will happen and led not turns on.
    Pleas help me.

    • Roshan Chamal November 14, 2016 12:13 AM

      add pin configuration line as describe below:

      GPRS gprs;

      void setup() {
      //setup pin 13
      pinMode(13, OUTPUT);

      • Roshan Chamal November 14, 2016 12:14 AM

        need to change this section:

        //Read message content and set status according to SMS content
        if (lastLine.indexOf( “LED ON”) >= 0) {
        //ledStatus = 1;
        digitalWrite(LED_PIN, HIGH);
        Serial.println(“ON”);
        } else if (lastLine.indexOf( “LED OFF”) >= 0) {
        //ledStatus = 0;
        digitalWrite(LED_PIN, LOW);
        Serial.println(“OFF”);
        }

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">