Reading a long text from GPRS Shield with Arduino

1.3k views Asked by At

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?

3

There are 3 answers

0
Sun Bee On

Have you tried reading into a character array, one byte at a time? See if this helps:

if (GPRS.available()) { // GPRS talking ..
    while(GPRS.available()) { // As long as it is talking ..
    buffer[count++]=GPRS.read();     
    // read char into array
    if(count == 64) break; // Enough said!
}
Serial.write(buffer,count); // Display in Terminal
clearBufferArray();
count = 0;
}

You need to declare the variables 'buffer' and 'count' appropriately and define the function 'clearBufferArray()'

Let me know if this helps.

0
user3485419 On

Looks like this is simply the result of the lack of flow control in all Arduino serial connections. If you cannot pace your GPRS() input byte sequence to a rate that guarantees the input FIFO can't overflow, then your Serial.write() will block when the output FIFO fills. At that point you will be dropping new GPRS input bytes on the floor until Serial output frees up more space.

Since the captured output is apparently clean up to about 64 bytes, this suggests
a) a 64 byte buffer,
b) a GPRS data rate much higher than the Serial one, and
c) that the garbage data is actually the occasional valid byte from later in the sequence.

You might confirm this by testing the return code from Serial.write. If you get back zero, that byte is getting lost.

If you were using 9600 for Serial and 57600 for GPRS, I would expect somewhat more than 64 bytes to come through before the output gets mangled, but if the GPRS rate is more than 64x the Serial rate, the entire output FIFO could fill up within a single output byte transmission time.

Capturing to an intermediate buffer should resolve your issue, as long as it is large enough for the whole message. Similarly, extending the size of either the source (in conjunction with testing the Serial.write) or destination (without any additional code) FIFOs to the maximum datagram size should work.

0
Ken On

I've had the same problem trying to read messages and get 64 characters. I overcame it by adding a "delay(10)" in the loop calling the function that does the read from the GPRS. Seems to be enough to overcome the race scenario. - Using Arduino Mega.

    void loop() {
      ReadmyGPRS();
      delay(10);  //A race condition exists to get the data.  
    }

    void ReadmyGPRS(){
      if (Serial1.available()){ // if data is comming from GPRS serial port
        count = 0;  // reset counter
        while(Serial1.available())          // reading data into char array 
      {
      buffer[count++]=Serial1.read();     // writing data into array
      if(count == 160)break;
     }
     Serial.write(buffer,count);
    }

}