Go Down

Topic: Use of buffer causes loss of data (Read 362 times) previous topic - next topic

snugRugBug

Hi

I'm currently having a little trouble reading data from my GPRS shield V2 with my Seeeduino Stalker V2.3. In the attached code, directly printing from the GPRS to serial works good enough, printing all the data being sent. I commented that out.
The problem occurs when I try to use a buffer for the same purpose. If you look at the attached text file, you will see that the buffer readout misses the last 68 characters of the data. It also incorrectly reads a "9" and an "e" at the end of the buffer.

The code I attached is a replication of an error I am experiencing in a larger program that already uses this buffer without a problem. I copied the code directly, and isolated the problem.

Please help me understand this behaviour
Thanks

snugRugBug

Here's the code:

Code: [Select]

#include <SoftwareSerial.h>
#define MAX_AT_COMM_LEN_I 24 // Max length of incoming AT commands
SoftwareSerial GPRS( 7, 8 ); // A softwareSerial line is defined for the GPRS Shield
char buffer[MAX_AT_COMM_LEN_I + 1];
char temp;
void setup()
{
  buffer[MAX_AT_COMM_LEN_I] = '\0';
  Serial.begin(4800);
  powerUp();
  GPRS.begin(4800);
  wipeBuffer();
}

void loop()
{
  while(Serial.available())
    GPRS.print((char)Serial.read());

// returns expected output....
// if (GPRS.available())
  //  Serial.print((char)GPRS.read());

// returns unexpected output
if (GPRS.available())
  addToBuffer((char)GPRS.read());
}

void powerUp()
{
  Serial.println("Powering Up SIM900");
  pinMode(9, OUTPUT);
  digitalWrite(9,LOW);
  delay(100);
  digitalWrite(9,HIGH);
  delay(500);
  digitalWrite(9,LOW);
  delay(100);
  Serial.println("SIM900 Powered Up");
}


void addToBuffer(char ch) // Maintains a FIFO buffer.
{                         // In this buffer, chars will appear to move from the right to left of the buffer:
  // Adding 's' to the buffer #### will result in ###s.
  // Then adding '@' will result in ##s@
  // The buffers length is determined by the longest AT command we have to listen for.
  if( ((int)ch >= 20 && (int)ch <= 126) ) // ignores all whitespaces and garbage chars except space
  {
    //  all chars in the buffer are moved one position to the right, and the new char is added to the end
    for(int i = 0; i < (MAX_AT_COMM_LEN_I - 1); i++)
      buffer[i] = buffer[i+1];
    buffer[MAX_AT_COMM_LEN_I - 1] = ch;
    Serial.print("b: ");
    Serial.println(buffer);
  }
}

void wipeBuffer() // fills buffer with # chars
{
  for(int i = 0; i < MAX_AT_COMM_LEN_I; i++)
    buffer[i] = '#';
}

pylon

Your serial buffer overruns before you reach the point where you have read enough. That's because you're printing much more data to Serial (27 times more at least) than you're reading on the SoftwareSerial. But Serial has the same baudrate as SoftwareSerial has, so you reach the point where the small input buffer overflows relatively early.

BTW: You should read about circular buffers: http://en.wikipedia.org/wiki/Circular_buffer

Go Up