Reading a long sms from a Seeed GPRS shield

I am having hell with this and I know it is probably really simple. I am trying to read a text message from my Seeed GPRS shield. I have the shield setup as a software serial and I am displaying the information received from the GPRS to the serial monitor. I am currently sending all AT commands over serial while I work on my code. To display the data from the software serial to the serial monitor, I am using the following code.

while(GPRS.available()!=0)
    {
      Serial.write(GPRS.read());
    }

GPRS is my software serial, obviously. The problem is, the text is long and I only get a few characters from it. Something like this.

+CMGR: “REC READ”,“1511”,"",“13/12/09,14:34:54-24”
Welcome to TM eos8

This text is a “Welcome to T-Mobile” text that is much longer. The last few characters shown are scrambled. I have done some research and have seen that I can mod the serial buffer size to 256 instead of the default 64. I want to avoid this because I am sure there is an easier way. Any ideas?

I’m right there with you, so I’ll bump your post and add my situation. I’m using the same SIM900 module on a Linksprite shield, also on T-mobile. I’ll post my code below, but if I create a serial patch to the SIM900 and use the AT command to read my first (or any) position SMS, I only get a few characters preceded by the originating telephone number and a timestamp. You don’t mention the number and timestamp in your post but I figure you’re getting that too. My whole response to AT+CMGR=1 in Terminal is:

+CMGR: “REC READ”,“1511”,"",“13/12/15,13:39:48-32”
Welcome to Tetrub1

If I run it again, I might get a few different ending characters like “Welcome to TbLrun5”.

Did you ever figure this out and if so could you post your sketch? Anyone have suggestions to add to our code to read the entire contents of an SMS? My code:

#include <SoftwareSerial.h>
 
SoftwareSerial mySerial(7, 8);
 
void setup()
{
  mySerial.begin(19200);               // the GPRS baud rate   
  Serial.begin(19200);                 // the GPRS baud rate
  mySerial.println("AT+IPR=19200");    // Tell the SIM900 not to autobaud
}
 
void loop()
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());  
 
}

The hardware serial port has a buffer to store some data until you get around to reading it. SoftwareSerial uses pin change interrupts to detect data and interrupt the processor to handle it.

Serial.available tells you that there is data in the buffer, so consider what happens when you say "while(serial.available) {... }", when you have read all the available data the while loop will exit. It does not mean that you have read all the data that is being sent, just that you emptied the buffer. If you then do other things and the buffer fills up again, it could overflow if you don't get round to reading it quickly enough.

Posting your full sketch may help with understanding what is going on. One thing to consider is separating the reading and writing, i.e. read all the data into memory (assuming you can determine the end-of-message, or read until a certain time has elapsed) and then write it out on the other port.

Hey I noticed you found the solution (or at least a work around) by changing the SoftwareSerial.h file in the SoftwareSerial library. Thanks for figuring this out! It's working great.

ironchariot: I had an issue with this. With receiving text, you have problems with the buffers. I had to mod the arduino serial buffer size to allow a larger buffer and write my own library for a larger software serial buffer. Here is the way I increased the serial buffer. http://www.hobbytronics.co.uk/arduino-serial-buffer-size . For the software serial I just duplicated the library, renamed the instance and keywords, and changed the max buffer size to 256. Both buffers are 64 originally. It is a pain, but you can do it non destructively. This way you can receive the whole text.