The SoftwareSerial library has a built-in Overflow function, but the Serial library does not. Is there a simple way to check for a data buffer overflow on a hardware serial port?
1 Answer
A look at HardwareSerial_private.h
shows incoming bytes are always read (interrupt-based), regardless of what your code is doing. So we can't set up a hardware interrupt to notify us when the chip's RX register has overflowed, because such an interrupt would depend on overflow flags but these flags never become set because, like I said, bytes are always read. It also shows that while all incoming bytes are read, not all are added to the 64-byte Serial buffer i.e. a byte may be read but if the buffer is full, nothing else happens; it is simply read to clear hardware flags. So the only (direct) way I can think of is to constantly poll Serial.available()
in loop()
to check if the number of bytes available for reading is equal to 64. If this condition yields TRUE, then you may safely conclude that the Serial buffer is full and about to overflow. This should suffice:
void loop(){
//your code
if (Serial.available() == SERIAL_RX_BUFFER_SIZE){ // Just to be general, 64 bytes in most cases
//buffer is overrun, do what u will
}
}
You could make some changes to HardwareSerial_private.h
to get something like the overflow() method of SoftwareSerial. The relevant lines are:
if (i != _rx_buffer_tail) {
_rx_buffer[_rx_buffer_head] = c;
_rx_buffer_head = i;
}
The snippet above ensures that the current write position is not equal to the tail of the ring buffer (i.e. if we are about to overwrite a character in the buffer), before writing the incoming byte to the buffer. An else
block could be added to set some global variable to indicate overflow. This global variable would have to be cleared when Serial.read()
is called.
_rx_overflow
). After the lines in the link, addelse _rx_overflow=true;
. Add the functionoverflow
which returns the value of_rx_overflow
and sets it back to false. Pretty much the same way the softwareserial library did it.