Go Down

Topic: How let Shield reply to a SMS sent from mobile .(NOT in serial monitor) (Read 3785 times) previous topic - next topic

lelocchio84

Hi guys,
i am a kind newby in Arduino and i need assistence.
I would like that my Arduino Shield reply automatically to a specific SMS sent from mobile, not to Serial monitor, but direcly to a mobile device.
So means..

send  message from mobile -> check if the message its according to a specific string --> reply to it like "hello!".

Hope i make myself clear :)

Thanks in advance!!!  :)

Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial MySerial(7, 8);

char incoming_byte=0; // incoming message

void setup()
{
  Serial.begin(19200); // for serial monitor
  MySerial.begin(19200); // for GSM shield
  delay(10000);  // delay to network

  MySerial.print("AT+CMGF=1\r");  // SMS mode totext
  delay(100);
  MySerial.print("AT+CNMI=2,2,0,0,0\r"); //blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
}
void loop()
{
  if(MySerial.available() >0) // display any value to serial
  {
    incoming_byte=MySerial.read(); //Get from message
    Serial.print(incoming_byte); //Print the message to serial.
    /* no idea how to go forward */
      sendSMS(); // if diplay values from sms, should send sms.. but i cant compare in if to a string.
  }
}


void sendSMS()
{
  MySerial.println("AT + CMGS = \"+0000000\"");                                     // mobile number
  delay(100);
  MySerial.println("Hello!");        // message to send
  delay(100);
  MySerial.println((char)26);                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  MySerial.println();
  delay(100);                                     // give module time to send SM
}

 

dannable

Very generally:

Store incoming characters to a character array. At the end of the message compare that with what you are expecting. Then send appropriate response!

Simples!  ;)
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

lelocchio84


Good thinking. Still dont read the value from my SMS. Suggestions? :D

Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial MySerial(7, 8);

char incoming_byte[25]; // where to store
int incoming_byte_Index=0; // store the next empty space

void setup()
{
  Serial.begin(19200); // for serial monitor
  MySerial.begin(19200); // for GSM shield
  delay(10000);  // delay to network
  MySerial.print("AT+CMGF=1\r");  // SMS mode totext
  delay(100);
  MySerial.print("AT+CNMI=2,2,0,0,0\r"); //blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
}
void loop()
{
  if(MySerial.available() >0) // display any value to serial
  {
    incoming_byte[incoming_byte_Index]=MySerial.read(); //Array
    incoming_byte_Index++; //Index
    Serial.print(incoming_byte); //print to serial values
    }
    if(incoming_byte=="content"){ //if values in Serial are = "content" than sendSMS
      sendSMS(); // if diplay values from sms, should send sms.. but i cant compare in if to a string.
  }
}

void sendSMS()
{
  MySerial.println("AT + CMGS = \"+0000000\"");                                     // mobile number
  delay(100);
  MySerial.println("Hello!");        // message to send
  delay(100);
  MySerial.println((char)26);                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  MySerial.println();
  delay(100);                                     // give module time to send SM
}

dannable

Code: [Select]
if(incoming_byte=="content"){

What do you get if you send incoming_byte to Serial Monitor?
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

lelocchio84

Thats what i got.

AATAT+AT+CAT+CMAT+CMGAT+CMGFAT+CMGF=AT+CMGF=1AT+CMGF=1
AT+CMGF=1

AT+CMGF=1

AT+CMGF=1

OAT+CMGF=1

OKAT+CMGF=1

OK
AT+CMGF=1

OK
AT+CMGF=1

OK
AAT+CMGF=1

OK
ATAT+CMGF=1

OK
AT+AT+CMGF=1

OK
AT+CAT+CMGF=1

OK
AT+CNAT+CMGF=1

OK
AT+CNMAT+CMGF=1

OK
AT+CNMIAT+CMGF=1

OK
AT+CNMI=AT+CMGF=1

OK
AT+CNMI=2CAT+CMGF=1

OK
AT+CNMI=2,AT+CMGF=1

OK
AT+CNMI=2,2AT+CMGF=1

OK
AT+CNMI=2,2,AT+CMGF=1

OK
AT+CNMI=2,2,0èAT+CMGF=1

OK
AT+CNMI=2,2,0,AT+CMGF=1

OK
AT+CNMI=2,2,0,0AT+CMGF=1

OK
AT+CNMI=2,2,0,0,AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0
AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0

AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0

AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0

O€)AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0

OK€)AT+CMGF=1

OK
AT+CNMI=2,2,0,0,0


dannable

Which are the responses to the AT commands sent in setup(). You can turn the echo off (ATE=0) to tidy it up.

Ideally you should check the return message after each AT command in case of an error or other information. However, for the purposes of testing we'll skip that. Instead, at the end of setup(), read all the characters from MySerial to clear the buffer.

Once you have done that send it a SMS and see what happens (print out incoming_byte array).
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

lelocchio84

Got some progress :) ...
Now the message that i send its recognize from the arduino and publish on the Serial (print out_byte array).
Problem its not recognize the If condiction. So cannot start the function SendSMS();


Code: [Select]


#include <SoftwareSerial.h>
SoftwareSerial MySerial(7, 8);

char incoming_byte[25]; // where to store
int incoming_byte_Index=0; // store the next empty space
char cleanbuffer[20];
int index=0;

void setup()
{
  Serial.begin(19200); // for serial monitor
  MySerial.begin(19200); // for GSM shield
  delay(10000);  // delay to network
  MySerial.println("AT+CMGF=1\r");  // SMS mode totext
  delay(100);
  MySerial.println("AT+CNMI=2,2,0,0,0\r"); //blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
  MySerial.println("ATE=0"); //echo off
  delay(100);
  if(MySerial.available()>0){ //cleaning buffer
  cleanbuffer[index]=MySerial.read();
  index++;
  }
}
void loop()
{
  //if(MySerial.available() >0) // display any value to serial
  //{
   incoming_byte[incoming_byte_Index]=MySerial.read(); //Array
   incoming_byte_Index++; //Index
   Serial.print(incoming_byte); //print to serial values
    //}
    if(incoming_byte=="TEST"){ //if values in Serial are = "TEST" than sendSMS
      sendSMS(); // if display values from sms, should send sms..
}
}

void sendSMS()
{
  MySerial.println("AT + CMGS = \"+0000000000\"");        // mobile number
  delay(100);
  MySerial.println("Hello!");        // message to send
  delay(100);
  MySerial.println((char)26);                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  MySerial.println();
  delay(100);                                     // give module time to send SM
}


 


dannable

Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

lelocchio84

Tried. Same staff.. display the Message in Serial but does not go forward to compare the IF condiction. :smiley-confuse:

Code: [Select]

void loop()
{
  if(MySerial.available() >0) // display any value to serial
  {
   incoming_byte[incoming_byte_Index]=MySerial.read(); //Array
   incoming_byte_Index++; //Index
   Serial.println(incoming_byte); //print to serial values
    //}
    if(strstr(incoming_byte,"TEST")){ //if values in Serial are = "TEST" than sendSMS
    delay(100);
    incoming_byte_Index=0;
    sendSMS(); // if display values from sms, should send sms..
}
}
}

dannable

You still need to show the output you are getting, and all of your code. Is the buffer too small to hold all the message at once?

Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

lelocchio84

I have resized the array to 100 carachters. The thing "interesting" its when i am sending the SMS from my mobile , the Serial repeat some AT commands from setup(). If i am not mistaken Setup function should run only once as loop  :o . Take a look on Pictures Attached.

Code: [Select]


#include <SoftwareSerial.h>
SoftwareSerial MySerial(7, 8);

char incoming_byte[100]; // where to store
int incoming_byte_Index=0; // store the next empty space
char cleanbuffer[100];
int index=0;
int endindex=25;

void setup()
{
  Serial.begin(19200); // for serial monitor
  MySerial.begin(19200); // for GSM shield
  delay(10000);  // delay to network
  MySerial.println("AT+CMGF=1\r");  // SMS mode totext
  delay(100);
  MySerial.println("AT+CNMI=2,2,0,0,0\r"); //blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
  MySerial.println("ATE=0"); //echo off
  delay(150);
  MySerial.println("AT+CMGD=1,4"); // delete the messages
  if(MySerial.available()>0){ //"cleaning" buffer, just read all the values
  cleanbuffer[index]=MySerial.read();
  index++;
  }
}

void loop(){
  if(MySerial.available()>0) // display any value to serial
  {
   incoming_byte[incoming_byte_Index]=MySerial.read(); //Array
   incoming_byte_Index++; //Index
  Serial.println(incoming_byte); //print to serial values
    if(strstr(incoming_byte,"TEST")){ //if values in Serial are = "TEST" than sendSMS
     Serial.println(incoming_byte);  // print again the incoming byte
     sendSMS();
    incoming_byte_Index=0;
    }
}
}
 // if display values from sms, should send sms..

void sendSMS()
{
  MySerial.println("AT + CMGS = \"+000000000\"");        // mobile number
  delay(100);
  MySerial.println("Hello!");        // message to send
  delay(100);
  MySerial.println((char)26);                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  MySerial.println();
  delay(100);                                     // give module time to send SM
}



dannable

At the end of setup() print out cleanbuffer just to make sure that it's doing it's job? Then do a while(1){} to put it into an infinite loop so you don't continue into loop().

To save memory I would have used the same character array to clear the serial buffer and then to hold any incoming messages.
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

lelocchio84

I follow it until the point of have a single array. I tried to use a single one but do not work; With two its working  :smiley-grin: BUT until the buffer/s are full than no response. How can I empty the memory of the array? I tried different Methods but anyone seems working  :-[

Code: [Select]


/*If sms send = TEST than you get a SMS reply to your own phone*/

#include <SoftwareSerial.h>
SoftwareSerial MySerial(7, 8);

char incoming_byte[100];   // array to compare incoming SMS
int incoming_byte_Index=0; // array to compare incoming SMS - index
char cleanbuffer[100];     // cleaning array
int index=0;               // store the next empty space
int count=0;


void setup()
{
  Serial.begin(19200);                                   // for serial monitor
  MySerial.begin(19200);                                 // for GSM shield
  delay(10000);                                          // 10sec/10000ms delay to connect to network
  MySerial.println("AT+CMGF=1\r");                       // SMS mode totext
  delay(100);
  MySerial.println("AT+CNMI=2,2,0,0,0\r");               //blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
  MySerial.println("ATE=0");                             //echo off
  delay(150);
  MySerial.println("AT+CMGD=1,4");                       // delete the messages
  if(MySerial.available()>0){                            //if
  cleanbuffer[index]=MySerial.read();                    // setting the array to read values inside MYSerial
  Serial.println(cleanbuffer);                           // print in my serial the values from array
  index++;                                               // increase the array position
  }
}

void loop(){
  while(MySerial.available()>0)                         // open condiction. MySerial is available
  {
   cleanbuffer[index]=MySerial.read();                 // set the Array to read all values displayed in MySerial
   index++;                                            //increase the array position
   Serial.println(cleanbuffer);
}   //print to serial values
 if (index == 100) {                             
   for (index=0; index<count;index++)
   {
     cleanbuffer[index]=NULL;
   }
 }
    if(strstr(incoming_byte,"TEST")){   //if values in Serial are = "TEST" than sendSMS - I used a new array for that
     sendSMS();                                        //start sendSMS function
    incoming_byte_Index=0;                             //Return to position 0 inside the array incoming_byte
    MySerial.println("AT+CMGD=1,4"); 
  }

}
 /* if display values from sms, should send sms..*/
 
void sendSMS()
{
  MySerial.println("AT + CMGS = \"+00000000\"");     // insert here your mobile number \"+......."\
  delay(100);
  MySerial.println("Hello!");                          // message to send
  delay(100);
  MySerial.println((char)26);                          // End AT command with a ^Z, ASCII code 26
  delay(100);
  MySerial.println();
  delay(100);                                          // give module time to send SM
}





dannable

Just a couple of quick observations:

You never reset index when you leave setup(). As a global variable it will retain its value.

When I initialise a character array I set each one to '\0' so you automatically have an end marker when printing it out.

I would suggest that you sit down with pencil and paper and work out what you want the program to do and when it wants to do it. When do you want to print the array out? When do you wan to clear it? Have a look at the serialRelay program again and study that.
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

lelocchio84

Okay. I used "pen and paper method"  :) and thanks to it I figure out in an other way.
In the loop will read all the messages until 150 characters, than IF the message is according to the specific condition, so = test, will go to the sendSMS() and than restart the software (instead of clean the array, but i have done also that just to be sure).  Very effective. XD

What do you think? btw thank you so much for the help dannable!.. I have learn a lot thanks to you!


Code: [Select]



/*If sms send = TEST than you get a SMS reply to your own phone*/

#include <SoftwareSerial.h>
SoftwareSerial MySerial(7, 8);

char incomingbyte[150];   // array to compare incoming SMS
int index=0; // array to compare incoming SMS - index
int count=5; // counting to 5 connecting network (Setup setting)
int i=0;  // Setup setting
int y=0; // condition to read incoming values


/*The setup will start in 19200 baud both Serial and My Serial, later count until 5 to connect to network and start the AT commands parameters, so
SMS messages and parameters*/

void setup(){
  Serial.begin(19200);                                 
  MySerial.begin(19200);
  for(i=0;i<count;i++){
  Serial.print(".");
  delay(1000);
  }
  Serial.println("done");
  delay(50);    // 10sec/10000ms delay to connect to network
  MySerial.println("AT+CMGF=1\r");                       // SMS mode totext
  delay(100);
  MySerial.println("AT+CNMI=2,2,0,0,0\r");               //blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
  MySerial.println("ATE=0");                             //echo off
  delay(150);
  MySerial.println("AT+CMGD=1,4");                       // delete every message from SIM
    } 
   
  /* in loop will read all the incoming messages unti 150 carachters, then will discard all the messages not according to "Test" by resetting the carachter array and
  restarting the software */
   
  void loop(){
   
    if(MySerial.available()){  // read all the incoming messages from your mobile to Shield
    do{
    incomingbyte[index++]=MySerial.read();
    Serial.println(incomingbyte);
    break;
    }while(y==0);
    }
    while(strstr(incomingbyte,"Test")){ // if message is according to Test, than start the SendSMS function
    sendSMS();
    delay(100);
     }
    if(index>=140){ // condiction: if messame more than 140 carachters then discard it, clean array and restart the software
    for(index=0;index<150;index++){
    incomingbyte[index]='\0';
    Serial.println("cleaning done, restarting");
    delay(300);
     software_Reset();
      }
      }
   }
   
   
   /*Send Hello! SMS and reset the software*/
   

    void sendSMS()
{
  while(strstr(incomingbyte,"Test")){
  MySerial.println("AT + CMGS = \"+00000000\"");     // insert here your mobile number \"+......."\
  delay(100);
  MySerial.println("Hello!");                          // message to send
  delay(100);
  MySerial.println((char)26);                          // End AT command with a ^Z, ASCII code 26
  delay(100);
  MySerial.println();
  delay(100); 
  software_Reset();                             
 }
  }

/* Software Reset function */

void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile ("  jmp 0"); 

   
   






Go Up