Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upSoftwareserial doesn't work at higher baudrates #2019
Comments
This comment has been minimized.
This comment has been minimized.
Oh, the 300 baud problems seem to be unrelated to SoftwareSerial. I just tried using a CP2102 USB->Serial convertor, and RX at 300 baud works perfectly. I suspect that the Arduino Serial convertor I was using before, was suffering from this Arduino bug as well. |
This comment has been minimized.
This comment has been minimized.
And it seems most of the TX problems were caused by an oversight in my test setup: When SoftwareSerial is transmitting at low baudrates, it disables interrupts for long periods of time, which cause incoming bytes at the HardwareSerial side to be dropped. I modified the sketch and test output in the first post to first receive all bytes and only then start transmitting them with SoftwareSerial, which fixes TX at lower rates (its still broken at 115200 at 8Mhz, though). |
Instead of using a lookup table with (wrong) timings, this calculates the timings in SoftwareSerial::begin. This is probably a bit slower, but since it typically happens once, this shouldn't be a problem. Additionally, since the lookup tables can be removed, this is also a lot smaller, as well as supporting arbitrary CPU speeds and baudrates, instead of the limited set that was defined before. Furthermore, this switches to use the _delay_loop_2 function from avr-libc instead of a handcoded delay function. The avr-libc function only takes two instructions, as opposed to four instructions for the old one. The compiler also inlines the avr-libc function, which makes the timings more reliable. The calculated timings directly rely on the instructions generated by the compiler, since a significant amount of time is spent processing (compared to the delays, especially at higher speeds). This means that if the code is changed, or a different compiler is used, the calculations might need changing (though a few cycles more or less shouldn't cause immediate breakage). The timings in the code have been calculated from the assembly generated by gcc 4.8.2 and gcc 4.3.2. The RX baudrates supported by SoftwareSerial are still not unlimited. At 16Mhz, using gcc 4.8.2, everything up to 115200 works. At 8Mhz, it works up to 57600. Using gcc 4.3.2, it also works up to 57600 at 16Mhz and up to 38400 at 8Mhz. Note that at these highest speeds, communication works, but is still quite sensitive to other interrupts (like the millis() interrupts) when bytes are sent back-to-back, so there still are corrupted bytes in RX. TX works up to 115200 for all combinations of compiler and clock rates. This fixes arduino#2019
This comment has been minimized.
This comment has been minimized.
That's exactly why I wrote AltSoftSerial... |
This comment has been minimized.
This comment has been minimized.
@PaulStoffregen Yeah, I think AltSoftSerial works more reliably at higher rates, but it also works on specific pins only and needs timers AFAIK, so it's not usable in all situations (so both libraries have their place and can co-exist, I think). |
This comment has been minimized.
This comment has been minimized.
Does AltSoftSerial run at the MIDI baudrate of 31250? I'm trying to swap SoftwareSerial out for AltSoftSerial (setup with the appropriate pins of 9 and 10) and seeing my data stream while using SoftwareSerial but not seeing anything when using AltSoftSerial. Edit: My apologies. Pilot error. The Arduino needed pins 9 and 8 (or 8 and 9). Either way, swapping SoftwareSerial for AltSoftSerial works like a champ while using the MIDI Library 4.1 Thanks! |
This comment has been minimized.
This comment has been minimized.
Not sure about AltSoftSerial, but this is definately not the right place to ask. Doesn't the library have it's own support forum/list/issuetracker? |
This comment has been minimized.
This comment has been minimized.
Since writing AltSoftSerial years ago, I've switched most of my development focus from AVR to ARM chips, where 3+ hardware serial ports are available. There's no issue tracker or other active development on AltSoftSerial, but it still works well (far better than SoftwareSerial, if you can spare the timer hardware). |
This comment has been minimized.
This comment has been minimized.
Just wanted to share, that I've solved this problem @38400 receiving from a serial GPS (which baud rate cannot be changed), by tweaking the delay_table. I knew it was a sync issue since the GPS worked well with physical serial. Just for reference the original values for Hope it helps. |
This comment has been minimized.
This comment has been minimized.
The delay table is entirely removed by the commit fixing this issue, so a recent 1.5.x and all 1.6.x versions should no longer have the delay table (and work with 38400 out of the box). I take it you're still using an older version, or perhaps have an old version of the SoftwareSerial library lying around? |
This comment has been minimized.
This comment has been minimized.
Oh man, I've been fighting with this for two days, you're absolutely right, I had a SoftwareSerial folder under libraries. I store my sketchbook location on a cloud based storage, and it must be left behind. The current library worked untouched. Thanks! |
Trying to use SoftwareSerial at 115200 on an Arduino Uno only gave me garbage output. After trying to fix the timings, things improved, but I've still not managed to fix everything.
To be able to reliably and repeatedly test the SoftwareSerial class, I
wrote a small python script. It talks to the Uno's USB serial and to
a separate USB serial convertor (I used this one and a
cp210x one, but any one should do).
The serial convertor is connected to pin 2 and 3 of the Uno, which
creates a SoftwareSerial object on those pins. The sketch on the Uno
then forwards data between SoftwareSerial and the regular Serial object.
Additionally, using some binary commands that are not forwarded, the
python script can tell the sketch to open and close the SoftwareSerial
port and specify the baudrate to use.
I tested all rates listed in the SoftwareSerial timing table and foundthat reception of the faster rates (and somehow, also 300 baud) failed.
For transmission, it's the reverse: Only the higest rates work, the
lower ones fail. Using gcc 4.8, things are even worse - none of the TX
rates works.
I tested all the rates listed in the SoftwareSerial timing table and
found that TX works every time (at 16Mhz) and fails at 115200 (at 8Mhz), but RX
fails at 115200 baud (at 16Mhz) and 38400 and up (at 8Mhz).
31250 baud also failed, but this appears to be a problem in the cp210x I
was using, using the Arduino USBSerial board 31250 worked (but 300 baud
failed...). When using gcc 4.8, RX baudrates from 28800 and up fail.
I tested the 1.5 branch with both the bundled gcc 4.3 version and a
locally compiled gcc 4.8 version and the master branch with just the
bundled 4.3 version. This was tested on a Uno, running at 16Mhz and at
8Mhz (using the prescaler register in the sketch below and setting the
cpu speed in boards.txt).
I'll see if I can fix this, but wanted to provide some documentation
about this issue already.
Here's the output from 1.5 with gcc 4.3 at 8Mhz.
Here's the python script I was using (requires python 3.3):
And the Arduino sketch: