How to send the state of an LED via SMS

Sorry, you do have them set, I missed it. It's still rather early!

You could try declare the pins as INPUT or OUTPUT first, then do the digital writes.

  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led13, OUTPUT);
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT);  
  pinMode(Relay_4, OUTPUT);  

  //-------( Initialize Pins so relays are inactive at reset)----
  
  digitalWrite(led, LOW);  // Set led to LOW
  digitalWrite(led13, LOW);  // Set led to LOW
  
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF);

thanks, i will try this later and get back to you.

Hi Dan,

I now want to build a level of security into controlling this LED via SMS. I want to have a password. Example: currently I'm controlling/monitoring the LED using these commands:

#a0 - to turn OFF light
#a1 - to turn ON light
#aS - to get the light STATUS

In my text message i now want a password TEXT = passwd + command i.e the password i want to use for example is ?20!4

?20!4#a0 - to turn light OFF
?20!4#a1 - to turn ligh ON
?20!4#aS - to get STATUS

I thought of modifying my void loop to this:

void loop() {
 
 if(SIM900.available() >0)
 {
   
 incoming_char=SIM900.read(); 
 
  if (incoming_char=='?')
   {
   delay(10);
   incoming_char=SIM900.read(); 
   
    if (incoming_char=='2')
   {
   delay(10);
   incoming_char=SIM900.read(); 
   
   
    if (incoming_char=='0')
   {
   delay(10);
   incoming_char=SIM900.read(); 
   
   
    if (incoming_char=='!')
   {
   delay(10);
   incoming_char=SIM900.read(); 
   
   
    if (incoming_char=='4')
   {
   delay(10);
   incoming_char=SIM900.read(); 
   
 if (incoming_char=='#')
   {
   delay(10);
   incoming_char=SIM900.read(); 

 if (incoming_char=='a')
     {
   delay(10);
   incoming_char=SIM900.read();

 if (incoming_char=='0')
   {
   digitalWrite(led, LOW);
   digitalWrite(Relay_1, LOW);// set the Relay OFF
   delay(1000);              // wait for a second
   } 
 else if (incoming_char=='1')
   {
   digitalWrite(led, HIGH);
   digitalWrite(Relay_1, HIGH);// set the Relay ON
   delay(1000);              // wait for a second
   }
 else if (incoming_char=='S')
   {
   digitalRead(led);
   led_status=digitalRead(led);
   Serial.print(led_status);  // prints status on serial terminal
   sendSMS(led_status);
   }
 delay(10);
                   }
                }
             }
          }
        }
      }
    }
  }
}

Is there a shorter way i can use to have password checked in the SMS being sent with out using the IF statement because it makes the code very long :frowning:

Stick them in a char array (Not a String!) and then do a string compare?

Just in case: http://www.cplusplus.com/reference/cstring/strcmp/

Hi Dan,

I have built some security into my code. I have not used the char array as mentioned previuosly, but I will. When i run this code even if i send the correct code to the arduino i.e ?20!4#a1 it keeps executing the sendSMSFAULT function repeatedly. Also why is it runnign that part of the code because the correct code was sent to the arduino to turn on light. Please have a look at the attached code for please:

The sendSMSFAULT should only run if the incoming character does not begin with ? mark

#include <SoftwareSerial.h>

SoftwareSerial SIM900(2, 3); // RX, TX

char incoming_char=0; //Will hold the incoming character from the Serial Port.If the command becomes bigger than 8 bits, try use char16_t
 
// Pin 8 has an LED connected on most Arduino boards.
int led = 8;
int led13 = 13;
int led_status = 0;     // variable to store the led status

/*-----( Declare Constants )-----*/
#define RELAY_ON 0
#define RELAY_OFF 1

/*-----( Declare variables )-----*/
#define Relay_1  8  // Arduino Digital I/O pin number
#define Relay_2  7
#define Relay_3  6
#define Relay_4  5

  // the setup routine runs once when you press reset:
void setup() {                

  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led13, OUTPUT);
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT);  
  pinMode(Relay_4, OUTPUT);  
  
  digitalWrite(led, LOW);  // Set led to LOW
  digitalWrite(led13, LOW);  // Set led to LOW
  
  //-------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF); 
  
  Serial.begin(19200); // set the baud rate
  SIM900.begin(19200); // for GSM shield
  delay(20000);  // give time to log on to network.
  Serial.println("setup Section");
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.println("AT+CNMI=2,2,0,0,0\r"); 
  SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100); 
  //digitalWrite(led, LOW);  // Set led to LOW
  //digitalWrite(led13, LOW);  // Set led to LOW
 // Serial.println("AT+CMGD=1,4");  //Delete all SMS in box
}

void sendSMS(byte led_status){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+277XXXXXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
if (led_status==0)
    {
      SIM900.println( " LIGHT STATUS: OFF");
      }
else
    {
      SIM900.println( " LIGHT STATUS: ON");
    }
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

void sendSMSFAULT(){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+277XXXXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  SIM900.println( " SORRY! YOU ARE NOT ALLOWED TO USE THE SYSTEM");
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

// the loop routine runs over and over again forever:
void loop() {
 
 if(SIM900.available() >0)
 {
 incoming_char=SIM900.read(); 
 if (incoming_char!='?')
   {
   delay(10);
   Serial.println("Discarded SMS");
   sendSMSFAULT();
   Serial.println("AT+CMGD=1,4");
   incoming_char=SIM900.read(); 
  if (incoming_char=='?')
   {
   delay(10);
   incoming_char=SIM900.read();   
 if (incoming_char=='2')
   {
   delay(10);
   incoming_char=SIM900.read(); 
 if (incoming_char=='0')
   {
   delay(10);
   incoming_char=SIM900.read(); 
 if (incoming_char=='!')
   {
   delay(10);
   incoming_char=SIM900.read();  
 if (incoming_char=='4')
   {
   delay(10);
   incoming_char=SIM900.read();   
 if (incoming_char=='#')
   {
   delay(10);
   incoming_char=SIM900.read(); 
 if (incoming_char=='a')
     {
   delay(10);
   incoming_char=SIM900.read();
 if (incoming_char=='0')
   {
   digitalWrite(led, LOW);
   digitalWrite(Relay_1, LOW);// set the Relay OFF
   delay(1000);              // wait for a second
   } 
 else if (incoming_char=='1')
   {
   digitalWrite(led, HIGH);
   digitalWrite(Relay_1, HIGH);// set the Relay ON
   delay(1000);              // wait for a second
   }
 else if (incoming_char=='S')
   {
   digitalRead(led);
   led_status=digitalRead(led);
   Serial.print(led_status);  // prints status on serial terminal
   sendSMS(led_status);
   }
 delay(10);
                   }
                }
             }
            }
          }
        }
      }
    }
  }
}

I also included this in the code as you previously advised in the void Setup, however even after the changes, when i upload the code onto the arduino, my LED turns ON and stays ON....:frowning:

 // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led13, OUTPUT);
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT);  
  pinMode(Relay_4, OUTPUT);  
  
  digitalWrite(led, LOW);  // Set led to LOW
  digitalWrite(led13, LOW);  // Set led to LOW
  
  //-------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF);

Hi Dan,

May you please give me an example how I can used the char array to analyze the incoming char and to do a compare as mentioned earlier.

"Stick them in a char array (Not a String!) and then do a string compare?"

In reply #3 I said:

Auto-format feature is your friend. Use it - a lot.

If you try it on the code you posted on 4th October you should be able to see where the problem arises. You have all your conditional testing in the section beginning:

 if (incoming_char!='?')

Hi Dan,

I have modified my void loop, however now my code keeps executing the sendSMSFAULT() function ALWAYS, even without sending commands to my modem. Please have a look at where I'm going wrong:

#include <SoftwareSerial.h>

SoftwareSerial SIM900(2, 3); // RX, TX

char incoming_char=0; //Will hold the incoming character from the Serial Port.If the command becomes bigger than 8 bits, try use char16_t

// Pin 8 has an LED connected on most Arduino boards.
int led = 8;
int led13 = 13;
int led_status = 0;     // variable to store the led status

/*-----( Declare Constants )-----*/
#define RELAY_ON 0
#define RELAY_OFF 1

/*-----( Declare variables )-----*/
#define Relay_1  8  // Arduino Digital I/O pin number
#define Relay_2  7
#define Relay_3  6
#define Relay_4  5

// the setup routine runs once when you press reset:
void setup() {                

  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led13, OUTPUT);
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT);  
  pinMode(Relay_4, OUTPUT);  

  digitalWrite(led, LOW);  // Set led to LOW
  digitalWrite(led13, LOW);  // Set led to LOW

    //-------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF); 

  Serial.begin(19200); // set the baud rate
  SIM900.begin(19200); // for GSM shield
  delay(20000);  // give time to log on to network.
  Serial.println("setup Section");
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.println("AT+CNMI=2,2,0,0,0\r"); 
  SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100); 
  //digitalWrite(led, LOW);  // Set led to LOW
  //digitalWrite(led13, LOW);  // Set led to LOW
  // Serial.println("AT+CMGD=1,4");  //Delete all SMS in box
}

void sendSMS(byte led_status){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+27725XXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  if (led_status==0)
  {
    SIM900.println( " LIGHT STATUS: OFF");
  }
  else
  {
    SIM900.println( " LIGHT STATUS: ON");
  }
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

void sendSMSFAULT(){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+27XXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  SIM900.println( " SORRY! YOU ARE NOT ALLOWED TO USE THE SYSTEM");
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

// the loop routine runs over and over again forever:
void loop() {

  if(SIM900.available() >0)
  {
    incoming_char=SIM900.read(); 
    if (incoming_char!='?')
    {
      delay(10);
      Serial.println("Discard SMS");
      sendSMSFAULT();
      Serial.println("AT+CMGD=1,4");
      {
        delay(10);
        incoming_char=SIM900.read();   
        if (incoming_char=='?')
        {
          delay(10);
          incoming_char=SIM900.read();   
          if (incoming_char=='2')
          {
            delay(10);
            incoming_char=SIM900.read(); 
            if (incoming_char=='0')
            {
              delay(10);
              incoming_char=SIM900.read(); 
              if (incoming_char=='!')
              {
                delay(10);
                incoming_char=SIM900.read();  
                if (incoming_char=='4')
                {
                  delay(10);
                  incoming_char=SIM900.read();   
                  if (incoming_char=='#')
                  {
                    delay(10);
                    incoming_char=SIM900.read(); 
                    if (incoming_char=='a')
                    {
                      delay(10);
                      incoming_char=SIM900.read();
                      if (incoming_char=='0')
                      {
                        digitalWrite(led, LOW);
                        digitalWrite(Relay_1, LOW);// set the Relay OFF
                        delay(1000);              // wait for a second
                      } 
                      else if (incoming_char=='1')
                      {
                        digitalWrite(led, HIGH);
                        digitalWrite(Relay_1, HIGH);// set the Relay ON
                        delay(1000);              // wait for a second
                      }
                      else if (incoming_char=='S')
                      {
                        digitalRead(led);
                        led_status=digitalRead(led);
                        Serial.print(led_status);  // prints status on serial terminal
                        sendSMS(led_status);
                      }
                      delay(10);
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Rather than checking each incoming character individually why not just load them into a character array?

In the following example the sketch waits until 5 characters have been received from Serial Terminal and then compares them to 'secret_code'.

char buffer[6]; // Five char plus null terminator
char secret_code[] = "12345";
char incoming_char;
byte buffer_pos=0;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  if (Serial.available()>0)
  {
    incoming_char=Serial.read();
    buffer[buffer_pos]=incoming_char;
    buffer_pos++;
    if (buffer_pos==5) // Already incremented
    {
      //Print it out
      buffer[buffer_pos]='\0';
      Serial.write(buffer);
      Serial.println();
      if (strcmp(buffer,secret_code)==0)
      {
        Serial.println("It's a match!");
      }
      buffer_pos=0;
    }
  }
}

Hi Dan,

I have modified my code to include storing incomming data from serial into a char_array as below. I will test it a bit later as I'm still at work. Please have a look at the below code and comment:

#include <SoftwareSerial.h>

SoftwareSerial SIM900(2, 3); // RX, TX

// Pin 8 has an LED connected on most Arduino boards.
int led = 8;
int led13 = 13;
int led_status = 0;     // variable to store the led status
char buffer[9]; // eight char plus null terminator
char secret_code[] = "?20!4#a0"; 
char secret_code1[] = "?20!4#a1";
char secret_code2[] = "?20!4#aS";
char incoming_char=0; //Will hold the incoming character from the Serial Port.If the command becomes bigger than 8 bits, try use char16_t
byte buffer_pos=0;

/*-----( Declare Constants )-----*/
#define RELAY_ON 0
#define RELAY_OFF 1

/*-----( Declare variables )-----*/
#define Relay_1  8  // Arduino Digital I/O pin number
#define Relay_2  7
#define Relay_3  6
#define Relay_4  5

// the setup routine runs once when you press reset:
void setup() {                

  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led13, OUTPUT);
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT);  
  pinMode(Relay_4, OUTPUT);  

  digitalWrite(led, LOW);  // Set led to LOW
  digitalWrite(led13, LOW);  // Set led to LOW

    //-------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF); 

  Serial.begin(19200); // set the baud rate
  SIM900.begin(19200); // for GSM shield
  delay(20000);  // give time to log on to network.
  Serial.println("setup Section");
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.println("AT+CNMI=2,2,0,0,0\r"); 
  SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100); 
  //digitalWrite(led, LOW);  // Set led to LOW
  //digitalWrite(led13, LOW);  // Set led to LOW
  // Serial.println("AT+CMGD=1,4");  //Delete all SMS in box
}

void sendSMS(byte led_status){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+XXXXXXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  if (led_status==0)
  {
    SIM900.println( " LIGHT STATUS: OFF");
  }
  else
  {
    SIM900.println( " LIGHT STATUS: ON");
  }
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

void sendSMSFAULT(){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+2XXXXXXXXXXXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  SIM900.println( " SORRY! YOU ARE NOT ALLOWED TO USE THE SYSTEM");
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

// the loop routine runs over and over again forever:
void loop() {
  if (Serial.available()>0)
  {
    incoming_char=Serial.read();
    buffer[buffer_pos]=incoming_char;
    buffer_pos++;
    if (buffer_pos==8) // Already incremented
    {
      //Print it out
      buffer[buffer_pos]='\0';
      Serial.write(buffer);
      Serial.println();
      if (strcmp(buffer,secret_code)==0)
      {   
        digitalWrite(led, LOW);
        digitalWrite(Relay_1, LOW);// set the Relay OFF
        delay(1000);              // wait for a second
      }
      buffer_pos=0;

      if (strcmp(buffer,secret_code1)==0)
      {   
        digitalWrite(led, HIGH);
        digitalWrite(Relay_1, HIGH);// set the Relay ON
        delay(1000);              // wait for a second
      }
      buffer_pos=0;

      if (strcmp(buffer,secret_code2)==0)
      {   
        digitalRead(led);
        led_status=digitalRead(led);
        Serial.print(led_status);  // prints status on serial terminal
        sendSMS(led_status);           // wait for a second
      }
      buffer_pos=0;
    }
  }
}

Hi Dan,

I used the above code and the code is not turning ON/OFF the LED. I have sent the correct codes but with no effect. Any ideas what I'm doing wrong?

Also, in arduino is there a way of seeing where the code is failing, i.e. DEBUG mode or something?

#include <SoftwareSerial.h>

SoftwareSerial SIM900(2, 3); // RX, TX

// Pin 8 has an LED connected on most Arduino boards.
int led = 8;
int led13 = 13;
int led_status = 0;     // variable to store the led status
char buffer[9]; // eight char plus null terminator
char secret_code[] = "?20!4#a0"; 
char secret_code1[] = "?20!4#a1";
char secret_code2[] = "?20!4#aS";
char incoming_char=0; //Will hold the incoming character from the Serial Port.If the command becomes bigger than 8 bits, try use char16_t
byte buffer_pos=0;

/*-----( Declare Constants )-----*/
#define RELAY_ON 0
#define RELAY_OFF 1

/*-----( Declare variables )-----*/
#define Relay_1  8  // Arduino Digital I/O pin number
#define Relay_2  7
#define Relay_3  6
#define Relay_4  5

// the setup routine runs once when you press reset:
void setup() {                

  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(led13, OUTPUT);
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT);  
  pinMode(Relay_4, OUTPUT);  

  digitalWrite(led, LOW);  // Set led to LOW
  digitalWrite(led13, LOW);  // Set led to LOW

    //-------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF); 

  Serial.begin(19200); // set the baud rate
  SIM900.begin(19200); // for GSM shield
  delay(20000);  // give time to log on to network.
  Serial.println("setup Section");
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.println("AT+CNMI=2,2,0,0,0\r"); 
  SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100); 
  //digitalWrite(led, LOW);  // Set led to LOW
  //digitalWrite(led13, LOW);  // Set led to LOW
  // Serial.println("AT+CMGD=1,4");  //Delete all SMS in box
}

void sendSMS(byte led_status){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+XXXXXXXXXXXXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  if (led_status==0)
  {
    SIM900.println( " LIGHT STATUS: OFF");
  }
  else
  {
    SIM900.println( " LIGHT STATUS: ON");
  }
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

void sendSMSFAULT(){               //SEND SMS

  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"XXXXXXXXXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  SIM900.println( " SORRY! YOU ARE NOT ALLOWED TO USE THE SYSTEM");
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(5000);     // give module time to send SMS  
}

// the loop routine runs over and over again forever:
void loop() {
  if (SIM900.available()>0)
  {
    incoming_char=SIM900.read();
    buffer[buffer_pos]=incoming_char;
    buffer_pos++;
    if (buffer_pos==8) // Already incremented
    {
      //Print it out
      buffer[buffer_pos]='\0';
      SIM900.write(buffer);
      SIM900.println();
      if (strcmp(buffer,secret_code)==0)
      {   
        digitalWrite(led, LOW);
        digitalWrite(Relay_1, LOW);// set the Relay OFF
        delay(1000);              // wait for a second
      }
      buffer_pos=0;

      if (strcmp(buffer,secret_code1)==0)
      {   
        digitalWrite(led, HIGH);
        digitalWrite(Relay_1, HIGH);// set the Relay ON
        delay(1000);              // wait for a second
      }
      buffer_pos=0;

      if (strcmp(buffer,secret_code2)==0)
      {   
        digitalRead(led);
        led_status=digitalRead(led);
        SIM900.print(led_status);  // prints status on serial terminal
        sendSMS(led_status);           // wait for a second
      }
      buffer_pos=0;
    }
  }
}

The usual way to debug a program is to use Serial.println() to print out the value of variables of interest, and to indicate that program execution has reached to a particular point.

Serial.println("Got to stage 7");

If you are going to put them in a piece of code that executes rapidly then temporarily add a delay(1000); just to slow it down so you can see what is happening. Don't forget to take it out afterwards!

Critique? Of you most recent code:

  SIM900.print("AT+CLIP=1\r"); // turn on caller ID notification

Being a little ambitious aren't we? We haven't even got the code working. Don't add stuff that you don't need. Just for curiosity, what are you expecting this command to do?

      SIM900.write(buffer);
      SIM900.println();

Why are you sending it to the SIM900? It would be of more use sending it to the serial monitor to tell us what is going on.

        digitalRead(led);

Read the pin, but don't do anything with it? And then read it again but save the result, which is what you should be doing to start with.

   SIM900.print(led_status);  // prints status on serial terminal
   sendSMS(led_status);           // wait for a second

Again, perhaps it would be better to send the led_status to Serial, not the SIM900. It doesn't care. And with both these lines, the comments don't match what is really happening. It may not matter right now, but you'll wonder what you were trying to do when you read them in three months time. Personally I comment a block of code rather than individual lines unless it really warrants it.

However, I've done a hatchet job on your code, partially because the modem I have to hand uses pins 7 & 8. I've put some debug comments in so you can see what is happening. It does work, but it only works once! I'll leave it to you to figure it out why.

#include <SoftwareSerial.h>

SoftwareSerial SIM900(7,8); // RX, TX

int led13 = 13;
char buffer[9]; // eight char plus null terminator
char secret_code[] = "20!4#a0"; 
char incoming_char=0;
byte buffer_pos=0;

void setup() 
{                
  pinMode(led13, OUTPUT);
  digitalWrite(led13, LOW);  // Set led to LOW

  Serial.begin(19200); // set the baud rate
  SIM900.begin(19200); // for GSM shield
  delay(20000);  // give time to log on to network.
  SIM900.print("ATE0\r");
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.println("AT+CNMI=2,2,0,0,0\r"); 
  delay(100); 
  Serial.println("Finished Setup Section");
}

void sendSMS(byte led_status)               //SEND SMS (Isn't the clue in the function name?)
{
  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+447751xxxxxx\"");  // recipient's mobile number, in international format
  delay(1000);
  if (led_status==0)
  {
    SIM900.println( " LIGHT STATUS: OFF");
  }
  else
  {
    SIM900.println( " LIGHT STATUS: ON");
  }
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  Serial.println("Message sent");
  delay(5000);     // give module time to send SMS  
}

void loop() 
{
  if (SIM900.available()>0)
  {
    Serial.println("Reading incoming data");
    incoming_char=SIM900.read();
    if (incoming_char=='?')
    {
      Serial.println("Got a ?");
      delay(100);
      while (SIM900.available())
      {
        delay(100);
        incoming_char=SIM900.read();
        buffer[buffer_pos]=incoming_char;
        buffer_pos++;

        if (buffer_pos==7) // Already incremented
        {
          //Print it out
          buffer[buffer_pos]='\0';

          Serial.write(buffer);
          Serial.println();
          if (strcmp(buffer,secret_code)==0)
          { 
            Serial.println("It's a match!");  
            digitalWrite(led13, HIGH);
            int led_status=digitalRead(led13);
            Serial.print ("LED status = ");
            Serial.println(led_status);  // prints status on serial terminal
            sendSMS(led_status);

            delay(1000);              // wait for a second
          }
          buffer_pos=0;
        }
      }
    }
  }
}

And it's not intended to be an example of good programming style!

Hi Dan,

Thanks for your comments - I will keep in mind going forward. Thank you also for the code you've sent, i have also tested on my modem and Led13 turns ON and STATUS sent upon receiving the code ?20!4#a0.

When u say it only works once, you mean the that the Led13 is turned ON once and the STATUS is sent once, correct?

This would be because the led13 is already ON if you try and resend the code again, so there will be no need to turn it ON again and the sendsms function will not run...Am i correct?

I will modify the code to include other secret_codes to be able to turn OFF and query the STATUS of the led

There is nothing in the code that would reject a second instance of 'Turn it on'. Send the SMS a second time, and watch the results in Serial Monitor.

Hi Dan,

I have modified the code to use a relay to turn ON/OFF and get the STATUS of the LED connect via breadboard. The code seems to intermittently work. May you kindly have a look at the below code:

Unfortunately, I cannot see why the 2nd the code will not run :frowning:

#include <SoftwareSerial.h>

SoftwareSerial SIM900(2,3); // RX, TX

int pin8 = 8;
int led13 = 13;
char buffer[9]; // eight char plus null terminator
char secret_code[] = "20!4#a1";
char secret_code1[] = "20!4#a0";
char secret_code2[] = "20!4#aS";
char incoming_char=0;
byte buffer_pos=0;
/*-----( Declare Constants )-----*/
#define RELAY_ON 1
#define RELAY_OFF 0

/*-----( Declare variables )-----*/
#define Relay_1  8  // Arduino Digital I/O pin number
#define Relay_2  7
#define Relay_3  6
#define Relay_4  5

void setup()
{               
  pinMode(pin8, OUTPUT);
  pinMode(led13, OUTPUT);
  digitalWrite(led13, LOW);
  digitalWrite(pin8, LOW);  // Set led to LOW

    pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT);  
  pinMode(Relay_4, OUTPUT);

  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF);

  Serial.begin(19200); // set the baud rate
  SIM900.begin(19200); // for GSM shield
  delay(20000);  // give time to log on to network.
  SIM900.print("ATE0\r");
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.println("AT+CNMI=2,2,0,0,0\r");
  delay(100);
  Serial.println("Finished Setup Section");
}

void sendSMS(byte led_status)               //SEND SMS (Isn't the clue in the function name?)
{
  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
  SIM900.println("AT + CMGS = \"+2XXXXXXX\"");  // recipient's mobile number, in international format
  delay(1000);
  if (led_status==0)
  {
    SIM900.println( " LIGHT STATUS: OFF");
  }
  else
  {
    SIM900.println( " LIGHT STATUS: ON");
  }
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000);
  SIM900.println();
  Serial.println("Message sent");
  delay(5000);     // give module time to send SMS 
}

void loop()
{
  if (SIM900.available()>0)
  {
    Serial.println("Reading incoming data");
    incoming_char=SIM900.read();
    if (incoming_char=='?')
    {
      Serial.println("Got a ?");
      delay(100);
      while (SIM900.available())
      {
        delay(100);
        incoming_char=SIM900.read();
        buffer[buffer_pos]=incoming_char;
        buffer_pos++;

        if (buffer_pos==7) // Already incremented
        {
          //Print it out
          buffer[buffer_pos]='\0';

          Serial.write(buffer);
          Serial.println();
          if (strcmp(buffer,secret_code)==0)
          {
            Serial.println("It's a match!"); 
            digitalWrite(pin8, HIGH);
            int led_status=digitalRead(pin8);
            Serial.print ("LED status = ");
            Serial.println(led_status);  // prints status on serial terminal
            sendSMS(led_status);

            delay(1000);              // wait for a second
          }
          buffer_pos=0;
          if (strcmp(buffer,secret_code1)==0)
          {
            Serial.println("It's a match!"); 
            digitalWrite(pin8, LOW);
            int led_status=digitalRead(pin8);
            Serial.print ("LED status = ");
            Serial.println(led_status);  // prints status on serial terminal
            sendSMS(led_status);

            delay(1000);              // wait for a second
          }
          buffer_pos=0;
          if (strcmp(buffer,secret_code2)==0)
          {
            Serial.println("It's a match!"); 
            int led_status=digitalRead(pin8);
            Serial.print ("LED status = ");
            Serial.println(led_status);  // prints status on serial terminal
            sendSMS(led_status);

            delay(1000);              // wait for a second
          }
          buffer_pos=0;
        }
      }
    }
  }
}

I know why it's not working. I left that for you to figure out. I've taken the sketch I posted earlier and added even more debug output to assist you.

#include <SoftwareSerial.h>

SoftwareSerial SIM900(7,8); // RX, TX

int led13 = 13;
char buffer[9]; // eight char plus null terminator
char secret_code[] = "20!4#a0"; 
char incoming_char=0; //Will hold the incoming character from the Serial Port.If the command becomes bigger than 8 bits, try use char16_t
byte buffer_pos=0;

void setup() {                

  pinMode(led13, OUTPUT);
  digitalWrite(led13, LOW);  // Set led to LOW

    Serial.begin(19200); // set the baud rate
  SIM900.begin(19200); // for GSM shield
  delay(5000);  // give time to log on to network.
  SIM900.print("ATE1\r");
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.println("AT+CNMI=2,2,0,0,0\r"); 
  delay(100); 
  Serial.println("Finished Setup Section");
}

void sendSMS(byte led_status){               //SEND SMS

  //SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  //delay(1000);
  SIM900.println("AT + CMGS = \"+447751xxxxxx\"");  // recipient's mobile number, in international format
  delay(1000);
  if (led_status==0)
  {
    SIM900.println( " LIGHT STATUS: OFF");
  }
  else
  {
    SIM900.println( " LIGHT STATUS: ON");
  }
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  Serial.println("Message sent");
  delay(5000);     // give module time to send SMS  
}

void loop() 
{
  if (SIM900.available()>0)
  {
    Serial.print("Reading incoming data: ");
    incoming_char=SIM900.read();
    Serial.print(int(incoming_char));
    Serial.print(" ");
    Serial.println(incoming_char);
    if (incoming_char=='?')
    {
      Serial.println("Got a ?");
      delay(100);
      while (SIM900.available())
      {
        delay(100);
        incoming_char=SIM900.read();

        Serial.print("Reading incoming data in loop: Buffer_pos = ");
        Serial.print(buffer_pos);
        Serial.print(" ");
        Serial.print(int(incoming_char));
        Serial.print(" ");
        Serial.println(incoming_char);


        buffer[buffer_pos]=incoming_char;
        buffer_pos++;

        if (buffer_pos==7) // Already incremented
        {
          //Print it out
          buffer[buffer_pos]='\0';

          Serial.write(buffer);
          Serial.println();
          if (strcmp(buffer,secret_code)==0)
          { 
            Serial.println("It's a match!");  
            digitalWrite(led13, HIGH);
            int led_status=digitalRead(led13);
            Serial.print ("LED status = ");
            Serial.println(led_status);  // prints status on serial terminal
            sendSMS(led_status);

            delay(1000);              // wait for a second
          }
          buffer_pos=0;
        }
      }
    }
  }
}

Thanks, I further look into this.

Hi Dan,

I'm very confused as what to look for now :~ =( I havn't been able to figure out why this code wouldn't run the 2nd time. Below was the output i saw in the serial terminal

Finished Setup Section
Reading incoming data: 13 

Reading incoming data: 10 

Reading incoming data: 62 >
Reading incoming data: 32  
Reading incoming data: 13 

Reading incoming data: 10 

Reading incoming data: 62 >
Reading incoming data: 32

Any other advise?

Send a text/SMS and watch what happens to buffer_pos. You may need to send more than one to fully appreciate what is happening.

Once you have worked out what the problem is then there are a few different ways to resolve it. That choice is up to you.