NewSoftSerial

A New Software Serial Library for Arduino

News: NewSoftSerial is in the core!  Starting with Arduino 1.0 (December, 2011), NewSoftSerial has replaced the old SoftwareSerial library as the officially supported software serial library.  This means that if you have 1.0 or later, you should not download this library.  To port your code to 1.0, simply change all NewSoftSerial references to SoftwareSerial.

NewSoftSerial is the latest of three Arduino libraries providing “soft” serial port support. It’s the direct descendant of ladyada’s AFSoftSerial, which introduced interrupt-driven receives — a dramatic improvement over the polling required by the native SoftwareSerial.

Without interrupts, your program’s design is considerably restricted, as it must continually poll the serial port at very short, regular intervals. This makes it nearly impossible, for example, to use SoftwareSerial to receive GPS data and parse it into a usable form. Your program is too busy trying to keep up with NMEA characters as they arrive to actually spend time assembling them into something meaningful. This is where AFSoftSerial’s (and NewSoftSerial‘s) interrupt architecture is a godsend. Using interrupt-driven RX, your program fills its buffer behind the scenes while processing previously received data.

Improvements

NewSoftSerial offers a number of improvements over SoftwareSerial:

  1. It inherits from built-in class Print, eliminating some 4-600 bytes of duplicate code
  2. It implements circular buffering scheme to make RX processing more efficient
  3. It extends support to all Arduino pins 0-19 (0-21 on Arduino Mini), not just 0-13
  4. It supports multiple simultaneous soft serial devices.*
  5. It supports a much wider range of baud rates.**
  6. It provides a boolean overflow() method to detect buffer overflow.
  7. Higher baud rates have been tuned for better accuracy.
  8. It supports the ATMega328 and 168.
  9. It supports 8MHz processors.
  10. It uses direct port I/O for faster and more precise operation.
  11. (New with version 10).  It supports software signal inversion.
  12. (New) It supports 20MHz processors.
  13. (New) It runs on the Teensy and Teensy++.
  14. (New) It supports an end() method as a complement to begin().

*But see below for an important caveat on multiple instances.
**Be circumspect about using 300 and 1200 baud though. The interrupt handler at these rate becomes so lengthy that timer tick interrupts can be starved, causing millis() to stop working during receives.

Using Multiple Instances

There has been considerable support for an library that would allow multiple soft serial devices. However, handling asynchronously received data from two, three, or four or more serial devices turns out to be an extremely difficult, if not intractable problem. Imagine four serial devices connected to an Arduino, each transmitting at 38,400 baud. As bits arrive, Arduino’s poor little processor must sample and process each of 4 incoming bits within 26 microseconds or else lose them forever. Yikes!

It occurred to me, though, that multiple instances could still be possible if the library user were willing to make a small concession. NewSoftSerial is written on the principle that you can have as many devices connected as resource constraints allow, as long as you only use one of them at a time. If you can organize your program code around this constraint, then NewSoftSerial may work for you.

What does this mean, exactly? Well, you have to use your serial devices serially, like this:

#include <NewSoftSerial.h>

// Here's a GPS device connect to pins 3 and 4
NewSoftSerial gps(4,3);

// A serial thermometer connected to 5 and 6
NewSoftSerial therm(6,5);

// An LCD connected to 7 and 8
NewSoftSerial LCD(8,7); // serial LCD

void loop()
{
  ...
  // collect data from the GPS unit for a few seconds
  gps.listen();
  read_gps_data();  // use gps as active device
  // collect temperature data from thermometer
  therm.listen();
  read_thermometer_data(); // now use therm
  // LCD becomes the active device here
  LCD.listen();
  LCD.print("Data gathered...");
  ...
}

In this example, we assume that read_gps_data() uses the gps object and read_thermometer_data() uses the therm object. Any time you call the listen() method, it becomes the “active” object, and the previously active object is deactivated and its RX buffer discarded. An important point here is that object.available() always returns 0 unless object is already active. This means that you can’t write code like this:

void loop()
{
  device1.listen();
  if (device1.available() > 0)
  {
    int c = device1.read();
    ...
  }
  device2.listen();
  if (device2.available() > 0)
  {
    int c = device2.read();
    ...
  }
}

This code will never do anything but activate one device after the other.

Signal Inversion

“Normal” TTL serial signaling defines a start bit as a transition from “high” to “low” logic.  Logical 1 is “high”, 0 is “low”.  But some serial devices turn this logic upside down, using what we call “inverted signaling”.  As of version 10, NewSoftSerial supports these devices natively with a third parameter in the constructor.

NewSoftSerial myInvertedConn(7, 5, true); // this device uses inverted signaling
NewSoftSerial myGPS(3, 2); // this one doesn't

Library Version

You can retrieve the version of the NewSoftSerial library by calling the static member library_version().

int ver = NewSoftSerial::library_version();

Resource Consumption

Linking the NewSoftSerial library to your application adds approximately 2000 bytes to its size.

Download

The latest version of NewSoftSerial is available here: NewSoftSerial12.zip.  Note: don’t download this if you have Arduino 1.0 or later.  As of 1.0, NewSoftSerial is included in the Arduino core (named SoftwareSerial).

Change Log

  1. initial version
  2. ported to Arduino 0013, included example sketch in package
  3. several important improvements: (a) support for 300, 1200, 14400, and 28800 baud (see caveats), (b) added bool overflow() method to test whether an RX buffer overflow has occurred, and (c) tuned RX and TX for greater accuracy at high baud rates 38.4K, 57.6K, and 115.2K.
  4. minor bug fixes — add .o file and objdump.txt to zip file for diagnostics.
  5. etracer’s inline assembler fix to OSX avr-gcc 4.3.0 interrupt handler bug added.
  6. ladyada’s new example sketch, fix to interrupt name, support for 328p.
  7. etracer’s workaround is now conditionally compiled only when avr-gcc’s version is less than 4.3.2.
  8. 8 MHz support and flush() and enable_timer0()  methods added
  9. digitalread/write scrapped in favor of direct port I/O.  Revised routines now get perfect RX up to 57.6K on 16MHz processors and 31.25K on 8MHz processors.
  10. inverted TTL signalling supported.  20MHz processors supported.  Teensy and Teensy++ supported.  New end() method and destructor added to clean up.
  11. added listen() method to explicitly activate ports.
  12. warn users about 1.0 conflict

Acknowledgements

Many thanks to David Mellis, who wrote the original SoftwareSerial, and to the multi-talented ladyada, whose work with AFSoftSerial is seminal.  Ladyada also provided the “Goodnight, moon” example sketch, fixed a problem with the interrupt naming (see v6) and tested NSS with the 328p.

Thanks also to rogermm and several other forum users who have tested NewSoftSerial and given useful feedback.

The diligent analysis of forum user etracer yielded the root cause of a tricky problem with NSS on OSX.  A bug in avr-gcc 4.3.0 causes the compiler to fail to generate the proper entry and exit sequences for certain interrupt handlers.  etracer identified the problem and provided an inline workaround.  etracer’s fix is in NSS 5.

User jin contributed a large body of work based on NSS and identified a potential problem that could result in data loss (fixed in NSS 5).  jin also made a variant of NSS that supports 4-pin serial, with the additional pins providing a very nice RTS/CTS flow control.  We may see this in NSS in the near future.

Thanks to Garret Mace, who contributed the delay tables for 20MHz processors and claims that he can send and receive at 115K baud.  Cool!

Thanks to Paul Stoffregen, both for his fine work with Teensy and Teensy++, and for contributing some useful suggestions that help NewSoftSerial run on them without modification.

I appreciate any and all input.

Mikal Hart

Page last updated on July 3, 2013 at 7:37 pm
647 Responses → “NewSoftSerial”

  1. Mikal

    12 years ago

    @Harald,

    What is mySerial connected to? That delay(2000) line is ominous. It will almost certainly cause data coming from mySerial to be missed.


  2. Simon

    12 years ago

    Hi Mikal

    I have been chasing down a problem of changing the buffer size see :-

    http://arduino.cc/forum/index.php/topic,128544.0.html

    You may like to consider adding the change or commenting on the buffer size in the header.

    … Simon


  3. pabloxid

    11 years ago

    Hi.

    In my experience, the official softwareSerial Arduino library performs very well, but has a couple of drawbacks, both related to the delay table that it’s based on:

    1) it does not support arbitrary baudrates, such as 3600, 5500, etc.

    2) it’s based on a delay table so, the lower the baudrate, the higher the wasted CPU time, to the point that, for example at 2400 or 1200 baud, if you receive a constant stream of data, the processor becomes unusable.

    To overcome this pair of constraints, I made a small modification that worked very well in my ATtiny85, in wich I use a timer to generate timing, instead of a delay table.

    Unfortunately, my code is not neat enough to be ported to any micro, but I hope you can appreciate the idea and implement it in future releases of this library.

    Here is the link: http://www.pablogindel.com/images/SoftSerial.rar

    Regards,
    P.G.


  4. Bernard

    11 years ago

    I Mikal,
    I have carefully read Marc’s post and your answer so my question is : what object.available() is used for ?
    Can you explain me the difference between your example doing nothing and the Arduino example doing something ?
    Arduino :
    void loop()
    {
    // There is no objectname.listen()
    if (mySerial.available())
    Serial.write(mySerial.read());

    Yours :
    void loop()
    {
    device1.listen();
    if (device1.available() > 0)
    {

    Looking forward to reading you.
    Best regards.
    Bernard.


  5. Ray

    11 years ago

    Does this library support the same extensions made to the HW serial support where the begin method supports a second argument to set the mode (such as SERIAL_8N2 to set 8-bit, no parity, 2-stop bits)?


  6. Ray

    11 years ago

    I’m interfacing with a device that uses 1 start-bit, 8-bit data, no parity and 2 stop-bits. Does the SoftwareSerial library support configuration for 2 stop-bits, as the hardware Serial now does via the optional second initialization parameter that is used to set the mode (such as SERIAL_8N2)?


  7. Attilio

    11 years ago

    I’m using SoftwareSerial with 8mHz atmega328 and I experiencing problems in communicating.

    I summarized with the code attached below. If I use hw Serial the sketch work as expected.

    If I use SoftwareSerial only the first few bytes (2 or 3 bytes) are replied correctly and the remaining are garbled.

    Any idea of the problem?

    Thanks for yours help
    Attilio

    #include
    #include “SoftwareSerial.h”

    #define SWRXPIN 5
    #define SWTXPIN 6

    SoftwareSerial debug(SWRXPIN,SWTXPIN);

    //#define debug Serial

    void setup() {

    debug.begin(9600);
    debug.println(“starting modem”);
    }

    void loop() {
    char r;
    if (debug.available() > 0) {
    r = debug.read();
    debug.print(r);
    }

    }


  8. Mikal

    11 years ago

    Thanks Simon.


  9. Mikal

    11 years ago

    Thanks pabloxid. I love timer-based delays, but the problem is that they don’t work very well at higher baud rates in “busy” systems. If you rely on timers, you also allow for the possibility that other timers and devices might cause the timing to be delayed enough to inject corruption into the system. But I agree that it’s a better scheme at low baud rates. Thanks for


  10. Mikal

    11 years ago

    Bernard,

    I believe those should normally be equivalent. available() is a method which returns the number of characters available to be read. In the top example, the code is checking to see if this value is non-zero. In the bottom, it’s checking to see if it’s greater than zero. If you have only one soft serial device in the system, it doesn’t matter if you call .listen() or not.


  11. Mikal

    11 years ago

    @Ray, no, I’m afraid not. I would like those, but no, it doesn’t currently.


  12. Mikal

    11 years ago

    @Attilio,

    Hmm.. I can’t see why that wouldn’t work. Is there any hardware collision?


  13. Attilio

    11 years ago

    @Mikal

    no hardware collisions: I’ve simply an atmega328p on a breadboard, 8MHz internal oscillator, an usb to serial converter.
    The breadboard is powered with 3V.

    My fuses:

    atmega328bb.bootloader.low_fuses=0xE2
    atmega328bb.bootloader.high_fuses=0xDA
    atmega328bb.bootloader.extended_fuses=0x07

    avrdude -c [programmer] -p m328p -U lfuse:w:0xe2:m -U hfuse:w:0xda:m -U efuse:w:0x07:m

    greetings
    Attilio


  14. pabloxid

    11 years ago

    @Mikal,

    I understand your point. Perhaps the best solution would be to use a timer at low or arbitrary baudrates, while keeping a delay-table for high baudrates, integrating both implementations in a single library?


  15. Sajid

    11 years ago

    Hi,
    thanks for such a great library , i used it to communicate several Arduino but the problem i am facing is that the data corrupts after some intervals of data as show in the below image, can you please tell me how to solve this issue, i am looking forward for your reply.thanks

    https://mail-attachment.googleusercontent.com/attachment/u/0/?ui=2&ik=58f2ad39b5&view=att&th=13ba033fb08fcac3&attid=0.1&disp=inline&realattid=f_har6p2m20&safe=1&zw&saduie=AG9B_P-HEsbSzOf0c1t9f7IJF-lX&sadet=1355602489931&sads=GYIyurJyjUKR62_UjLfjxXENWj4&sadssc=1


  16. Mikal

    11 years ago

    Sorry, I can’t see that image Sajid. It’s not publicly shared.


  17. Sajid

    11 years ago

    Hi,
    thanks for such a great library , i used it to communicate several Arduino but the problem i am facing is that the data corrupts after some intervals of data as show in the below image, can you please tell me how to solve this issue, i am looking forward for your reply.thanks

    http://oi45.tinypic.com/2ikxoph.jpg


  18. Deborah O'Connor

    11 years ago

    I am so confused…
    I have Arduino Uno R3, IDE 1.0.3 and a peice of code using a GSM shield…
    I keep reading confused things about NewSoftSerial and SoftwareSerial….
    which is “new”, which goes in my library?, which include file do I use….
    is it on Arduino or in the library?
    Examples all say “newsoftserial” but my IDE didn’t compile until I changed to SoftwareSerial.h…
    Are the calls still SoftwareSerial ?
    I read everything I can get my eyes on but in this case it has been just a source of confusion.
    Thanks much.


  19. silky

    11 years ago

    hello
    Iam facing serial overflow problem with my programme kindly help me getting out of this.


  20. Mikal

    11 years ago

    @Deborah O’Connor,

    You shouldn’t bother with the NewSoftSerial library at all if you are using Arduino >= 1.00. That library is now part of the Arduino core, renamed to SoftwareSerial.


  21. Mikal

    11 years ago

    @silky,

    The only thing I can tell you about overflow is that you are not reading your serial port often/fast enough. In between reads, make sure you don’t do any delay() calls, writes to Serial port, or especially not calls to slow libraries like SD card readers/writers.


  22. doug lyon

    11 years ago

    How do I get the bluetooth examples working?
    BluetoothShield Demo Code Slave.pde writes:
    #include //Software Serial Port

    and uses it…but now it is not supposed to use it, right?

    So, what do we do to get example code to work?


  23. Mikal

    11 years ago

    Older sketches that use newsoftserial can be easily ported simply by changing all references to “NewSoftSerial” to “SoftwareSerial”.


  24. yenni alejandra

    11 years ago

    ola tengo una pregunta es que en mi caso conectaria dos dispositivos el zigbee y un sensor de color se puede usar la libreria nombrarla 2 veces para diferentes pines


  25. william

    11 years ago

    I do not quite get the multiple port and listen() function. If I understand you have to listen for some time before the port is available. So with two ports, and only one able to listen at any given time, how would you stop data being missed on the second port? Would something like
    port1.listen();
    while(port1.IsAvailable() == false); //spin
    int val = port1.Read();

    make sense to try to optimize the time spent waiting for the port?


  26. Mikal

    11 years ago

    Hi william,

    There is indeed no reliable way to ensure that you don’t miss data on the “other” port. The multiple soft port paradigm is most useful when one of the devices is continually transmitting an updated status stream that is not critical to miss. Or a sensor that you can synchronously query for data. But it’s not very useful when both devices might unpredictably deliver asynchronous mission-critical data.

    Example: Port 1 is a Bluetooth modem that may at any time deliver a command from a remote controller. Port 2 is a GPS unit or a digital humidity sensor.

    You’d configure your program to always listen() to the Bluetooth modem, but when it received the command to report back GPS (or humidity) information, you’d shift to the second port and listen() just long enough to gather whatever data is pertinent.

    Does that make sense?


  27. Paulo Coutinho

    11 years ago

    Hi man,

    I dont understand one thing. I need connect 10 serial RFID to my arduino, and each RFID sensor can receive information at same time, because each sensor will be in one door here. I can use your library to manage this 10 serial sensor at same time? The link of RFID reader is this: http://www.ebay.com/itm/Arduino-UART-125Khz-EM4100-RFID-Card-Key-ID-Reader-Module-RDM6300-RDM630-/110987494834 — Thanks


  28. Mikal

    11 years ago

    @Paulo, I’m having a hard time understanding the utility of connecting 10 RFID modules to the same Arduino. Why not just connect one module and have it understand 10 different cards? In any case, no, I’m sorry to say that I can’t see how such a design would work with NewSoftSerial (now SoftwareSerial). SoftwareSerial can only listen to one RFID reader at a time.


  29. Michael Doerr

    11 years ago

    Hi Mikal,

    Very good library: the inverse logic code saved me a hardware inverter
    im my LED sign project. But I think I’ve found a small bug in function
    SoftwareSerial::setTX when inverse logic is being used. The very first
    start bit does not work right without the following patch applied:

    msd$ diff SoftwareSerial.cpp_orig SoftwareSerial.cpp
    358c358
    digitalWrite(tx, _inverse_logic ? LOW : HIGH); // pullup for normal logic!

    Thanks a lot.


  30. Mike

    11 years ago

    Is there any chance an Arduino Due compatible version could be promulgated?


  31. doug

    11 years ago

    Hello, does this have any ability to do hardware handshaking?

    I have an old HP pen plotter and the usb serial cable isn’t handshaking so it ends up overflowing the buffer of the plotter and it makes a mess. I was thinking about using the adruino as a print spooler. It could receive data on the usb and send it on the software serial port. I guess i could connect the rts and cts to unused digital pins and not send unless they are free, but was hoping it would be built in?

    If somebody has done this before, i would gladly learn from them rather than reinventing the wheel.

    doug


  32. Nossu

    11 years ago

    Hi,I wold like to use under settings at NewSoftSerial.
    115200bps,8bit,start1bit,stop1bit,no flow,parity EVEN


  33. shrawan

    11 years ago

    Sir, as i am new to arduino microcontroller. I use the latest version of Newsoftserial library but facing following error.Please help me out..

    C:\Program Files\Arduino\libraries\NewSoftSerial/NewSoftSerial.h:33:2: error: #error NewSoftSerial has been moved into the Arduino core as of version 1.0. Use SoftwareSerial instead.
    In file included from easyvr.ino:1:
    C:\Program Files\Arduino\libraries\NewSoftSerial/NewSoftSerial.h:99: error: conflicting return type specified for ‘virtual void NewSoftSerial::write(uint8_t)’
    C:\Program Files\Arduino\hardware\arduino\cores\arduino/Print.h:48: error: overriding ‘virtual size_t Print::write(uint8_t)’


  34. Mika

    11 years ago

    Hello,

    I’m afraid I have some timing issues when running with8MHz(atmega328 on breadboard) and 115200 datarate when sending data to bluetooth mate.

    I think that timing needs just some slight adjustment since about 20% of chars looks to be correct (and rest are garbage).

    Might be also useful to try to calibrate internal oscillator but I do not have experience on that…


  35. Mikal

    11 years ago

    @Nossu,

    Sorry, for AVR processors anyway 115.2K is just too fast to reliably operate.


  36. Mikal

    11 years ago

    Hi shrawan, and welcome. As the error message indicates, you’re not supposed to use NewSoftSerial anymore. It’s been moved into the Arduino software. Since Arduino version 1.0 it’s now called “SoftwareSerial”.


  37. Mikal

    11 years ago

    @Mika, I’m afraid 115.2K is too fast even for 16MHz processors. I don’t believe that that “slight adjustment” exists. Sorry.


  38. Petr Stehlík

    11 years ago

    Hi Mikal,

    I have a suspect that SoftwareSerial(3, 2) (i.e. using pins 2 and 3) somehow affects pins 10-13 (on Arduino Pro Mini). I had attached MAA7361 on pins 10-13 and when SoftwareSerial was sending data (on pin 2) it was totally messing up the MAA7361.

    Do you know about something like that? Is it documented somewhere? Thanks for letting me know.


  39. shilpam sharma

    11 years ago

    Dear Mikal,
    If it is possible to use pin (Analog input) A4 and A5 on Arduino UNO R3 to act as Rx and Tx


  40. Mikal

    11 years ago

    @Petr Stehlík,

    I haven’t used the MAA7361 before, but I suspect its communication channel requires interrupts to be enabled. Since SoftwareSerial disables interrupts, this sometimes affects communication.


  41. Mikal

    11 years ago

    @shilpam sharma,

    Yep! They don’t publicize it well, but on the Uno the pins labeled A0-A5 can also be used as digital pins 14-19. Use 18 and 19 in your sketch and then wire the serial device to A4 and A5.


  42. Mike

    11 years ago

    Mikal, I have most digital pins doing other functions and when I add softserial the other inputs and outputs get a disterbance when data comes in. beats up my motors and servos. any way to stop this or do I need to move up to a Mege board and use hardware serial for my gps unit?

8 Trackbacks For This Post
  1. Giving Arduino a second UART over I2C by stacking another Arduino on top « CyclicRedundancy

    […] tried using the SoftSerial (or the NewSoftSerial) library but ran into data corruptions even at the low speeds, so I decided to look for ways to get another […]

  2. RFID Reader #1 « Tesla UIs

    […] the example code. There some issues on the Arduino library SoftwareSerial, which changed to the NewSoftSerial once in a while. Share this:TwitterFacebookLike this:LikeBe the first to like this. Categories […]

  3. Resources for the VCNL4000 IR Proximity Sensor | Sciencearium

    […] – http://arduiniana.org/libraries/NewSoftSerial/ Share this: This entry was posted in AT Physics Class and tagged arduino, IR, proximity […]

  4. Serial LCD do-it-yourself(DIY) kit | BUILD CIRCUIT

    […] NewSoftSerial Library – Required for the example sketches. Sets up a second (third, fourth,…) serial port on the Arduino. […]

  5. How to assemble serial LCD kit | BUILD CIRCUIT

    […] NewSoftSerial Library – Required for the example sketches. Sets up a second (third, fourth,…) serial port on the Arduino. […]

  6. Android talks to Arduino board - Arduino for ProjectsArduino for Projects

    […] from this project (bluetooth_chat_LCD.pde attached below) – NewSoftSerial library from Mikal Hart: http://arduiniana.org/libraries/newsoftserial/ – Eclipse – Android Development Kit (explicitly follow all of Google’s installation […]

  7. Burn Arduino Bootloader on an ATtiny45 for SoftwareSerial | No bread? Make it!

    […] http://arduiniana.org/libraries/newsoftserial/ いいね:いいね 読み込み中… カテゴリー Arduino, […]

  8. Burn Arduino Bootloader on an ATtiny for SoftwareSerial | No bread? Make it!

    […] http://arduiniana.org/libraries/newsoftserial/ いいね:いいね 読み込み中… カテゴリー Arduino, […]

Leave a Reply