Silky
Silky

Reputation: 41

Serial overflow in Arduino

When reading SMS using an Arduino program, the serial monitor shows only the senders (no date or time) and truncates the message. This is may be due to serial overflow, a common problem in Arduino.

Code:

#include <SoftwareSerial.h>
#include <String.h>

SoftwareSerial mySerial(7, 8);
void setup()
{
  mySerial.begin(9600);               
  Serial.begin(9600);    

}


void loop()
{
 mySerial.print("AT+CMGR=1\r");
 delay(100);
 while(mySerial.available())
   Serial.write(mySerial.read());
   delay(1000);
}

Output

AT+CMGR=1

+CMGR: "REC READ","+XXXXX","A Silky Soni","1AT+CMGR=1

+CMGR: "REC READ","+XXXXX","A Silky Soni","1AT+CMGR=1

+CMGR: "REC READ","+XXXXX","A Silky Soni","1AT+CMGR=1

Upvotes: 4

Views: 1121

Answers (2)

Reynel Fals de Pedro
Reynel Fals de Pedro

Reputation: 111

It's not the baud rate, because the string is legible so all the bits are in the correct position, however the string is truncated.

This happen because the output buffer in mySerial take more time to be filled by the GSM shield than the time to be depleted by the mySerial.read() instruction. That's it: when mySerial.available() is checked and the GSM shield don't have time to put anything in the output buffer, the result is the fail of the while loop. There are some ways to face that problem:

Put a delay() with specific time inside the while:

void loop()
{
         mySerial.print("AT+CMGR=1\r");
         delay(100);
         while(mySerial.available()){
           Serial.write(mySerial.read());
           delay(100);  //fix the time according to how fast the GSM shield
                        //wrote the data in the serial port. 
         }
         delay(1000);
}

Or use a timeout:

unsigned long init_time, timeout=500;//choose the correct timeout value  
void loop()
{
 mySerial.print("AT+CMGR=1\r");
 //delay(100); //this delay can be omitted
 init_time=millis();
 do{
   while(mySerial.available()){
     Serial.write(mySerial.read());
     init_time=millis();
   }  
 }while(millis()-init_time < timeout);
 delay(1000);
}

The millis()-init_time give the time elapsed since the last time the mySerial.available() return true or before the check if never was available. The code will still checking for availability until reach the timeout limit.

I suggest the last approach. Happy coding!

Upvotes: 0

blarg
blarg

Reputation: 3893

You might need to adjust the baud rate in your code to match the GSM shield.

Upvotes: 1

Related Questions