Serial.read() misses one character every 2-3 hours

Hi,

I’m using HardwareSerial for communication between Arduino and Libelium’s GPRS-Shield (Hilo module). All works fine, but every 2-3 hours it seems that Serial.read() misses one character, which was sended from the Hilo module. My first idea was, that the module misses to send the character, so I monitored the serial output of the Hilo module with a separate TTL2Serial converter and Hyperterminal: no characters are missed. So, in most cases (more than 99.9%) the arduino receives all characters from the Hilo module, but sometimes (every 2-3 hours or about every 10.000 characters) one byte is not received correctly. I have learned to deal with this, but I will sleep better if I could fix this error with your help.

my questions are:

  1. Is it an interrupt issue? Maybe a conflict between HardwareSerial and NewSoftSerial? I use both simultaneously (HardwareSerial for communication with GPRS-shield at 2400 baud and NewSoftSerial for reading data from GPS receiver at 38400 baud). And what can I do to figure it out?

  2. Is it a software error of my code? I use the following function to wait for a specific character string from the Hilo module:

/***********************************************************************
 *   waitfor_P - waits for a specific character string sended from the Hilo module
 *               addr:        address of character string in PROGMEM
 *               maxtime:     maximum time to wait in mS
 *               return true: if the string was found in the recieved characters
 */
boolean GPRS::waitfor_P(const char *addr, unsigned long maxtime){
  maxtime/=20;
  int ind=0;
  char str;
  for (int i=0;i<20;i++){
    delay(maxtime);
    while (Serial.available()>0){
      str=pgm_read_byte(addr+ind);
      if (str=='\0') return true;  // if we reach the end of the string we found it
      else {
        char c=Serial.read();
        if (str==c) ind++; else ind=0;
        if (*debug==3 && c>31) (*MSG).printURL(c);   // this is for logging (MSG is of class PString)
        }
      }
    }
  return false;
  }

typical calls are:
waitfor_P(PSTR(“RING”),1500) or
waitfor_P(PSTR("+KTCPSTAT:"),4000) …

I have the strong feeling that the hole thing is an software issue, but maybe I’m wrong. So every help from you is very welcome.

Best regards,
Schimmel

I'm going to bet it's NewSoftSerial. It works by doing timing loops inside an interrupt service routine, so that interrupts are disabled during this time. With interrupts disabled, you could be missing characters.

-- The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, light sensor, potentiometers, pushbuttons

Did you try to switch the serial libs? NewSoftSerial for the GPRS-shield @ 2400 baud and HardwareSerial for GPS receiver @ 38400 baud.

If Rugged is right, using NewSoftSerial at the lower speed may give less errors. (assumption!!!)

Just thinking out loud. Rob

Does your GPS actually use 38400 as a baud rate? Typically, GPSs use 4800.

Thanks for all your comments,

@PaulS: Yes, the GPS receiver uses 38400 as the default baud rate. (NAVILOCK NL-403P http://www.navilock.de/produkte/gruppen/3/Kabel_Empfaenger/60109_NL-403P.html?show=spec) Sorry, I don't find an english page. Maybe it is possible to change the baud rate. I have never tried this.

@robtillaart: Good point, but unfortunately, this is not possible because the GPRS-Shield has fixed RX/TX-Pins which has to enter into the HardwareSerial-Pins of Arduino. And I'm afraid to change this. I think it is not possible to use HardwareSerial on other pins than 0 and 1. I can use NewSoftSerial for both devices, but ... :-/

@RuggedCircuits: I will chek your hypothesis. This experiment schould show, if you are rigth:

void loop{
  getGPSfix with NewSoftSerial and TinyGPS
  
  // turn off NewSoftSerial
  nss.end();

  send and recieve data via HardwareSerial with GPRS-Shield

  // turn on NewSoftSerial
  nss.begin();

  // wait 1 or 2 seconds to fill the receive buffer
  delay(1000);
}

I will report the results. regards, Schimmel

Update: Yes! It works! The test is still running. After 4 hours the Arduino receives 56.000 bytes without any missing character. Thanks for your help. Schimmel