SoftwareSerial unexpectedly low upper limit

Hi all,

This issue nearly ruined a project I made for a client. It was supposed to be an Arduino Uno talking to the computer via hardware serial, and to a peripheral device via software serial at 38,400 Baud (no servos, special interrupts or other potential sources of interference).

After much frustration I discovered that SoftwareSerial couldn't handle this speed, which is odd because everywhere I looked it says the limit is 57,600 or even higher. I finally resorted to an Arduino Mega with its extra hardware serials... still - ?

Here's a little test setup I made. Two Arduinos (Let's call then A and B) are connected to the PC. A has "empty sketch" uploaded, B has this sketch:

#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());
}

Pins RX and TX of A are connected to pin 2 and 3 of B. So in theory, anything sent to one of them from the PC should return from the other, right?

I opened monitors for both (using my own Serial Monitor Deluxe, heh) and it works as expected for 9,600 and 19,200 Baud. However, for 38,400 and 57,600 it only works one way - from B to A, where the Software Serial is the sender.

From A to B, where the Software Serial is the receiver, I get total garbage at these speeds.

At some point I guess I'll have to use a logic analyzer... :slight_smile: until then, can anyone give some input on this matter? Thanks!

There is nothing unexpected about this, and I understood 9600 is all software serial is good for, so I guess you were more lucky than most. If you really need the 38400, you have made the right choice in getting a Mega. No logic analyser needed

Nick_Pyner:
There is nothing unexpected about this, and I understood 9600 is all software serial is good for

Empirically I guess that's right, but it's not what it says here...
http://arduino.cc/en/Reference/SoftwareSerialBegin
And that's kind of an official source :wink:

igendel, from "my" experience, SS is a piece of crap - when it comes to "2-way" comms, such as in your loop in your first post. It's not worth messing with, despite what you may hear or find written. You need a chip with >1 h.w. UART if you really want to do what you attempted there. I switched over to the mega1284 chip, largely to get 2 Serial Ports that actually work right.

This issue comes up all the time, and although some people "say" it works, I seem to live in the other Twilight Zone, where it doesn't work. If you look at this recent thread, you'll see where the guy never responded after I asked him to do a real test.
http://forum.arduino.cc/index.php?topic=285527

I actually wish he had showed how to get it to work, and "proved" me wrong, but ....

oric_dan:
This issue comes up all the time, and although some people "say" it works, I seem to live in the other Twilight Zone, where it doesn't work.

Indeed it does come up all the time. This is because there are more people who actually find it doesn't work than there are those who just say it does, and it's not the first time the "official" reference leaves a bit to be desired.

Have a look at my SW Serial tests here - SoftwareSerial magic numbers - Libraries - Arduino Forum -

in my tests that had minimal overhead, no ISR's etc, 70-80K was the max feasible.
So in a real program divide that by 2 (4?) giving 38400 as max workable baud rate.

Heh, looks like I hit a hornet nest with this one :smiley: I'm extremely picky with the jobs I take, because I know from experience how things tend to not work in real life... but such a reputable Arduino library, who would have thought!

Thanks for all the feedback - the funny thing is that somehow I didn't find all these interesting posts in earlier searches. I'll test AltSoftSerial for future reference, too. Oh well, at least it'll make for a nice blog post!

robtillaart:
Have a look at my SW Serial tests here - SoftwareSerial magic numbers - Libraries - Arduino Forum -

in my tests that had minimal overhead, no ISR's etc, 70-80K was the max feasible.
So in a real program divide that by 2 (4?) giving 38400 as max workable baud rate.

I don't see how that thread actually bears on OP's problem. It appears to go to efforts to determine the most accurate timing for SS, but the real problem with SS is that it's plain unreliable in the context of "other" interrupts going on in a program, since any real-world program will not have "minimal overhead, no ISR's etc".

SS may work for very specific cases, eg maybe with receive-only from a GPS device, but for reliable 2-way comms as in the 1st post, and with other ISRs occurring, and at baudrates above maybe 9600, as already mentioned, forget it. As long as there are other interrupts going on, such as Serial, millis(), etc, these will ruin SS's accuracy.

I did actually accomplish something like this, but in the PIC world, and by having only a "single" finely-tuned ISR carefully coded in assembler, and with minimal overhead, and which handled "all" interrupts in the program. Therefore, when the soft-serial INT pin triggered, it's code would always have priority. I doubt this sort of thing can be done easily in the Arduino context.

So, best get a chip with multiple, real h.w. UARTs.

OTOH, there may be some classy way to use the mega chip timers or other peripherals to do a second Serial, as suggested in PaulS's post on the other thread.
http://forum.arduino.cc/index.php?topic=138497.msg1392275#msg1392275

... but such a reputable Arduino library, who would have thought!

Unfortunately, the more you use Ardunio, the more you realize that Team-Arduino is severely over-extended, and there are many bugs in the s.w., and it falls to the "user community" to fix most of them, and even so, they rarely get fixed in the IDE distributions. Case in point, the SD library in the IDE is [get this] 5-yo, and even though Bill Greiman the author updates his library constantly, this never gets put back into the IDE. Go figure.

I don't see how that thread actually bears on OP's problem. It appears to go to efforts to determine the most accurate timing for SS, but the real problem with SS is that it's plain unreliable in the context of "other" interrupts going on in a program, since any real-world program will not have "minimal overhead, no ISR's etc".

First during these tests I have come to the same conclusion as OP that Software Serial does not work at 115200, and that in practice 38400 is a maximum.

Furthermore, and I should have been more explicit in that, is that with the use of formulas iso lookup table one can use slightly "wrong" baud rates in SW serial that will match the factual baud rate better. E.g. if one arduino is 16Mhz (Crystal) and the other is e.g. 5% off (resonator) one can adjust the baud rate to compensate for these kind of mismatches.

I understand that, but still don't see that this solves OP's problem of doing reliable 2-way comms in a general-purpose real-world program. SS has to work properly in the context of "everything else" going on, which is where it seems to fall down.

I don't want to give away too much information without the client's permission, but I can assure you that there's not much going on in my system in terms of complexity. It's mostly simple requests going this way, and packets of info going that way as replies.

At the moment, it seems to me that the whole problem boils down to SoftwareSerial being unable to receive higher-baud communication in a reliable manner.

Ok, as long if it satisfies the requirements, but it's an open question as to where "reliable" communications begins and ends. I think if you add some new code to the program, then bamm, problems may suddenly appear. But for general 2-way comms, I think you begin to see the limitations.

Would be interesting to hear your experiences with AltSoftSerial as compared to SS, if you try it.

oric_dan:
Would be interesting to hear your experiences with AltSoftSerial as compared to SS, if you try it.

The original setup will require some tweaking for that, because the library provided by the seller is hard-coded for the SoftwareSerial library. I'll get on it soon.