3

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?

  • The current code just ignores incoming data, if the buffer is full. So there is no way to see if the buffer has been "overflown". Though it wouldn't be hard to add this yourself. – Gerben Dec 29 '15 at 20:52
  • @Gerben - yes I'm aware. That is the question I'm asking: how would you add something to check? – Joel M. Dec 29 '15 at 21:07
  • Just add a single boolean variable to the class (e.g. _rx_overflow). After the lines in the link, add else _rx_overflow=true;. Add the function overflow which returns the value of _rx_overflow and sets it back to false. Pretty much the same way the softwareserial library did it. – Gerben Dec 30 '15 at 8:50
  • The HardwareSerial has actually two levels of RX data overflow. The first may occur if the ISR is locked out a longer period and the UART RX registers are not emptied in time. There is a special status flag for this (UCSR0A USART Control and Status Register A, Bit: DOR0 Data Overrun). The second level is the RX ring-buffer as described above. – Mikael Patel Dec 30 '15 at 17:01
3

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.