Wednesday, 28 October 2015

Serial Buffer Sizes on Arduino

Often you want to leave the serial port alone to send or receive data under interrupts while the main loop of the code wanders off to do other things. If you don't get back often enough, the buffer may overflow. The standard buffer size in the Arduino IDE is 64 bytes (or only 16 for really small RAM boards). The code is in arduino/avr/cores/arduino/HardwareSerial.h and looks something like this:

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif

Altering that code to something like this can get you some more buffer space on larger processors.

#if !defined(SERIAL_RX_BUFFER_SIZE)
#if (RAMEND < 1000)
#define SERIAL_RX_BUFFER_SIZE 16
#else
// this test will create a large buffer on anything big
#if (RAMEND > 2200)
#define SERIAL_RX_BUFFER_SIZE 512
#else
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif
#endif

The downside of this is you will probably lose your mods when you next upgrade the IDE, and they won't move with your sketch code if you take it to another platform. I would like to be able to include these defines in my sketch, but I'm not sure how to get them snuck in at the right point in the build process.

Also, this file change won't translate to other processors that install their own code under the IDE, like the Teensy family. Paul Stoffregen has kept all his defines in the individual c code files like teensy/avr/cores/teensy3/serial1.c, where changing these should let you increase the size as needed:

////////////////////////////////////////////////////////////////
// Tunable parameters (relatively safe to edit these numbers)
////////////////////////////////////////////////////////////////

#define TX_BUFFER_SIZE 64 // number of outgoing bytes to buffer
#define RX_BUFFER_SIZE 64 // number of incoming bytes to buffer

I saw a note somewhere recommending power of two buffer sizes for efficiency in index arithmetic, and I can't really imagine going anything other than 64, 128, 256, 512, etc. anyway. In my current application I'm expecting to get packets of around 250 bytes back on request, so I will set the RX buffer size to 512 to be sure it's big enough to catch the whole packet. The request code is short, so I won't increase the size of the TX buffer.