(Software)Serial Killer

In me previous rant, I mentioned that even Arduino’s own SoftwareSerial library suffers from issues that make it unreliable. Here’s how you can see that for yourself.

The details of how I discovered it are less interesting – something didn’t worked, I investigated, voilà – but it almost cost me a job with a client, hence my anger and almost total lack of trust in libraries. This is not some improvised hack by a nobody from nowhere; SoftwareSerial is one of the few libraries that come built-in with the Arduino IDE itself!

To demonstrate the problem, we need to construct a communication cycle: send known data through a SoftwareSerial connection and see what we get on the other side. For completeness, the test should be done twice: once with the SoftwareSerial as listener and once as transmitter.

The easiest way to achieve that is to get two Arduino boards (NOT leonardos – these treat serial communications differently). Let’s call these boards A and B. Upload an empty sketch to A (just the setup and loop functions, with nothing in them). To B, upload this:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);

void setup() {
  Serial.begin(57600);
  mySerial.begin(57600);
}

void loop() {
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

This simple code echoes whatever it gets on the hardware serial to the software serial, and vice versa.

Now, connect the RX/TX pins of A to pins 2/3 of B, and connect both Arduinos to the PC.  You’ll need two serial monitor programs, one for each Arduino – I suggest my own Serial Monitor Deluxe ;-). Adjust the monitors to the same baud rate as in the Arduino code (57,600 in this case), and send strings back and forth to see what you get. Here’s what I got (click to enlarge):

SoftwareSerial issue demonstrated
SoftwareSerial issue demonstrated

The window on the left is connected to B, the one on the right to A. When B sent something (i.e. the SoftwareSerial component is transmitting), all is well. When A is sending (the SoftwareSerial component is supposed to be receiving), we get complete garbage.  This behavior starts at relatively low baud rates, so perhaps the safe upper limit in the standard Arduino Serial bitrates is just 19,200. Why didn’t anyone state that anywhere in the official resources?

Testing AltSoftSerial

After raising the issue on the Arduino forums, I discovered that I am neither the first nor the last to notice this problem. One of the suggestions was to try using the AltSoftSerial library, which takes a whole different approach to software serial communications. It worked better than SoftwareSerial, but it too started having hiccups at higher speeds:

AltSoftSerial issues at higher baudrates
AltSoftSerial issues at higher baudrates

Also, AltSoftSerial only works with pins 8 & 9 of the Arduino, and makes use of timer 0 of the microcontroller, which may be problematic if you (or any libraries you use) need it for something else.

So, if you need reliable high-speed serial communication in your Arduino system, do everything you can to use the Hardware serial. The Arduino Mega has four of them, and the Arduino Leonardo has an “extra” one too, because the “regular” serial communication with the PC is done using its USB capabilities. If you have no choice but to work with software serial, then keep the speeds low, remember the limitations and test rigorously every aspect of the communications in the actual system before moving on.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.