How does the Arduino handle serial buffer overflow? Does it throw away the newest incoming data or the oldest? How many bytes can the buffer hold?

share|improve this question

migrated from stackoverflow.com May 27 '14 at 15:25

This question came from our site for professional and enthusiast programmers.

up vote 9 down vote accepted

For hardware serial ports you can see in HardwareSerial.cpp that the buffer size varies depending on the amount of RAM available on the particular AVR:

#if (RAMEND < 1000)
    #define SERIAL_BUFFER_SIZE 16
#else
    #define SERIAL_BUFFER_SIZE 64
#endif

For a software serial port in SoftwareSerial.h the receiver buffer size _SS_MAX_RX_BUFF is defined as 64 bytes. In both cases it stops attempting to insert received data into the queue when it is full, so you could get a mix to old and new data depending on how you're retrieving data from the queue.

Ideally it would be best to ensure the buffer always gets emptied in a prompt manner to avoid the buffer filling. Maybe take a look at timers and implementing a simple state machine if your problem is related to other code blocking the main loop.

share|improve this answer
    
I get the impression that if I transmit data to the Arduino and don't have an active "puller" of data on the Arduino side then if more data arrives than can fit in the buffer, it will be discarded. Can you confirm that? I had naively assumed that the transmitter would block until space available to hold the data became available. – Kolban Jun 19 '15 at 18:54

Receiving

You can see from the source of HardwareSerial that if an incoming byte finds the ring buffer full it is discarded:

inline void store_char(unsigned char c, ring_buffer *buffer)
{
  int i = (unsigned int)(buffer->head + 1) % SERIAL_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 != buffer->tail) {
    buffer->buffer[buffer->head] = c;
    buffer->head = i;
  }
}

I get the impression that if I transmit data to the Arduino and don't have an active "puller" of data on the Arduino side then if more data arrives than can fit in the buffer, it will be discarded. Can you confirm that?

Yes it will be discarded. There is no software or hardware flow control, unless you implement your own.

However with a 64-byte buffer, and receiving data at (say) 9600 baud, you get one byte every 1.04 ms, and thus it takes 66.6 ms to fill up the buffer. On a 16 MHz processor you should be able to check the buffer often enough that it doesn't fill up. All you really have to do is move the data from the HardwareSerial buffer to your own, if you don't want to process it right now.

You can see from the #if (RAMEND < 1000) check that the processors with 1000+ bytes of RAM get the 64-byte buffer, the ones will less RAM get the 16-byte buffer.


Sending

Data that you write is placed in a same-sized buffer (16 or 64 bytes). In the case of sending if the buffer fills up the code "blocks" waiting for an interrupt to send the next byte out the serial port.

If interrupts are turned off this will never happen, thus you do not do Serial prints inside an Interrupt Service Routine.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.