NewSoftSerial 9 is now available. This is a major new release that replaces all the performance path pin reads and writes with direct Port I/O.
What does that give you? Well, a couple of things. Most importantly, it makes NewSoftSerial more compatible with the latest Arduino release. Changes to timings of digitalRead and digitalWrite in Arduino 0015 broke NewSoftSerial at higher baud rates. All software serial libraries are timing sensitive, and even a microsecond or two change in a function’s timing can introduce enough error to fatally corrupt serial transmissions. By using direct port I/O and retuning all the timing tables, we avoid problems caused by the longer digitalReads and digitalWrites. Furthermore, the library should be more immune to future changes of this kind.
Direct port I/O is amazingly fast — about 10-25 times faster than the equivalent call to digitalRead/Write. Because of this, NewSoftSerial 9 is able to operate reliably at higher baud rates than in the past. In my test suite, I am now able to get reliable RX at speeds up to an unprecedented 57.6K baud on a 16MHz processor and 31.25K baud at 8MHz*. Because the performance paths no longer use digitalRead/Write, they are less sluggish and much easier to tune to the higher speeds.
*These figures are about 70% higher than NewSoftSerial 8 with Arduino 0014. These were measured using USB-powered Arduinos running a prerelease v. 0016 copy of the software, which optimizes the timer 0 overflow counter — an important contributor to software serial performance. I/O was tightly controlled to avoid overflow, which can easily occur at high baud rates when you have no hardware flow control.
Please let me know what you think. The new version is here.
What’s next for NewSoftSerial? Well, there are a number of things being asked for:
- Arduino Mega support
- Signal inversion option
- RTS/CTS flow control option
- Configurability, i.e. “E, 7, 1” style parity, data and stopbit configuration.
What are you most interested in? Let me know here.
Mikal
Blake Dayton
15 years ago
Wow, looks impressive. Great work!
Mikal
15 years ago
Why, thank you!
Mikal
Adam Aitoumeziane
15 years ago
I would love support for the Mega, and RTS/CTS capability.
Jake
15 years ago
Hello Mikal,
I want to use the possibility of interrupt driven receives, but I can’t seem to figure out how to make that happen using your library. I would be greatful if you could send me an example of how to set up an interrupt on RX with use of your great library.
Thanks in advance,
Jake.
Mikal
15 years ago
Are you using a TTL Serial device? If so the connection is pretty simple:
1. Hook the device’s TX line to pin you designate as your “RX” pin.
2. Hook the device’s RX line to your “TX” pin.
Then, in software, create a NewSoftSerial object like this:
Then in setup(), use the begin method to set the baud rate:
The NewSoftSerial example programs show how to proceed from there.
Mikal
Sander
15 years ago
For a long time I used SoftwareSerial to communicate with my LCD, however sometimes it caused strange symbols to show up on the display (I guess due to incorrect timing). With your library these problems disappeared into thin air! Thanks again!
Zachary Zimmerman
15 years ago
I am working on a project that could greatly benefit from Arduino Mega support. Thanks!
Mikal
15 years ago
Hey, thanks for sharing that, Sander. What baud rate were you using to talk to the LCD?
Derrick Whittet
15 years ago
Hmmmm; just downloaded and tossed this into arduino/hardware/libraries; and on compile I got “NewSoftSerial.cpp:54: warning: only initialized variables can be placed into program memory area”
Just a heads up. Seems to be working fine, though I’ve not had a chance to really test it properly yet.
Mikal
15 years ago
Thanks, Derrick. Yes, I should have made it more clear that you will get that warning until a compiler bug in avr-gcc is fixed. Any library that makes use of flash data generates that error message. Several of us spent many hours trying to figure out how to work around that problem, but it looks like with stuck with it for now.
Mikal
Ron
15 years ago
Support for inverted signals would really be great. I have some serial LCDs (bought to use with Basic Stamps) that I can’t use with the Arduino.
Thanks for your efforts!
Ron
15 years ago
Just like Derrick, I downloaded, installed on arduino 15. Tried to compile the NewSoftSerialTest. It says Error building library “NewSoftSerial”, below it says,’C:\Documents…\NewSoftSerialTest.hex’:no such file
What did i do wrong? Thanks.
John Dugan
15 years ago
Very nice progress. Thanks for your effort. Looking forward to using the new version, I was getting some checksum errors with TinyGPS in the past, perhaps the speedier NSS will alleviate some of that?
Flow control would be nice, as I’d like to use that ability on the FTDI VDrive2 for USB Datalogging.
Software inversion would also be nice, but I’ve had good success using a basic NPN transistor (ex. 2N3904) for signal inversion, so that might be lower on my list.
Tze-Chien Chu
15 years ago
Thanks for your nice program. I use the NewSoftSerial9 to read 2 Uart. I use a Flag , so each time only 1 uart are checked. But since the 2 UART timing are close. So the success rate to read the data is not very high.(I think it is beacuse of enable 2 SoftSerail and even I don’t want to check theother UART, the library still do that for me).
Can I temporay turn off the Not Reading UART and Watch the Reading UART ?
Tze-Chien Chu
15 years ago
Forget my previous post. I think it is my program’s bug. It works fine in one UART but after add another UART it became not stable. But it is not the problem of the NewSoftSerail. Forgive me.
Mikal
15 years ago
Thanks, John. NSS 9 may indeed help your checksum problems. What baud rate are you using? Another cause of checksum errors is overflow. Are you sure you’re checking the serial port often enough? Newer versions of NewSoftSerial have an overflow() method to tell you whether you are overflowing.
Mikal
Mikal
15 years ago
No problem, Tze-Chien! Let me know how it works out. I like to see more dual-port activity with NewSoftSerial.
Mikal
Mikal
15 years ago
Ron–
Geez, I don’t know. It compiles fine for me. Did you put the library in the right place?
Mikal
Ron
15 years ago
Mikal,
I added it here: C:\arduino-0015\hardware\libraries\
I will also check using a PC, maybe there’s something wrong with my laptop.
Thanks,
Ron
jjrosent
15 years ago
RTS/CTS greatly needed.
Joe
15 years ago
Hello,
Using the NewSoftSerial to read data from a device @57600.
I connect one pin of the Arduino to the RX of the Device and i connect the ground of the arduino to the ground pin of the Serial Device.
I get some data, but it is not the same as on a direct
connection to a PC Terminal via e.g. Serial/USB Cable.
Is this a timming issue?
What could i check to fix this?
(Arduino Version 0016 and NewSoftSerial9)
Thank you all in advance for your support!
I get following HEX Data with NewSoftSerial but on the PC
i get e.g. Hex 7E instead of 40 a 7E HEX Data…
1
0
0
40
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
1
0
0
40
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
1
0
0
Best Regards,
Joe
Mikal
15 years ago
Joe,
I’m pretty sure all the FFs can be explained by the fact that read() returns -1 (FF) if no data is available. So instead of doing
use something like
Of course that doesn’t explain why you get 40 instead of 7E. If your transmitting partner transmits in rapid bursts, software serial may have a hard time keeping up at high baud rates. Have you tried disabling the timer tick with
Of course that’s not an optimal solution, because it disables millis().
Mikal
Henrik
15 years ago
Hello,
Great work with the NSS9. I’m currently trying to use the NSS9 with a hardware that’s sending inverted signals. How can I configure the library to work with this?
As I understand there are two things that need to be done.
1. the interupts need to be when the signal goes from low to high instead of high to low.
2. All the bits need to be inverted.
Thankful for any help.
Regards,
Henrik
Mikal
15 years ago
Thanks, Henrik. Logical inversion is a common request. I am working on it now. Check your email.
Mikal
Iain McFarlane
15 years ago
I really need this to be able to do 7 bit
What code do I need to change to do this?
I have tried this but without success
// Read each of the 8 bits
– for (uint8_t i=0x1; i; i <<= 1)
+ for (uint8_t i=0x1; i; i <<= 0x7)
Mikal
15 years ago
Iain,
The loop would look more like this:
That said, remember that most 7-bit serial uses a parity bit in addition to the stop bit. Make sure you account for that. Please let me know how you progress!
Mikal
Iain McFarlane
15 years ago
This is as far as I have got so far:
// Read each of the 8 bits
// for (uint8_t i=0x1; i; i <<= 1)
for (uint8_t i=0x1; i != 0x8; i <<= 1)
{
tunedDelay(_rx_delay_intrabit);
DebugPulse(13, 1);
uint8_t noti = ~i;
if (rx_pin_read())
d |= i;
else // else clause added to ensure function timing is ~balanced
d &= noti;
}
// skip the stop bit and parity bit
tunedDelay(_rx_delay_stopbit *2); //double the delay so that we cover both bits
// skip the stop bit
// tunedDelay(_rx_delay_stopbit);
DebugPulse(13, 1);
If I just add a second tunedDelay I get compile errors something about needing registers 28, 29 …
However I don’t get any decent data out of the port.
When I put a 1 in then I get two characters one with a DEC value of 1 and one with a DEC value of 7.
2 gives a 2 and a 7
3 gives a 3 and a 6
4 gives a 4 and a 7
5 gives a 5 and a 6
6 gives a 6 and a 6
7 gives a 7 and a 7
8 gives just a 7
9 gives a 1 and a 6
This is consistent but completely rubbish to me.
Switching back to the proper version with 8-bit works perfectly ;-)
Iain
Mike V
15 years ago
Mikal – thanks heaps for your excellent work with this library. I am also after logical inversion for controlling some motors with inbuilt serial controllers – is there any chance you could forward me the email you sent to Henrick :)
Cheers,
Mike V
Mikal
15 years ago
Iain,
You changed
Change it back. :)
Mikal
Mikal
15 years ago
Ok. :)
Mikal
yves
15 years ago
hi mikal
I seem to have problems with your library… I can recieve serial communication just fine,
but if I send something, it seems to only send the last 1-3 characters…
bluetooth.println(“INQUIRY 6”); comes back as “Ye6”.
What could be the reason for that?
Thanks for your help…
yves
David
15 years ago
Hi Mikal,
First, thanks so much for your work on “newsoftserial”. It’s greatly appreciated!
I’m running into a small problem reading a stream of packets from both the UART pins and the soft-serial pins. Here’s the link to the discussion:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1246726142
I was wondering if you had any advice? Is it possible that UART serial interrupts and soft-serial interrupts can’t/won’t play nice? Do you have any suggestions?
Thanks again,
David
Mikal
15 years ago
Yves–
“Ye6”? Where does the “e” come from? Are you sure the baud rates are matching at both ends? What software’s running on the receiving end?
Mikal
Mikal
15 years ago
Hmm…
David, let me check that thread out…
Mikal
David Palmer
15 years ago
I have a few minor changes to NewSoftSerial v9. Specifically, adding a ‘sparebits’ argument to the begin() method for things like parity bits and extra stop bits. (The current version gets confused at 8 bits + parity). It doesn’t test whether the parity check is valid, but at least it doesn’t confuse it with a stop bit. (And it doesn’t do parity transmission properly, but it’s a start.)
It also adds a ‘deactivate()’ method, which is necessary because when the port is active, it loses ticks in the millisecond/microsecond counter whenever a character comes in. Therefore you have to deactivate the port to do accurate timing.
Where can I send the diffs so you can roll it into v10? (Contact me at the email I left in the mail entry for reply.)
Mikal
15 years ago
David Palmer—
I would welcome an opportunity to see your suggested changes.
Mikal
Joachim
15 years ago
Hi Mikal, you’re a hero!
I am using NSS to send NMEA data from a compass. However the loop is terminated and the board resets when I print a string to the NMEA port. Since print is inherited and not inside NSS, I cannot understand why this is a problem. Once I comment out the print statement, the sketch runs fine. The string is also printed fine with Serial.print.
I thought it could be a RAM problem, but the behaviour is the same with the 328 as the 168.
Best regards, Joachim
Nathan
15 years ago
I am trying *desperately* to get some sort of serial communication working using the following scheme:
Baud Rate: 9600 NRZ
Serial Bit Format: 1 Start Bit
8 Data Bits
1 Mode Bit (basically a 9th data bit, not parity bit)
1 Stop Bit
11 Bits Total
LSB MSB
Start 0 1 2 3 4 5 6 7 Mode Stop
It’s a goofy ass protocol, I’ll admit – but I’m not the one that came up with it :)
Basically it’s a 9N1 format. I haven’t had much luck getting the Arduino hardware serial drivers to do this, and my AVR mojo isn’t strong enough to modify your code. Any chance to see this sometime soon? If not, can you give me enough information to get started?
To be honest, if $50 or so would motivate you to get this feature in the next week or so, my PayPal account is ready and waiting :)
Nathan
15 years ago
Actually, ignore the above. I think I may have gotten it… Will test tomorrow and see! Thanks :)
Len
15 years ago
Just downloaded NSS9. Is there a usage description somewhere? Function definition etc? New at this stuff so forgive me if it’s obvious.
Thanks
Len
Mikal
15 years ago
Len, it might be instructive to check the NewSoftSerial examples that come with the distribution. Beyond that and what you read on this website and in the Arduino forum, there isn’t much else (yet).
Mikal
Stephen
15 years ago
G’day Mikal,
I want to add support for 10Mhz and was wondering how you came up with the delay figures in the DELAY_TABLE
Thanks,
Stephen…
Mikal
15 years ago
Stephen, it was a combination of massaging some values of got from AFSoftSerial, looking at waveforms on a little logic analyzer, trial and error, and lots of testing. :) Good luck!
Mikal
Stephen
15 years ago
@Mikal
sigh….that’s what I was afraid of, it would seem that I have some playing around to do :)
I think I’ll start off with some figures in between yours and take it from there.
I’ll send you through the patches when I’m done.
Stephen..
Stephen
15 years ago
Hi Mikal,
I couldn’t find any contact info on the your website to send you through the patch for 10Mhz, so If you can ping me through an email at the address I’ve put on my comment I’ll send the patch through.
Regards,
Stephen….
aminosan
15 years ago
Hello Mikal,
We writing article about Arduino.
And we want to introduce about NewSoftSerial and TinyGPS(with sketch, this site’s URL) in that article.
So can we about those?
Regards,
aminosan[The-MenZ]
Mikal
15 years ago
Aminosan-
I would be happy to see some writing about NewSoftSerial and TinyGPS. Please send a link when you are done!
Best wishes,
Mikal
aminosan
15 years ago
Mikal,
Thank you so much!
If when published that magazine,
I’ll send a link your E-Mail!
Best Regards,
aminosan[The-MenZ]
techyjt
15 years ago
I have a question. Is the a reason why the max read buffer is 64? I have a need to send and recieve up to 256 bytes per transfer at times. I can change the header to suit my needs, but I wanted to make sure there was not a reason. I ave the Arduino with 328 chip in it, and I have just started doing some dev and research with the Arduino.
Thanks.
Mikal
15 years ago
Hi techyjt–
It’s more a matter of history. The 64-byte buffer is a matter of history. It is used in Hardware Serial and in AFSoftSerial, the parent for NewSoftSerial. There’s no reason why you can’t change it, but there’s also not a compelling reason that I know to do so.
Mikal