Arduino doesn't respond to SMS after first SMS(SIM800L)

Hello,
posting after a long time so apologies for any mistake.
here is a code of my project which is about a personal gps tracker. But its in testing phase now, so i am using a led to mimic a task which has to be done after parsing SMS from SIM800L module. The problem is after only the "led on" command works but "led off" doesn't. I am unable to figure out if there is an error in my test code or something else.

#include <SoftwareSerial.h>
#include <Keypad.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

SoftwareSerial sim800(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32(Original) and for some 128x64 chinese clones
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO, NANO, PRO MINI:     A4(SDA), A5(SCL)

#define LED_PIN 13

#define BUFFER_SIZE   64       // incoming data buffer size
char bufferData[BUFFER_SIZE];   // holds the char data
char bufferIndex;               // holds the position of the char in the buffer
char sender_cmd[10];     // holds the specific command when a new SMS is received
String sender_num = "xxxxxxxxxxx";

bool CMD_OK = false;    // CMD is for processing the parsing the sms command
int cmd_pos_index = 0;
int cmd_pos_count = 0;

float gpslat, gpslon;

boolean livetrack_status = false;
boolean alarm_status = false;
boolean led_status = false;


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// 'gps', 128x64px
const unsigned char hypertraklogo [] PROGMEM = {
  
};

void setup()
{
  sim800.begin(9600);//start gsm serial communication
  delay(1000);
  Serial.begin(115200);
  Serial.println("Initializing...");
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, led_status);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
  display.clearDisplay();//Prevents Adafruit splash screen
  display.drawBitmap(0, 0,  hypertraklogo, 128, 64, WHITE);//This function draws custom logo
  display.display();
  delay(7000);//wait 5-10 secs for gsm to register to a network
  // Clear the buffer
  display.clearDisplay();

  initializeGSM();
  memset(bufferData, 0, sizeof(bufferData)); // Initialize the string
  bufferIndex = 0;
  Serial.println("Setup done");

}

void loop()
{
  manageGSM();
  delay(500);
}


void initializeGSM() // Set to receive mode
{
  sim800.println("AT\r"); //Once the handshake test is successful, it will back to OK
  updateSerial();
  sim800.println("AT+CMGF=1\r");//Configuring SMS as TEXT mode
  updateSerial();
  sim800.println("AT+CNMI=1,2,0,0,0\r");// Decides how newly arrived SMS messages should be handled
  updateSerial();
  sim800.println("AT&W");
  updateSerial();

}

void manageGSM()
{
  while (sim800.available() > 0)
  {
    bufferData[bufferIndex] = sim800.read();
    // Find the string "CMD:"
    //    if found, parse the command for processing
    if ( (bufferData[bufferIndex - 3] == 'C') &&
         (bufferData[bufferIndex - 2] == 'M') &&
         (bufferData[bufferIndex - 1] == 'D') &&
         (bufferData[bufferIndex] == ':')      )
    {
      //Serial.println("CMD");
      CMD_OK = true;
      memset(sender_cmd, 0, sizeof(sender_cmd));
      cmd_pos_index = bufferIndex;  // get the position
      cmd_pos_count = 0;            // reset pos counter
    }
    if ( ( (bufferIndex - cmd_pos_index) > 1 ) && (CMD_OK))
    {
      if (bufferData[bufferIndex] == '<')
      {
        //Serial.println(sender_cmd);
        processCommand();
        CMD_OK = false; // done
        break;
      }
      else
      {
        sender_cmd[cmd_pos_count] =  bufferData[bufferIndex];
        cmd_pos_count++;
      }
    }
    bufferIndex++;
  }
  memset(bufferData, 0, sizeof(bufferData));    // Initialize the string
  bufferIndex = 0;
}

void processCommand()
{
  if      (strcmp(sender_cmd, "Led on") == 0)
  {
    led_status = true;
    sendSMS("LED On", sender_num);
  }
  else if (strcmp(sender_cmd, "Led off") == 0)
  {
    led_status = false;
    sendSMS("LED Off", sender_num);
  }
  digitalWrite(LED_PIN, led_status);
}
void sendSMS(String message, String mobile)
{
  sim800.println("AT+CMGF=1");                    //Sets the GSM Module in Text Mode
  delay(1000);
  sim800.println("AT+CMGS=\"" + mobile + "\"\r"); //Mobile phone number to send message
  updateSerial();
  sim800.println(message);                        // This is the message to be sent.
  updateSerial();
  sim800.println((char)26);                       // ASCII code of CTRL+Z to finalized the sending of sms
  updateSerial();
}
void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    sim800.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while (sim800.available())
  {
    Serial.write(sim800.read());//Forward what Software Serial received to Serial Port
  }
}

Here is the code. P.S- i have removed the custom logo code from here as it was exceeding 9000 characters limit.
Any help is appreciated

First thought...
While you’re in manageGSM(), you’re parsing for the CMD: far too frequently...
You’re already buffering the serial stream, why process it on every character received? Wait until a line-end (CR or LF) arrives, them search the buffer for the keywords you’re wanting (using strstr() or other c-string functions) then left-trim the string, and move on to the the rest of the buffer which should still be receiving characters.

While it’s related, but yet to be identified, I’ll almost guarantee you’re overrunning the 10 character buffer which will cause all sorts of unexpected behaviour. The actual size of the buffer can. e found through trial and error, but if you’ve guessed at 10, I’d start with 20 until you KNOW what you need.
Don’t forget the trailing CR & LF chars and the null. you can usually strip them as soon as you detect the line-end.

Putting some debug prints in - to keep an eye on the buffer index would help too.

always interesting!

lastchancename:
First thought...
While you’re in manageGSM(), you’re parsing for the CMD: far too frequently...
You’re already buffering the serial stream, why process it on every character received? Wait until a line-end (CR or LF) arrives, them search the buffer for the keywords you’re wanting (using strstr() or other c-string functions) then left-trim the string, and move on to the the rest of the buffer which should still be receiving characters.

While it’s related, but yet to be identified, I’ll almost guarantee you’re overrunning the 10 character buffer which will cause all sorts of unexpected behaviour. The actual size of the buffer can. e found through trial and error, but if you’ve guessed at 10, I’d start with 20 until you KNOW what you need.
Don’t forget the trailing CR & LF chars and the null. you can usually strip them as soon as you detect the line-end.

Putting some debug prints in - to keep an eye on the buffer index would help too.

always interesting!

I understood a little bit of what you said. A small example code or a code snippet would be really helpful. Also i tried changing the buffer to 20 but that resulted in the uno to loop forever showing "Initializing" repeatedly in serial monitor. If there is an easy way to parse the text messages from SIM800L, then please do suggest.
Thanks


This the format I receive my all SMS. Is there a simple way to parse and extract only the messages such as "Led off", "Hello" or "Livetrack"? I have been seeing multiple forum posts related to this but was not able to find an answer. So I decided to start from scratch, proceed later to other things in this project like 2x2keypad matrix switch and OLED Menu for my upcoming GPS Tracker project. Any help on "how to parse these SMS for obtaining message and doing a task according to it" is appreciated.

Here is the code for getting receiving the messages:

#include <SoftwareSerial.h>

//Create software serial object to communicate with SIM800L
SoftwareSerial mySerial(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(9600);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();

  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();
  mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
  updateSerial();

}

void loop()
{
  updateSerial();
}

void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while (mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}

Thanks

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.