problem facing in GSM900A Module with Arduino UNO

cattledog:
I think that for some reason, which I don't understand, the outgoing message is being received as well as sent.

Do you see "Switch was turned ON " as a received message with this piece of your code?

textMessage = GPRS.readString();

Serial.print(textMessage);




Is your phone echoing anything back when it receives the sent message?

If the issue is the phone echo, that can be modified.

If the issue is some sort of self receipt of the outgoing message, I think there is a work around if you change the message in sendSMS().

#Echoing means?

#Echoing means?

Phone sending back a message (perhaps what it received) to confirm that the message was received.

cattledog:
Phone sending back a message (perhaps what it received) to confirm that the message was received.

Sir,

msg delivery report enabled on the GSM sim.Now i disabled,but no improvement.

but Sir,its become success ;D ;D :stuck_out_tongue_closed_eyes: ..... after using small letter "on" and off" .

sir now i am inclueding one or more function that is Relaystate.when i send the txt msg "state" to

GSM,GSM will acknowledge the current status(ON/OFF) of relay through reply msg'

#include <SoftwareSerial.h>

SoftwareSerial GPRS(10, 11);
String textMessage;
String relayState = "HIGH";

const int relay = 4;
const uint8_t switchPin = 2;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState = switchOff;
bool newState;
int joystick[1];
void setup()
{
  pinMode(relay, OUTPUT);
  /*digitalWrite(relay, HIGH);*/
  pinMode ( switchPin, INPUT_PULLUP );
  GPRS.begin(9600);
  Serial.begin(9600);
  GPRS.println("AT+CMGF=1");
  delay(500);
  GPRS.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
}

void loop()
{
  //while (GPRS.available()) {
  //  Serial.write(GPRS.read());
  // }
  joystick[0] = digitalRead(switchPin);
  newState = joystick[0];
  delay(500);
  if (newState == switchOn and lastState == switchOff)
  {
    Serial.println("Switch was turned ON ");
    sendSMS(); //try with and without an outgoing message
  }

  lastState = newState;
  delay(500);
  if (GPRS.available() > 0) {
    textMessage = GPRS.readString();
    Serial.print(textMessage);
    recvSMS();
    delay(10);
  }
}
void recvSMS() {
  if (textMessage.indexOf("on") >= 0) {
    // Turn on relay and save current state
    digitalWrite(relay, HIGH);
    relayState = "on";
    Serial.println("Relay set to ON");
    textMessage = "";
  }
  if (textMessage.indexOf("off") >= 0) {
    // Turn off relay and save current state
    digitalWrite(relay, LOW);
    relayState = "off"; 
    Serial.println("Relay set to OFF");
    textMessage = "";
  }
if(textMessage.indexOf("state")>=0){
    String message = "relay is " + relayState;
    sendSMS(message);
    Serial.println("relay state resquest");
    textMessage = "";
}
}
void sendSMS() {
  Serial.println("Switch was turned ON ");
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character
  delay(500);
}
void sendSMS(String  message){
  // AT command to set SIM900 to SMS mode
  if (GPRS.available() > 0) {
    textMessage = GPRS.readString();
   Serial.print(textMessage);}
  
  GPRS.print("AT+CMGF=1\ "); 
  delay(100);
  GPRS.println("AT+CMGS=\"+917987553768\"\ "); 
  delay(1000);
   GPRS.println(message); 
  delay(1000);
  // End AT command with a ^Z, ASCII code 26
  GPRS.write( 0x1a ); 
  delay(100);
  GPRS.println();
  delay(5000);
}

But GSM not sending reply.

serial monitor showing" ERROR"

CMT: "+917987553768","","18/12/20,00:57:55+22"
state
relay state resquest
AT+CMGF=1 AT+CMGS="+917987553768" 

ERROR
relay is HIGH


But GSM not sending reply.

Is this function successful in sending a message to the phone?

void sendSMS() {
  Serial.println("Switch was turned ON ");
  GPRS.println("AT+CMGS=\"+917987553768\"");
  delay(500);
  GPRS.println ("Switch was turned ON ");
  GPRS.write( 0x1a ); // ctrl+Z character
  delay(500);
}

But this one is not?

void sendSMS(String  message){
  // AT command to set SIM900 to SMS mode
  if (GPRS.available() > 0) {
    textMessage = GPRS.readString();
   Serial.print(textMessage);}
  
  GPRS.print("AT+CMGF=1\ "); 
  delay(100);
  GPRS.println("AT+CMGS=\"+917987553768\"\ "); 
  delay(1000);
   GPRS.println(message); 
  delay(1000);
  // End AT command with a ^Z, ASCII code 26
  GPRS.write( 0x1a ); 
  delay(100);
  GPRS.println();
  delay(5000);  
}

If that is the case, then make them identical except for the parameter. First, remove the reading routine from the sending function, it does not belong there. Then, make the syntax identical between the two functions. You need to look carefully, but you have made subtle errors. Try

void sendSMS(String  message){
  // AT command to set SIM900 to SMS mode
  //if (GPRS.available() > 0) {
  //  textMessage = GPRS.readString();
 //  Serial.print(textMessage);}
  
 // GPRS.print("AT+CMGF=1\ "); 
 // delay(100);
 // GPRS.println("AT+CMGS=\"+917987553768\"\ "); 
   GPRS.println("AT+CMGS=\"+917987553768\""); //note the small difference from above
   //delay(1000);
   delay(500);
  GPRS.println(message); 
  delay(1000);
  // End AT command with a ^Z, ASCII code 26
  GPRS.write( 0x1a ); 
  //delay(100);
 // GPRS.println();
  //delay(5000);
  delay(500);
}

Cleaned up, it looks like this. Look carefully for any differences I may have missed.

void sendSMS(String  message) {
  Serial.println(message);
  GPRS.println("AT+CMGS=\"+917987553768\""); 
  delay(500);
  GPRS.println(message);
  GPRS.write( 0x1a );
  delay(500);
}
 void sendSMS(String  message) {
  Serial.println(message);
  GPRS.println("AT+CMGS=\"+917987553768\""); 
  delay(500);
  GPRS.println(message);
  GPRS.write( 0x1a );
  delay(500);
}

after changing its ,working properly.

"i want to operate the relay only when GSM receives sms from valid sender" is it possible?

I didn't get any relevant point for adding the valid sender in gsm module

after changing its ,working properly.

Good news. I hope you learned a lesson from this. Programming involves close attention to detail. Computers are unforgiving and "stupid". If you don't tell then exactly, and precisely, what they expect, they won't do what you tell them. You would do better to slow down a bit, think things through, and be more careful in the future.

"i want to operate the relay only when GSM receives sms from valid sender" is it possible?

I m not familiar with the GSM module, and if there are an possible settings for "valid sender".

You can certainly determine the phone number which sent the incoming message, and test it against a list of valid numbers. An alternative might be to add a password to the message.

cattledog:
Good news. I hope you learned a lesson from this. Programming involves close attention to detail. Computers are unforgiving and "stupid". If you don't tell then exactly, and precisely, what they expect, they won't do what you tell them. You would do better to slow down a bit, think things through, and be more careful in the future.

I m not familiar with the GSM module, and if there are an possible settings for "valid sender".

You can certainly determine the phone number which sent the incoming message, and test it against a list of valid numbers. An alternative might be to add a password to the message.

Sir,
i am not very much know about language C++,Ihave listening through this platform with the help of expert people like you.Once again thank you very much for your cooperation and valuable advice.this

My project totally held up due to the Valid sender problem.. could u please anyone can help me.

cattledog:
Good news. I hope you learned a lesson from this. Programming involves close attention to detail. Computers are unforgiving and "stupid". If you don't tell then exactly, and precisely, what they expect, they won't do what you tell them. You would do better to slow down a bit, think things through, and be more careful in the future.

I m not familiar with the GSM module, and if there are an possible settings for "valid sender".

You can certainly determine the phone number which sent the incoming message, and test it against a list of valid numbers. An alternative might be to add a password to the message.

Sir,

now i add a valid sender function in my program with the help of youtube.

codes showing below

#include <SoftwareSerial.h>
SoftwareSerial GPRS(10, 11); // RX, TX

enum _parseState {
  PS_DETECT_MSG_TYPE,

  PS_IGNORING_COMMAND_ECHO,

  PS_READ_CMTI_STORAGE_TYPE,
  PS_READ_CMTI_ID,

  PS_READ_CMGR_STATUS,
  PS_READ_CMGR_NUMBER,
  PS_READ_CMGR_SOMETHING,
  PS_READ_CMGR_DATE,
  PS_READ_CMGR_CONTENT,
  
};

byte state = PS_DETECT_MSG_TYPE;
String textMessage;
String relayState = "LOW";

const int relay = 4;
char buffer[82];
byte pos = 0;

const uint8_t switchPin = 3;
const bool switchOn  = false;     // using INPUT_PULLUP
const bool switchOff = true;
bool lastState = switchOff;
bool newState;
int joystick[1];
int lastReceivedSMSId = 0;
boolean validSender = false;

void resetBuffer() {
  memset(buffer, 0, sizeof(buffer));
  pos = 0;
}

void setup()
{
  GPRS.begin(9600);
  Serial.begin(9600);

  // Set as appropriate for your case
  lastState = !digitalRead(switchPin);
  pinMode ( switchPin, INPUT_PULLUP );
  pinMode(2, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(6, OUTPUT);
  digitalWrite(2, HIGH);
  digitalWrite(4, HIGH);
   digitalWrite(6, HIGH);
  for (int i = 1; i <= 15; i++) {
    GPRS.print("AT+CMGD=");
    GPRS.println(i);
    delay(200);

    // Not really necessary but prevents the serial monitor from dropping any input
    while(GPRS.available()){ 
      Serial.write(GPRS.read());
  }
 }
}

void loop()
{
  joystick[0] = digitalRead(switchPin);
  newState = joystick[0];
  delay(5000);
  if (newState == switchOn and lastState == switchOff)
  { 
    sendSMS(); 
  }
  lastState = newState;
    delay(500);
    while(GPRS.available()) {
    byte b = (GPRS.read());
    parseATText(b);
    }
}

void parseATText(byte b) {

  buffer[pos++] = b;
  switch (state) {
  case PS_DETECT_MSG_TYPE: 
    {
      if ( b == '\n' )
        resetBuffer();
      else {        
        if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
          state = PS_IGNORING_COMMAND_ECHO;
        }
        else if ( pos == 6 ) {
          
          if ( strcmp(buffer, "+CMTI:") == 0 ) {
            Serial.println("Received CMTI");
            state = PS_READ_CMTI_STORAGE_TYPE;
          }
          else if ( strcmp(buffer, "+CMT: ") == 0   ) {  
            Serial.println("Received CMGR");            
            state = PS_READ_CMGR_NUMBER;//PS_READ_CMGR_STATUS;
          }
          resetBuffer();
        }
      }
    }
    break;

  case PS_IGNORING_COMMAND_ECHO:
    {
      if ( b == '\n' ) {
        state = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

   case PS_READ_CMTI_STORAGE_TYPE:
    {
      if ( b == ',' ) {
        Serial.print("SMS storage is ");
        Serial.println(buffer);
        state = PS_READ_CMTI_ID;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMTI_ID:
    {
      if ( b == '\n' ) {
        lastReceivedSMSId = atoi(buffer);
        Serial.print("SMS id is ");
        Serial.println(lastReceivedSMSId);

        GPRS.print("AT+CMGR=");
        GPRS.println(lastReceivedSMSId);
        //delay(500); don't do this!

        state = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_NUMBER:
    {
      if ( b == ','  ) {
        

        // Uncomment these two lines to check the sender's cell number
       validSender = false;
       if ( strcmp(buffer,"\"+91798755378\",") == 0 ){
       
        validSender = true;
        Serial.print("CMGR number: ");
        Serial.println(buffer);
        state = PS_READ_CMGR_SOMETHING;
        resetBuffer();}
        else if ( strcmp(buffer,"\"+91799964539\",") == 0 ){
        validSender = true;
        Serial.print("CMGR number: ");
        Serial.println(buffer);
        state = PS_READ_CMGR_SOMETHING;
        
        resetBuffer();}
      }
    }
    break;

  case PS_READ_CMGR_SOMETHING:
    {
      if ( b == ',' ) {
        Serial.print("CMGR something: ");
        Serial.println(buffer);
        state = PS_READ_CMGR_DATE;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_DATE:
    {
      if ( b == '\n' ) {
        Serial.print("CMGR date: ");
        Serial.println(buffer);
        state = PS_READ_CMGR_CONTENT;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_CONTENT:
    {
      //delay(3000);
      if ( b == '\n' ) {
         
        Serial.print("CMGR content: ");
        Serial.print(buffer);
      
       parseSMSContent();

        GPRS.print("AT+CMGD=");
        GPRS.println(lastReceivedSMSId);
      // delay(3000);// don't do this!

        state = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;
  }
}
void parseSMSContent()
{
  char* ptr = buffer;

  if ( strlen(ptr) >= 4 ) {

    if ( ptr[0] == 'v'  ) {
      if ( ptr[1] == 'r' )
      if ( ptr[2] == 'm' )
      if (digitalRead(switchPin)==LOW)
        digitalWrite(2, LOW);
        relayState = "on";
        Serial.println("Relay set to ON"); 
        
        }
    if ( ptr[0] == 'a'  ) {
      if ( ptr[1] == 'r' )
      if ( ptr[2] == 'a' )
        
        digitalWrite(2, HIGH);
        relayState = "off";
        Serial.println("Relay set to OFF");
    }
    
     if  ( ptr[0] == 'd' ) { 
     if ( ptr[1] == 'a' )
       if ( ptr[2] == 'z' )
       digitalWrite(4, HIGH);
       String message = "relay is " + (relayState);
      Serial.println("relay state resquest");
      GPRS.println("AT+CMGS=\"+91798755378\""); 
      delay(1000);
      GPRS.println(message);
      GPRS.write( 0x1a );
      delay(500);
      }
       ptr += 4;
      }
 }


void sendSMS()
{
  Serial.println("Switch was turned ON ");
  GPRS.println("AT+CMGS=\"+91798755768\"");
  delay(500);
  GPRS.println ("Switch was turned ON");
  GPRS.write( 0x1a ); // ctrl+Z character
  delay(500);
}

its working properly...

some problem also be there, that is if i have send the sms other than pre determined texts("ara","vrm","daz") to GSM module its gets hang and not responding further SMS. Otherwise its working

some problem also be there, that is if i have send the sms other than pre determined texts("ara","vrm","daz") to GSM module its gets hang and not responding further SMS.

I can not confirm you issue. When I test your function parseSMSContent() it is passing control back and not hanging. Please confirm with Serial print that you are getting back to state = PS_DETECT_MSG_TYPE; and that you can receive a new message.

I'm not sure the problem is where you think it is. I am not comfortable with the entire design of the program. I believe you will be far better off to receive a complete message and then parse it, rather than doing the parsing "on the fly" as the message is received with a state machine.

If you comment out the call to parseSMSContent() can you receive further messages?
Can you receive multiple messages from the phone?
Can you receive multiple messages from a non valid number?

You never do anything with the valid sender state to prevent a not valid phone from making a command.

Here is the code I used to test parseSMS to verify the return with any message.

//char buffer[] = "ara\n";
//char buffer[]= "vrm\n";
//char buffer[] = "daz\n";
char buffer[] = "xyz\n";
//char buffer[] = "xy";
//char buffer[] = "abcdefg";
String relayState = "LOW";
const int relay = 4;
const uint8_t switchPin = 3;

void setup() {

  Serial.begin(115200);
  Serial.print(buffer);
}

void loop() {
  parseSMSContent();
  Serial.println("returned from parse function");
  delay(1000);
}

void parseSMSContent()
{
  char* ptr = buffer;

  if ( strlen(ptr) >= 4 ) {

    if ( ptr[0] == 'v'  ) {
      if ( ptr[1] == 'r' )
        if ( ptr[2] == 'm' )
          if (digitalRead(switchPin) == LOW)
            digitalWrite(2, LOW);
      relayState = "on";
      Serial.println("Relay set to ON");
    }
    if ( ptr[0] == 'a'  ) {
      if ( ptr[1] == 'r' )
        if ( ptr[2] == 'a' )

          digitalWrite(2, HIGH);
      relayState = "off";
      Serial.println("Relay set to OFF");
    }

    if  ( ptr[0] == 'd' ) {
      if ( ptr[1] == 'a' )
        if ( ptr[2] == 'z' )
          digitalWrite(4, HIGH);
      String message = "relay is " + (relayState);
      Serial.println("relay state resquest");
      Serial.println("AT+CMGS=\"+91798755378\"");
      delay(1000);
      Serial.println(message);
      Serial.write( 0x1a );
      delay(500);
    }
    ptr += 4;
  }
}