Any chance serial drops zeros?

Kluge to check for serial receive errors -- seems to work on my bench top....

the status byte is ORed with the new status after every each character is received. When you check the status after receiving a number of bytes, if the error bits are not set, then there were no errors. If there were errors at any time since the previous status check the error bits will be set. This is much faster than checking for errors after every byte and shouldnt throw off buffering too much.
The routine to read the status register resets the variable to 0 each time it is called.

Finally -- only bits 2-4 indicate errors. I mask them in the test program.


NOTE this involves editing the wiring serial library. Not something you want to do for your production code. I dont know the "official" warnings on this, but be sure you make backup copies so you can put the original files back.

I am still researching the "correct" way to do this, and this shouldnt cause any problems as long as you put the original files back.


Part 1 - Edit wiring_serial.c

// this stuff is near the top of the files
int rx_buffer_head = 0;
int rx_buffer_tail = 0;
//  ********begining of first change*******
// new status variable here
byte status_reg = 0;

//function to return status byte
//status variable reset to 0 with each call
int serialStatus(void)
{
  int temp;
  temp = status_reg;
  status_reg = 0;
  return temp;
}
//  ******end of  first change*********
void beginSerial(long baud)

//**** second change ***********
//  skip further down the file to make this change
//  modify the interrupt/signal routine
// **************************** 
#if defined(__AVR_ATmega168__)
SIGNAL(SIG_USART_RECV)
#else
SIGNAL(SIG_UART_RECV)
#endif
{
#if defined(__AVR_ATmega168__)
      unsigned char c = UDR0;
#else
      unsigned char c = UDR;
#endif
// ************ begin second change *********
//get status byte
               status_reg = status_reg | UCSR0A;
//************  end second change  **********
      int i = (rx_buffer_head + 1) % RX_BUFFER_SIZE;

      // if we should be storing the received character into the location
      // just before the tail (meaning that the head would advance to the
      // current location of the tail), we're about to overflow the buffer
      // and so we don't write the character or advance the head.
      if (i != rx_buffer_tail) {
            rx_buffer[rx_buffer_head] = c;
            rx_buffer_head = i;
      }
}

Part 2 -- edit wiring.h

// you should problably put this near the other serial declarations
int serialStatus(void);

Part 3 -- Demo program

// reads a serial character then echos it back
// checks the status byte before each read
// you really should only check status at the end of a packet
// the delays are probably not necessary
int read_char;
int status;
void setup() 
{ 
  Serial.begin(9600); 
  
  // prints title with ending line break 
  Serial.println("Serial Test"); 
 
  // wait for the long string to be sent 
  delay(100); 
  
 // pinMode(ledPin, OUTPUT);
  
} 


void loop() 
{ 
  if (Serial.available() > 0) 
  { status = serialStatus();
// only bits 2-4 indicate errors  mask the others with 0x1C
// bit 2 = parity
// bit 3 = data overrun
// bit 4 = frame error
    status = status & 0x1C;
    read_char = Serial.read();
    Serial.print("*");
    Serial.print(read_char, BYTE);
    delay(100);
  }
 else
   {delay(25);} 
 
 if (status != 0)
  {Serial.print("#");
   Serial.print(status);
   Serial.print("#");
  }
}