sending AT commands to receive sms

Hello,
We have a college project to send and receive an sms using a GSM module and display the received/sent sms on an LCD screen. We have done the first bit,that is, send and display.We are facing a problem with the receiving part of the project.

code to receive unread messages.

#include <SoftwareSerial.h> 
SoftwareSerial mySerial(2,3);  
const int ledPin =  13;    

void setup() 
{ 
 mySerial.begin(9600); 
 delay(2000); 
 mySerial.println("AT"); 
 delay(2000); 
 mySerial.println("AT+CSMP=17,167,0,0"); 
 delay(2000); 
  // initialize the LED pin as an output: 
  pinMode(ledPin, OUTPUT);      
 
} 

void loop() 
{ 
   
  digitalWrite(ledPin, HIGH); 
  delay(1000); 
  mySerial.println("AT+CMGF=1"); // set the SMS mode to text 
  delay(2500); 
  mySerial.write("AT+CMGL="); 
  mySerial.write(34); //ASCII of “ 
  mySerial.write("REC UNREAD"); 
  mySerial.write(34); 
  mySerial.write(13); 
  mySerial.write(10); 
  delay(2500); 

}

These set of commands display the unread messages when tested on the hyper terminal but don't work on the arduino.why is that so??
Here are our exact queries:
1> How do we get the unread messages to be displayed onto the serial monitor??
2>The AT+CMGF=1 command is not being printed on the serial monitor.

Please, help us figure out our start up project! Thanks in advance :slight_smile:

you have set the receiving end to 9600 baud as well?

This is the modification we came up with for our prior code ,but no results on the serial monitor yet.:-/

#include <SoftwareSerial.h> 
SoftwareSerial mySerial(2,3);  
const int ledPin =  13;    
int input[20];
void setup() 
{ 
 mySerial.begin(9600); 
 delay(2000); 
 mySerial.println("AT"); 
 delay(2000); 
 mySerial.println("AT+CSMP=17,167,0,0"); 
 delay(2000); 
  // initialize the LED pin as an output: 
  pinMode(ledPin, OUTPUT);      
 
} 

void loop() 
{ 
   
  digitalWrite(ledPin, HIGH); 
  delay(1000); 
  mySerial.println("AT+CMGF=1"); // set the SMS mode to text 
  delay(2500); 
  mySerial.write("AT+CMGL="); 
  mySerial.write(34); //ASCII of “ 
  mySerial.write("REC UNREAD"); 
  mySerial.write(34); 
  mySerial.write(13); 
  mySerial.write(10); 
  delay(2500); 
  if(mySerial.available()>0)
  {
    for(int i=0;i<20;i++)
    {
    input[i]=mySerial.read();
    Serial.print(input[i]);
    }
  }
    

}

yes, we set it to 9600 on the serial monitor as well

I think you need to change the code at the end

basically you need to fill the input[] array when there is data available
and print it when you get a newline

So you could see the messages;
"AT"
"AT+CSMP=17,167,0,0"

but not the message
"AT+CMGF=1"

What does pin 13 do?

Here is a useful link.
http://www.diafaan.com/sms-tutorials/gsm-modem-tutorial/at-cmgl-text-mode/

Initially I would use "ALL" instead of "REC UNREAD" , just for convenience.
Also you can see the modem returns "OK" etc. to commands you need to expect to read those.

hey,
we had to take a break from the project due to exams.The output we are receiving seems indecipherable,it seems to be in ASCII?Here's the modified code and the screenshot of the serial monitor window.
Kindly help! :slight_smile:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); 
char incomingByte=0; 
void setup() 
{
       Serial.begin(9600);  
     mySerial.begin(9600);   
      pinMode(13, OUTPUT); 
      mySerial.println("AT");
      mySerial.println("AT+CMGF=1");  
      //mySerial.println("AT+CMGD=255,4");
     }

void loop()

{   
mySerial.println("AT+CMGL=");
mySerial.write(34);
mySerial.write("ALL");
mySerial.write(34);
mySerial.write(13);
mySerial.write(10);


        while (mySerial.available() > 0) 
        {               
               incomingByte = mySerial.read();
                
               Serial.println(incomingByte);
               
          Serial.println(mySerial.read());
        
        
        
      }
       
}

Can you please instruct us on the modifications needed to be made to the above code?

project_quest:
The output we are receiving seems indecipherable,it seems to be in ASCII?

I guess the output you posted comes from here:

               incomingByte = mySerial.read();
                
               Serial.println(incomingByte);

Because you're using print rather than write to output the received byte, what you're seeing is a decimal representation of the ascii character value. If you used write() instead, the ascii character would be written directly to the serial port so what you saw in the serial monitor would be exactly what was received.

However there are bigger problems with that sketch - you don't wait to receive a complete response before you send the next command, so you will end up throwing commands at the modem very quickly and not fully reading any of the responses. You need to think about when you want to send the next command.

If it was me I would start with a very simple sketch that just sends a single command and reads and displays the output. Once you do that all the rest will drop into place.

Hello,
Thank you,PeterH,for pointing out a major slip up! introduced delays after the AT commands,the GSM modem replies with an OK.However,despite using Serial.write() as opposed to Serial.print(),the characters appearing on the serial monitor are mainly numbers or symbols :-/.
Tried to use a AT+CNMI command (feeding in parameters that are within the range displayed on the hyperterminal).output has remained the same.

The same set of commands,on the hyperterminal ,are displaying texts received by the gsm modem, but not so on the serial monitor. Any advice /suggestions as to where the problem might lie?

Thanks.

project_quest:
Any advice /suggestions as to where the problem might lie?

Somewhere in your code, I would guess.

Which we can't see.

Of course,sorry! Here's the code :).

#include <SoftwareSerial.h>
SoftwareSerial mySerial(9,10); 
char incomingByte=0; 
void setup() 
{
       Serial.begin(9600);  
      mySerial.begin(9600);   
      pinMode(13, OUTPUT); 
      mySerial.println("AT");
      delay(2000);
      mySerial.println("AT+CMGF=1");
      delay(2000);  
      //mySerial.println("AT+CSMP=17,167,0,0");
      mySerial.println("AT+CNMI=3,3,0,0"); 
      delay(2000);
     
     }

void loop()

{   
mySerial.write("AT+CMGL=");
mySerial.write(34);
mySerial.write("ALL");
mySerial.write(34);
mySerial.write(13);
mySerial.write(10);


        while (mySerial.available() > 0) 
        {       
               incomingByte = mySerial.read();
               if(incomingByte!='/n')
               {
               Serial.print(incomingByte);
               }
               
               if(incomingByte=='/n')
               {
                 Serial.println(incomingByte);
               }
         
      

        }
}

project_quest:
despite using Serial.write() as opposed to Serial.print(),the characters appearing on the serial monitor are mainly numbers or symbols :-/.

               Serial.print(incomingByte);
               Serial.println(incomingByte);

I'm not seeing the Serial.write() in your code.

Also, you haven't addressed the issue of waiting until you receive a complete response to a command before you send the next command.

Hey PeterH,
I introduced delays after typing the GSM commands so that the modem has the time to respond with an "OK".This is what i understood "waiting until you receive a complete response" to mean.Did you mean something else? Here is the code and the screen shot of the serial window. I typed in AT+CMGR=index in my code.This way,I can see the text that is stored in my SIM having the index 15 ,(verified on hyperterminal) on the serial window. BUT,there is a whole lot of other stuff too :-/.i need to display just the text received, on an LCD display .The output looks clean on the hyperterminal window.what can i do to eliminate the junk values over here??

  #include <SoftwareSerial.h>
SoftwareSerial mySerial(9,10); 
char incomingByte=0; 
void setup() 
{
       Serial.begin(9600);  
      mySerial.begin(9600);   
      //pinMode(13, OUTPUT); 
      mySerial.println("AT");
      delay(2000);
      mySerial.println("AT+CMGF=1");
      delay(2000);  
      //mySerial.println("AT+CSMP=17,167,0,0");
      mySerial.println("AT+CNMI=2,2,0,1,0"); 
      delay(2000);
     
     }

void loop()

{   
mySerial.write("AT+CMGR=");
//mySerial.write(34);
mySerial.write("15");
//mySerial.write(34);
mySerial.write(13);
mySerial.write(10);


        while (mySerial.available() > 0) 
        {       
               incomingByte = mySerial.read();
               if(incomingByte!='/n')
               {
               Serial.write(incomingByte);
               }
               
               if(incomingByte=='/n')
               {
                 Serial.write(incomingByte);
                 Serial.write(13);
                 Serial.write(10);
               }
         
      

        }
}

Also,Thanks for replying!

There seem to be two issues - getting the modem working at all, and designing a real sketch to use it.

Just to get it working at all, using delays to ensure that the whole response is available before you start reading it would probably work, but I'd want to know how big the expected responses were and confirm that the SoftwareSerial receive buffer was big enough to hold them. At the very least, I suggest you should empty the receive buffer after each command.

In your code to check for newline characters you are testing for '/n'. You should be testing for '\n'. I don't think this will solve all of your problems, but you might as well get it right.

The garbage you're seeing on the Serial output makes me suspect that the modem SoftwareSerial port settings are not correct. What speed does the modem default to?

In the full sketch I suggest you should work out when you have received a complete response based on what you have received rather than based on a fixed delay, but you aren't at the point where matters yet.

Hi,
Sorry for the long delay.We were working on an electronics project for a fest.How can i empty the buffer?i saw this code snippet .

while (Serial.available ())
  Serial.read ();

Is this how?And as for the "\n",thanks.corrected,with no change in response however.Sorry for so many questions,but isn't the speed of the modem what we set the baud rate to?

Can the sms receive code on the GSM library be used for SIM300 as well, and not just the GSM shield? by connecting the rx and tx on arduino to the rx and tx of the modem?

We're beginners with arduino and coding too! So please bear with this :-p

project_quest:
isn't the speed of the modem what we set the baud rate to?

The modem will choose a speed for its serial port. Your sketch chooses a speed for its serial port. The two speeds must be the same. If they're different then data sent over the connection will be corrupted.