Unable to receive SMS using GSM read example but AT commands reveal sms received

Hello all,

I am using an Arduino UNO w/ an ATWIN QuadBand GSM shield and a TRUSIM sim card. I am connecting to the Arduino using the freely available IDE. When I attempt to use the supplied GSM example to receive SMS found here: http://arduino.cc/en/Tutorial/GSMExamplesReceiveSMS

The serial monitor never displays any information past “Waiting for messages” when I actively send an SMS to the shield or when there are already unread SMS’s on the SIM. After running into this issue I decided to try using AT Commands to at least ensure the SMS’s were being received by the SIM. Upon running {AT+CMGL=“ALL”} or {AT+CMGR=1} the serial monitor will display the SMS messages that are stored on the SIM. I have also tested the ability to send SMS from the Arduino and that works flawlessly. By doing this I believe I ruled out the SIM or GSM shield not working.
Since I was unable to find any information online related to the example GSM SMS read tutorial linked above I decided to look for other solutions such as running AT commands on a time interval. I used the code below to try to achieve this but the SMS messages are still unable to be found and displayed in the serial monitor.

#include <SoftwareSerial.h>
#include <string.h>
char command = 0; //Conditional Programming Variable changes with SMS content.
char incoming_char = 0;
SoftwareSerial cell(2, 3); 

//These variables are for timing the Receive SMS command.
long previousMillis = 0; //Equals current millis every time interval is met.
long interval = 30000; //Amount of time to wait between Receive SMS commands
unsigned long time;
void setup()
{
  Serial.begin(9600);
  cell.begin(9600);
  delay(2000);
  Serial.print("Starting modem communication...");
  delay(12000);
  Serial.print("OK\nIntroduce your AT commands:\n"); 
}

void loop()

{ 
//--------Timed SMS Receive command code ---------
time = millis();

  if (time - previousMillis > interval) {

    cell.println('AT+CMGR=1,0');
    cell.print("\r");
    Serial.println("Time reached: \n");
    previousMillis = time;
  }
//------------------------------------------------


  if(cell.available() > 0)
  {
    incoming_char=cell.read();
    if((incoming_char >= ' ') && (incoming_char <= 'z'))
      Serial.print(incoming_char);
    if(incoming_char=='#'){
      Serial.println("SMS command mode:"); //If the SMS contains "#" the arduino looks for commands that follow.
      command=cell.read();
    }
    if (command == 'a'){  //If the next character in the SMS is "a", then do the following
      Serial.println("Commands would execute here and now.");
      command = 0;
    }

    else
    {
      Serial.print("%");
      Serial.print((int)incoming_char);
      Serial.print("%");
      if(incoming_char==10)
        Serial.println();

      //Serial.println(incoming_char);



    }
  }

  if(Serial.available() > 0)
  {
    incoming_char = Serial.read();
    cell.print(incoming_char);
  }
}

The above code I found on the forums and modified slightly to work with the UNO.

I suppose my question is are their any others who have run into issues using the example GSM SMS read() tutorial other than a shield or sim being faulty as the cause of the problem.

The overall purpose of the project I am working on is: I want to send an SMS to the Arduino, the arduino will determine the content of the SMS message (I.E. Start, Stop, Lock, Unlock) and perform the action accordingly. I have yet to receive an SMS and display it to the serial monitor as the SMS is received. The only way I can see what SMS messages have been received are by only running AT commands through the serial monitor which then outputs the sms messages that have been received. Any help or guidance is greatly appreciated!!

Thanks!

Usually, when an SMS arrives, the GSM sends an unsollicited sentence : +CMTI = "Storage Memory", n° tne number of the SMS is just after the first ' , ' character . Then you use this as the index to retrieve the SMS .

So you need to poll the serial input from GSM, and, when it receives a +CMTI=......... , retrieve the index, and send a AT+CMGR=index command etc....

Thanks for the reply, can what you are referencing be used in the code i pasted into the original post or is this something that needs to be added to the example SMS Read() tutorial included with Arduino. My understanding of the SMS read tutorial was that the sms messages should appear in the serial monitor as they come through the SIM. is that not the case?

When you say "Usually when as SMS arrives, the GSM sends an unsollicited sentence: + CMTI.... will that display in the serial monitor or do I have to look else where for that sentence? Thanks again for your help.

I can't say anything about the arduino example, because it uses the GSM library, and I don't.

But the GSM sends the "+CMTI....." code to the serial input of the arduino each time it receives a SMS. Then, yes, you need to modify your code a little bit (the if(cell.available() {...} part ) Until now, in your code, you read only one character and you print it immediately on the monitor.But you don't save it. If you look at your monitor when you've just sent a SMS, you'll see the "+CMTI....." sentence. (you'll see it better if you comment the Serial.print("%"); lines ;) ) There are several ways to deal with that, which depend on what you want to do exactly. The idea is to store each received char (until '13' = carriage return is received) in a string, and, when the received char = '13' , then you check if it contains "+CMTI" . If it does, you read the value right after the first comma, and use it to retrieve the SMS content using AT+CMGR command. And erase the string.

It is very late here and I have to go to sleep, but if you need more help, I'll try to help more tomorrow .

I have the same issue.

I have an Arduino UNO, and a SIM908 chip shield that reads the SIM card.
Whenever I run the SIM908 in UART mode, I can read and poll the info from the card. I can read txt messages, and all no problem.

But when I try using the following code:

void readMessages(int stat, boolean markAsRead=true){
  char readChar [500] = { 0  };
  int index = 0;
  String command =  "AT+CMGL=\"ALL\",1";
  //String command = "AT+CMGL=4,1"; // i have tried this as well with same results
  double prevTimer = millis();
  double currTimer = millis();
  
  Serial.println("AT+CMGF=1,1");
  delay(2000);
  Serial.println(command);
  
  while(1){
    if(Serial.available()){
      readChar[index]=Serial.read();
      Serial.print(readChar[index]);
    }
    currTimer = millis(); //get time lapsed
    if (currTimer - prevTimer > 10000){//every 10 seconds
      Serial.println(command);
      prevTimer = millis(); //update prev timer
    }

  }
}

The output of the code is something like this:

.AT
AT+CGPSIPR=9600
AT+CMGF=1
AT+CMGL="ALL",1
AT
OK

Nothing happens, i know im supposed to get something like:

+CMGL: 2,"REC UNREAD","+##########","","13/11/02,15:15:32-20"
This is a response

I can send TXT msgs just fine.

@CcXD, looking at your code, you’ll never get the SMS list :

void readMessages(int stat, boolean markAsRead=true){
char readChar [500] = { 0 };
int index = 0;
String command = “AT+CMGL=“ALL”,1”; // you ask for the SMS list
//String command = “AT+CMGL=4,1”; // i have tried this as well with same results
double prevTimer = millis();
double currTimer = millis();
Serial.println(“AT+CMGF=1,1”); // here you set the SMS format -IMHO, it should be done before, just after
delay(2000); // you enter the pin code
Serial.println(command);
while(1){ // you never get out of the while loop !! , OK ?
if(Serial.available()){
readChar[index]=Serial.read(); // here, you read
Serial.print(readChar[index]); // and print the answer to… AT+CMGF command
}
currTimer = millis(); //get time lapsed
if (currTimer - prevTimer > 10000){//every 10 seconds
Serial.println(command);
prevTimer = millis(); //update prev timer
}

}
}

the reading of the serial input should nt be in an infinite loop. Either you read a char each time the loop() is executed, or you read all the characters in the buffer in a while() loop, which exits as soon as there are no more characters available.
This page is IMO very useful : Gammon Forum : Electronics : Microprocessors : How to process incoming serial data without blocking

Edit : also, you are using the same serial port for both communications arduino <-> GSM and arduino <-> serial monitor
When you write this :

   if(Serial.available()){
      readChar[index]=Serial.read();  
      Serial.print(readChar[index]);  
    }

you send the received datas to the serial monitor, and… back to the GSM too . I think it might produce weird results.

Thanks for your reply,

One thing that you pointed out, i had already had a suspicion about it. When you mention that I use the same serial port to read a character, then write that char, which then reads, in fact the output starts becoming an aggregate of all the outputs jammed together.

How can I debug this, if I cannot print out what I read from the SIM without it being read and replied like you said it will happen?

//you enter the pin code

In regards of your comments, I have never had to enter a "pin" code.... not even when using the UART console instead of the arduino. Is this necessary? I dont think I have setup a pin for the SIM card.

// here you set the SMS format -IMHO, it should be done before,

The variable "command" is declared at the beginning of the function, but it is sent out after the configuration, like you suggested.

The variable "command" is declared at the beginning of the function, but it is sent out after the configuration, like you suggested.

oups, you're right, sorry

In regards of your comments, I have never had to enter a "pin" code.... not even when using the UART console instead of the arduino. Is this necessary? I dont think I have setup a pin for the SIM card.

no, if you SIM card doesn't wait for it, no need to send a pin code

How can I debug this, if I cannot print out what I read from the SIM without it being read and replied like you said it will happen?

In your while loop, the variable index is allways 0, you should add a index++; statement and, instead of sending back each received char, you could fill readChar[] until the received char is '13' so that readChar contains the whole answer . Then you can do anything you want with it. If you want to send it to the monitor, OK, but it is better to change the first characters in it so that it doesn't appear as a valid command to the GPRS . Even without changing anything in it, and just for debugging purpose, you could print it as is, only if it contains some consecutive characters. For example, if you want to see if a SMS has been received, you can check if readChar contains "+CMTI:" and print it if yes.

    if(strstr(readChar,"+CMTI:")!=NULL)
       serial.Println(readChar);

You'll see that the +CMTI: answer contains the information you need to retrieve the SMS with an +CMGR command. BTW, 500 is more than necessary for the GPRS answers, remember there is not much RAM available ;)

I have finally gotten it to work.

I think this code works because the Serial interface is relatively slow. and what I had before was happening way too fast for the buffer to work well. I am posting the code here so that if others have similar problem, they can use mine as an example.

// Product name: GPS/GPRS/GSM Module V3.0
// # Product SKU : TEL0051
// # Version     : 0.1

// # Description:
// # The sketch for driving the gsm mode via the Arduino board

// # Steps:
// #        1. Turn the S1 switch to the Prog(right side)
// #        2. Turn the S2 switch to the Arduino side(left side)
// #        3. Take off the GSM/GPS jumper caps from the Uart select
// #        4. Upload the sketch to the Arduino board
// #        5. Turn the S1 switch to the comm(left side)
// #        6. Plug the jumper caps back to GSM side
// #        7. RST the board

// #        wiki link- http://www.dfrobot.com/wiki/index.php/GPS/GPRS/GSM_Module_V3.0_(SKU:TEL0051)
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"

SMSGSM sms;

byte gsmDriverPin[3] = {
  3,4,5};//The default digital driver pins for the GSM and GPS mode
//If you want to change the digital driver pins
//or you have a conflict with D3~D5 on Arduino board,
//you can remove the J10~J12 jumpers to reconnect other driver pins for the module!

/**********************************************
 Functions created by me
***********************************************/
  int BufferIndex = 0;
//function to send a message
void sendMessage(char* message){
  Serial.println("AT+CMGF=1");
  delay(1000);
  Serial.println("AT+CMGS=\"14692545597\"");//Change the receiver phone number
  delay(1000);
  Serial.print(message);
  delay(1000);
  Serial.write(26);
}
//------------
//function to read text messages
/* Inputs:
 int stat: 0 to read all unread
 1 to read read
 2 to read ALL
 boolean markAsRead: True if message when message is read, it turns into "read" status
 //------------*/
void readMessages(int stat, boolean markAsRead=true){
  delay(100);
  int index = 0;
  String command = "AT+CMGL=";
  double prevTimer = millis();
  double currTimer = millis();
  
  Serial.println("AT+CMGF=1"); //select configuration "text"
  delay(2000);
  
  if (stat == 0)
    command.concat("\"REC UNREAD\"");
  else if (stat == 1)
    command.concat("\"REC READ\"");
  else if (stat == 2)
    command.concat("\"ALL\"");
  if (markAsRead)
    command.concat(",1");

  //send the command 
  Serial.println(command);
  
}
//------------------------------
//function to fill the buffer
// no inputs so far... maybe specify command to read at a later point?
//------------------------------
void readReply(){
  char replyCommand [7] = {'+','C','M','G','L',':',' '};
  char txtIndex; 
  //read the feedback

  char readChar [100] = { 0 };
  while(Serial.available()){
      readChar[BufferIndex]=Serial.read();
      //compare each read character to each char from replyCommand
      if (readChar[BufferIndex] == replyCommand[BufferIndex]){
        //if index ==6 ; it matches all characters from replyCommand
        if(BufferIndex == 6){
        }
        BufferIndex++;
      }
      else if(BufferIndex == 7){
        txtIndex = readChar[BufferIndex];
        Serial.print("Txt msg rcv. index: ");Serial.println(txtIndex);
        BufferIndex++;
      }
      else{
        BufferIndex = 0;
      }
  }
}
/*--------------------------------
 When I run on 
 USB mode, enable this code instead of the other one
 void setup()
 {
 //Init the driver pins for GSM function
 pinMode(3,OUTPUT);
 pinMode(4,OUTPUT);
 pinMode(5,OUTPUT);
 //Output GSM Timing  
 digitalWrite(5,HIGH);
 delay(1500);
 digitalWrite(5,LOW); 
 }
 void loop()    
 { 
 digitalWrite(3,HIGH);//disable GSM TX?RX
 digitalWrite(4,HIGH);//disable GPS TX?RX
 }
 ------------------------------------*/

//------------------------------------------
//setup and loop functions
void setup()
{   
  Serial.begin(9600); //set the baud rate
  //Init the driver pins for GSM function
  for(int i = 0 ; i < 3; i++){
    pinMode(gsmDriverPin[i],OUTPUT);
  }
  digitalWrite(5,HIGH);//Output GSM Timing
  delay(1500);
  digitalWrite(5,LOW); 
  digitalWrite(3,LOW);//Enable the GSM mode
  digitalWrite(4,HIGH);//Disable the GPS mode

  delay(2000);

  Serial.println("Setup, please wait...");
  delay(5000);//call ready
  //  sendMessage("This is a message"); //this works
  delay(10000);
  Serial.println();
  char readChar;
  Serial.println("Dumping"); //clearing the buffer
  while(Serial.available()){
     Serial.read();
  }
  Serial.println(".");
  delay(2000);
  Serial.println("AT"); //Send AT command 
  delay(2000);
  Serial.println("AT+CGPSIPR=9600");
  delay(2000);

}
boolean firstRun = true;
void loop()
{ 
  
    //Send message
  if (firstRun){
    firstRun = false;
    readMessages(2,false);
  }
  delay(100);
  readReply();
  //sendMessage("Message is here)");
//  Serial.println("The End");
//  while(1);
}

Hello, Is there any one who can make me understand why I am not getting complete sms from my gsm module, I am using Arduino mega

My code

#include <string.h>
#include <ctype.h>

char sms_array[150];

boolean estado_botao = false; //state
boolean smsReceived = false;

void setup()
{
Serial.begin(9600);
Serial1.begin(9600);
Serial1.print(“AT+CNMI=2,2,0,0,0”);
delay(30);
Serial1.write(0x0d);
delay(30);
Serial1.println(“AT+CMGF=1”);
delay(30);
Serial1.write(0x0d);
delay(30);
}

void loop()
{
carrega_array_dados(); //loads_array_data
}
void carrega_array_dados() // loads_array_data
{
int k = 0 ;
while (Serial1.available() > 0 )
{
sms_array[k] = Serial1.read();
delay(20);
Serial.print(sms_array[k]);
delay(50);
k++;

}
Serial1.flush();
}

when I am send sms

Lat:2832.65186
Lon:07716.3446
Ph:4.10

The output that I am getting is

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

OK
AT+CMGF=1

OK

+CMT: “+919015805072”,“13/12/18,23:04:37+22”
Lat:2832.65186L7

    Serial1.flush();

Block until all pending output data has been shifted out. How, pray tell, is that useful?

when I am send sms

Where are you sending it from?

There appears to be no reason to save the received data in an array, since you never do anything with the array.

Check AT+CNMI

I think it is for able or disable CMTI “echo”, isn’t it ?

i’m facing similar problems too… i want to save the sms content and sender number in separate arrays. but i’m pointless about how to do it… i hav tried to put conditions but after i put any conditions, my program doesn’t run at all… and most of the times i’m getting junk values even without any conditions.
can please someone help me out about this issue?

For me, the only way I could get it to work is by using this:

// Must be an integer
int c;

if (sms.available()) {
Serial.println("Message received from:");
sms.remoteNumber(senderNumber, 20);
Serial.println(senderNumber);

// Translates incoming numbers into string characters until
// ...until character values are -1 (null, message done)
while ((c = sms.read()) != -1) {
Serial.print((char)c);
}

Serial.println("\nEND OF MESSAGE");
sms.flush();
Serial.println("MESSAGE DELETED");
}

delay(3000);
}```

But now the message prints right out in the serial monitor

tabbymughal: i'm facing similar problems too.. i want to save the sms content and sender number in separate arrays. but i'm pointless about how to do it... i hav tried to put conditions but after i put any conditions, my program doesn't run at all... and most of the times i'm getting junk values even without any conditions. can please someone help me out about this issue?

Please start your own thread, instead of resurrecting a 6 year old thread.