NewSoftSerial

A New Software Serial Library for Arduino

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
  read_gps_data();  // use gps as active device
  // collect temperature data from thermometer
  read_thermometer_data(); // now use therm
  // LCD becomes the active device here
  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 “use” an object by calling its begin(), available(), read(), or print[ln]() methods, 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()
{
  if (device1.available() > 0)
  {
    int c = device1.read();
    ...
  }
  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

Upcoming Improvements

  • RTS/CTS flow control
  • support for Arduino Mega

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: NewSoftSerial10c.zip

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.

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 January 18, 2010 at 12:26 pm
186 Responses → “NewSoftSerial”

  1. 3dotter

    6 months ago

    Hi Mikal,

    I am a newbie in using Arduino. I tried already some codes with the Lilypad and a boardino and was able to make some code which worked. In a next step I also want to use your library to connect and “talk” to a GSM modem with AT commands, but it has not become clear to me which softserial port will become the Rx and which the Tx port in the following pin selection: e.g. NewSoftSerial gps(4,3); Is the 1st position, here 4, the Rx or the Tx? Thanks in advance for your answer!


  2. Mikal

    6 months ago

    Hi 3dotter, and welcome to the great world of Arduino. The prototype for NewSoftSerial’s constructor is:

    NewSoftSerial(int rx, int tx);

    So you can see the first pin is RX. Make sure you realize that that’s RX from the Arduino’s point of view. To connect a GPS, you’d connect the GPS’s TX line to NewSoftSerial’s RX line. Don’t let that confuse you. :)

    Mikal


  3. 3dotter

    6 months ago

    Hi Mikal,

    Thanks for the swift answer. Understood! Yes, arduino rocks :) It is great.

    Best wishes,
    3dotter


  4. NSR

    6 months ago

    Hi Mikal,

    I’m working with Keywon on her project, and I’ve found the issue. I’m posting it because I think it’s worth knowing. It appears the Windows machine had a /slightly/ older version of the version 10 library. In the newest version of the library, there is a segment in lines 45-57 that is supposed to define a mapping from pin numbers to PCICR/PCMSK variables. In the slightly older version, it works as intended, but in a fresh download the #if, #else, and #endif statements are commented out. This results in the macros being defined as NULL for every type of processor.


  5. Mikal

    6 months ago

    Ouch. Most embarrassing. Thank you both very much. Sorry for the errant post. The correct version (10C) is now posted.

    Mikal


  6. Markham

    6 months ago

    Hi Mikal,
    Love your work. I have a simple question which I think based on the responses above, I may already now the answer.

    Are there any problem with NewSoftSerial and version 0017?

    The reason I ask, is that I have it working perfectly for transmitting data, but I get nothing when receiving.
    I started with my GPS project which worked perfectly with the hardware serial, transferred it to NewSoftSerial and I didn’t receive anything. e.g. gps.available() always return 0. Transmitting beautifully at high speed but nothing in return.
    I then went to the simple example where I echoed to the hardware serial and the NewSoftSerial (reverse wiring on pins 0,1 & 2,3), same thing happened , NewSoftSerial transmitted data ok but nothing in return. I tried all speeds from 4800 to 56900. Yes, I’ve wired it properly and yes I’m using the same speed for both ports. I know the information is being transmitted from the device because I’m remotely monitoring the signal and see it going there but NewSoftware is not picking it up.

    I’m using the latest Arduino Duemilanove with ATMega328 and version 0017 loaded on a XP windows platform.

    Thanks


  7. Mikal

    6 months ago

    Hi Markham,

    NewSoftSerial 10b which was briefly posted here had a defect which broke it for receives on Duemilanove. Please discard that and grab 10c which is now posted. If you continue to have trouble, would you mind downgrading to version 9 to see if that works? It’s at http://arduiniana.org/NewSoftSerial/NewSoftSerial9.zip.

    There should be no incompatibility between NewSoftSerial and Arduino 0017, except for the servo library.

    Mikal


  8. cTiger

    6 months ago

    quickly scanning through the code of the library it seems this library does not support very well 1200 bauds and even worse in my case with 7bits data word.

    could someone confirm ?

    cheers
    cTiger


  9. Mikal

    6 months ago

    cTiger,

    1200 baud is supported, but not yet 7-bit data words.

    Mikal


  10. mango

    6 months ago

    Hi,

    I am trying the “NewSoftSerialTest” example code and it’s not working for me. I have pins 2 and 3 connected to each other and have set all baud rates to 9600. I’m using the Arduino Duemilanove 328. In the terminal I get “Goodnight moon!” and nothing else. I am expecting to see “Hello, world?”. Has anyone else run into this problem or know how I can continue trouble shooting (I’ve tried checking mySerial.available()>0)?

    Here is the code:

    #include

    NewSoftSerial mySerial(2, 3);

    void setup()
    {
    Serial.begin(9600);
    Serial.println(“Goodnight moon!”);

    // set the data rate for the NewSoftSerial port
    mySerial.begin(9600);
    mySerial.println(“Hello, world?”);
    }

    void loop() // run over and over again
    {

    if (mySerial.available()) {
    Serial.print((char)mySerial.read());
    }
    if (Serial.available()) {
    mySerial.print((char)Serial.read());
    }
    }


  11. Mikal

    6 months ago

    Mango, you shouldn’t connect the two pins together. That sketch is not designed to be a “loopback” test. It assumes that a console or some serial device is physically connected to pins 2 and 3 on the Arduino.

    To explain it another way, since software serial libraries require 100% of the CPU to transmit or receive a byte, they can’t do both at the same time.

    Connect a serial device like a GPS to those pins and watch the data fly on the Arduino serial console.

    Mikal


  12. mango

    6 months ago

    Mikal,

    I forgot to mention with my previous quote that I am working on Mac OS X 10.5, Arduino 0017, and have also tried NewSoftSerial 9 as you suggested to Markham.


  13. mango

    6 months ago

    Thanks for the explanation. It works just fine now!


  14. Markham

    6 months ago

    Thanks Mikal, version 10C works a whole lot better. However I did find out some interesting limitations.I also tried ver9 and it did the same thing.
    I have a number of GPS units and there are two which I love the most, being;
    -32 Channel San Jose Navigation GPS 5Hz Receiver with Antenna.
    -Venus GPS Logger with SMA Connector.

    Both can be programmed to output the exact same NMEA sentences, position update rate and communicate on 3.3V TTL serial.
    The interesting thing is that NewSoftSerial communicates almost flawlessly with the Venus GPS from speeds of 9600 to 115200 (fantastic). However the San Joes unit has a number of communications problems with NewSoftSerial (incorrect data determination, not necessarily just data lost). The San Joes unit works perfectly at 9600. At 38400, data is lost and incorrect characters generated but just readable. At speeds higher than 38400, data is unreadable.

    Clearly the two different units, although supposedly communicating at the same speed, their timings are microseconds slightly different. Clearly the hardware serial can read both units at any speed because it can buffer more information and adjusts itself accordingly. Unlike NewSoftSerial which has hardwired timings. I could play with the timings table and get the San Joes working perfectly but then I would suspect that my Venus unit would be affected.

    Mikal what would be an excellent tool, is a small program that can generate the timings table for any device. e.g. use the hardware serial in parallel and adjust the timings until the same data is read with the NewSoftSerial program. Only one problem would be different units requiring different timings being used together.

    Again Thanks Mikal.


  15. David McCallum

    6 months ago

    Hi Mikal,

    Thanks for the great library!

    I’d like one clarification, with respect to the “active” serial object, and how switching to a new active object clears the previous object’s RX buffer.

    Does this mean that when we create a function to deal with a serial input, it should loop “.available() > 0″ until it’s !> 0 before moving on to the next serial object, to make sure no incoming data is lost?

    I hope this makes sense…

    Thanks!
    D!


  16. Mikal

    6 months ago

    Hi David, and thanks for the good question.

    To save space, there is internally only one 64-byte RX buffer, which is shared between all NewSoftSerial objects in a sketch. Whichever one is the “active” one has custody of the buffer, meaning that if a byte arrives for that object it is placed into the buffer. Bytes arriving from inactive devices are simply discarded and lost. The buffer is cleared each time the active device changes.

    So if you’re thinking of activating an inactive device, is probably is a good idea to process whatever bytes are currently in the buffer before “moving on”. But make sure you’re aware that this won’t prevent future data from being lost if it arrives while the device is inactive.

    Does that make sense?

    Mikal


  17. Stanislav

    6 months ago

    Hi Mikal,
    Its me again :) so.. i still have same problem with BMW IBUS connection – i’m using adapter from Rolf Resler and reading on pc data from ibus, and at the same time i’m reading same data via arduino\NSS.
    Problem is: i’m getting about 1-3 bytes of “right” data and then ~ 3-6 bytes of mess…(typical message size on IBUS is about 8-10 bytes) so i’m usualy getting normal only few first bytes of almost every message….then wrong bytes till end of message, then again good few bytes etc…(i’m reading reference data via Rolf Resler adapter and comparing it with data coming from arduino)
    I’m using arduino nano duo ( ATmega328 16 Mhz).

    I think its because of timers in NSS, is there any way to adjust them(how to calculate right timers) ? What rxcenter rxintra rxstop tx means in NSS ?

    By the way is it possible to implement more RX buffers at cost of memory space for more than 1 NSS device ? (ie change NSS so it will be possible set num of buffers in setup section of sketch)

    p.s. sorry for my bad english.


  18. Mikal

    6 months ago

    Stanislav, what baud rate are you connecting at?

    You certainly could rewrite the serial code so that each object had its own buffer, but that wouldn’t change the fact that two objects cannot receive data (safely) at the same time, so doing so would be pointless.

    Mikal


  19. Stanislav

    6 months ago

    Mikal, 9600.


  20. Hafiz

    5 months ago

    Hi Mikal. noob question here…i’m using sparkfun’s 16×2 LCD (http://www.sparkfun.com/commerce/product_info.php?products_id=9395)
    and im trying to send stuff on the fly using the serial monitor (arduino). This lcd only has 1 connection to arduino…I tried using your library, but it’s not working for me :( help would be greatly appreciated. Thank you


  21. Mikal

    5 months ago

    Hafiz–

    I haven’t tried a serial display, but it should work fine. Don’t forget to connect the grounds of the Arduino and the display together. What exactly is “not working”?

    Mikal


  22. Keith Nasman

    5 months ago

    Mikal,

    I’ve been beating my head against the wall on this. I am trying to set up communication between two arduinos. Here are the sketches for each arduino.

    // Sending arduino

    #include
    #include
    #define rxPin 2 // d2
    #define txPin 3 // d3
    LED led = LED(13);
    NewSoftSerial mySerial(rxPin, txPin);
    void setup() {}
    void loop()
    {
    mySerial.begin(9600);
    mySerial.print(“1″);
    led.blink(1000);
    delay(5000);
    }

    // Receiving arduino

    #include
    #include
    #define rxPin 2 //d2
    #define txPin 3 //d3
    LED led = LED(13);
    NewSoftSerial mySerial(rxPin, txPin);
    void setup() {}
    void loop()
    {
    mySerial.begin(9600);
    if (mySerial.available()) {
    mySerial.read();
    led.blink(2000);
    }
    delay(5000);
    }

    What am I missing?
    Thanks, Keith


  23. Mikal

    5 months ago

    Cool, Keith.

    Just a couple of thoughts: remove the calls to begin() from loop(); these belong in setup(). Also remove the delay from loop on the receiving end. You want the receiver to act immediately whenever a character arrives.

    Make sure the Arduino grounds are connected together and that the TX pins are connected to the RX pins, and I bet it will work.

    Mikal


  24. leosys

    5 months ago

    Hi Mikal,

    Great work.

    At some point you asked about wishlist… Well, configurability, i.e. E,7, 1 style parity, data and stopbit configuration would be appreciated much. Currently I got an FT1.2 enabled KNX/EIB device (BIM113) to listen/talk to. And the FT1.2 protocol seems to require 8 data bits, EVEN parity and 1 stop bit (8E1 if I’m right :-) ).

    Any visibility about that? Or could you point a where in your lib to start work on that?

    BR Joe


  25. Keith Nasman

    5 months ago

    Mikal,

    I made the changes you suggested and now the receiving arduino blinks on receive. For the next step I’d like the sending arduino to send the number of blinks to the receiver. Here is the what the receiver is doing:

    int count = mySerial.read();
    for (int blinks=0; blinks < count; blinks++) {
    led.blink(500);
    }

    No matter what number I put in on the sending side, I get one blink. I’ve tried setting the mySerial.print() to pass an integer variable with no success.

    Thanks so much!


  26. Mikal

    5 months ago

    leosys–

    The E71-style configurability is one of the top two feature requests for NewSoftSerial. (The other is support for the Mega.) Conceptually, this wouldn’t be too hard. In the code you’d simply change the loops which count to 8 and make them count to 7 or whatever and then add the parity bit check. I haven’t done this because the changed timing might be a little messy to sort out. I’m afraid I can’t give you visibility yet — too much other stuff going on — but I’d welcome other contributions, if anyone is game… :) .

    Mikal


  27. leosys

    5 months ago

    Mikal,

    I made a quick&dirty hack in recv() to ignore the parity bit and write() for 8E1, just to proceed with my project. I used the stop bit timing for the parity bit, and checked it with an oscilloscope @19200. The relevant code fragments below…

    Generally I could think to improve it a bit.
    - begin(): add 2nd parameter with type of parity (Ignore, None, Odd, Even, Mark, Space)
    - recv(): _receive_parity_error flag to indicate a parity error during reception of a byte

    But you are the owner (or maintainer) of the lib. It’s up to you to decide and integrate later on. And I would go ahead only then ;-) No need to work in vain.

    Joe

    void NewSoftSerial::recv()
    {

    // Read each of the 8 bits
    for (uint8_t i=0×1; i; i <don’t care
    // skip the stop bit
    for (uint8_t i=1; i<2; i++) {
    tunedDelay(_rx_delay_stopbit);
    DebugPulse(_DEBUG_PIN2, 1);
    }

    void NewSoftSerial::write(uint8_t b)
    {

    // *JW* hack parity=EVEN
    uint8_t parity= 0;

    if (_tx_delay == 0)
    return;

    // *JW* Calculate parity = EVEN
    for (byte mask = 0×01; mask; mask <<= 1)
    if (b & mask) parity= !parity;

    activate();

    uint8_t oldSREG = SREG;
    cli(); // turn off interrupts for a clean txmit

    // Write the start bit
    tx_pin_write(_inverse_logic ? HIGH : LOW);
    tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);

    // Write each of the 8 bits
    if (_inverse_logic)
    {
    for (byte mask = 0×01; mask; mask <<= 1)
    {
    if (b & mask) // choose bit
    tx_pin_write(LOW); // send 1
    else
    tx_pin_write(HIGH); // send 0

    tunedDelay(_tx_delay);
    }

    // *JW* write parity = EVEN
    tx_pin_write(parity ? LOW : HIGH);
    tunedDelay(_tx_delay);

    tx_pin_write(LOW); // restore pin to natural state
    }
    else
    {
    for (byte mask = 0×01; mask; mask <<= 1)
    {
    if (b & mask) // choose bit
    tx_pin_write(HIGH); // send 1
    else
    tx_pin_write(LOW); // send 0

    tunedDelay(_tx_delay);
    }

    // *JW* write parity = EVEN
    tx_pin_write(parity ? HIGH : LOW);
    tunedDelay(_tx_delay);

    tx_pin_write(HIGH); // restore pin to natural state
    }

    SREG = oldSREG; // turn interrupts back on
    tunedDelay(_tx_delay);
    }


  28. Phlogi

    5 months ago

    Are there any news about supporting the Arduino Mega? Anyone tried to get it working?

    Thanks a lot.


  29. Mikal

    5 months ago

    Phlogi–

    All that’s needed (I think) to get NewSoftSerial working on Mega is for someone to calculate and define these four macros at the top of NewSoftSerial.cpp:

    #define digitalPinToPCICR(p) (((p) >= 0 && (p) < = 21) ? (&PCICR) : ((uint8_t *)NULL))
    #define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
    #define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)NULL))))
    #define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) – 8) : ((p) – 14)))

    Are you sure you need it? The Mega has four “real” serial ports, you know.

    Mikal


  30. Mark

    5 months ago

    Hello Mikal,
    I have an speed issue.
    While keeping an 5khz pulse running to an stepper motor I need to send my position and other data out via serial port at the same time.
    I was hopeful the NewSoftSerial was faster.
    But NO.

    in my test both the NewSoftSerial and the old Serial use the standard 0&1 pins.
    so I can only run the test once as the old serial will not release.

    Question. Do you have any ideas how I can do my 2 things at the same time?

    here is my test code for the Atmega328

    // Speed test of new Soft Serial
    #include

    NewSoftSerial mySerial(0, 1);
    int ver;
    long val_1;
    long val_2;
    long time;

    void setup()
    {
    // set the data rate for the NewSoftSerial port
    mySerial.begin(57600);
    mySerial.println(“Hello, world?”);
    ver = NewSoftSerial::library_version();
    mySerial.print(“NewSoftSerial::library_version = “);
    mySerial.println(ver);
    mySerial.println(“Speed test for 480 chars begin.”);
    delay(1500);
    }

    void loop() // run over and over again
    {
    //NewSoftSerial mySerial(0, 1);
    mySerial.begin(57600);
    val_1 = millis();
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    mySerial.println(“The quick brown fox jumps over the lazy dog.”);
    val_2 = millis();
    time = val_2 – val_1;
    mySerial.print(“NewSoftSerial takes “);
    mySerial.print(time);
    mySerial.println(” to complete.”);
    mySerial.println(“”);
    mySerial.end();

    delay(1200);

    Serial.begin(57600);
    val_1 = millis();
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    Serial.println(“The quick brown fox jumps over the lazy dog.”);
    val_2 = millis();
    time = val_2 – val_1;
    Serial.print(“Old Serial takes “);
    Serial.print(time);
    Serial.println(” to complete!”);
    Serial.println(“”);

    delay(2000);
    }


  31. Andre Crone

    5 months ago

    I tried to compile this library with the Antipasto Arduino IDE; it’s not working. I am getting several error messages. Has anyone found out how to solve this? I would love to use one IDE for Arduino and TouchShield Slide development.


  32. Mikal

    5 months ago

    Mark, I think you may have a misconception of how serial works. If you need to 500 characters over a 57.6K/N/8/1 serial link, it’s going to take at least 86 milliseconds no matter what kind of software library you use. I don’t see why the stepper library should be incompatible with Serial, but I would always use Serial in lieu of NewSoftSerial whenever you have other stuff in your program that might be time sensitive.

    Mikal


  33. Mikal

    5 months ago

    Andre, can you share the first few error messages? That might give us some idea of what’s involved.

    Mikal


  34. Andre Crone

    5 months ago

    Mikal,

    I get the following error:
    compile(), new thread run about to sketch.handleRun()
    [echo] Building Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 libraries…
    [apply] /Applications/Arduino/hardware/cores/arduino/src/components/library/NewSoftSerial/NewSoftSerial.cpp: In member function ‘void NewSoftSerial::begin(long int)’:
    [apply] /Applications/Arduino/hardware/cores/arduino/src/components/library/NewSoftSerial/NewSoftSerial.cpp:410: error: ‘NULL’ was not declared in this scope
    [apply] /Applications/Arduino/hardware/cores/arduino/src/components/library/NewSoftSerial/NewSoftSerial.cpp: In member function ‘void NewSoftSerial::end()’:
    [apply] /Applications/Arduino/hardware/cores/arduino/src/components/library/NewSoftSerial/NewSoftSerial.cpp:428: error: ‘NULL’ was not declared in this scope

    This looks a bit like the issue regarding the macro’s as mentioned a few replies before mine?


  35. JDMartin

    5 months ago

    Mikal,

    I have a project I’m working on that will have 7 or 8 Arduino AT168 clones, each receiving button and switch inputs. I am then converting the button and switch inputs to actual keystrokes, and then I am sending those to the application on the PC. What I would like to do is have all the Arduino clones communicate their respective keystroke outputs back to a single Arduino, which would do the communicating with the PC. There would only be a single button or switch activated at a time.

    Is this something that could be accomplished with this library?

    Jim


  36. Mikal

    4 months ago

    Jim,

    I’m afraid that that doesn’t sound like a very good app for NewSoftSerial. Unless you knew which of the 7 or 8 Arduinos to listen to in advance, you would lose data.

    Mikal


  37. Nenad

    4 months ago

    Hi there,
    I just started using your library and its pretty awesome.
    I looked through the code and it looked to me that there was a slight chance for improvement.
    I was thinking about replacing tunedDelay() with a timer based interrupt. Did you ever consider that? If you explain i.e give me sample code instead of assembly, and some timing info for this routine, maybe I could offer some help too.
    Thanks


  38. Kurt Schulz

    4 months ago

    Hi Mikal,

    I’m having exactly the same problem described by Andre Crone when compiling the library with the Antipasto Arduino IDE. I’d really like to use NewSoftSerial to talk to the TouchShield Slide. Any thoughts on what might be the problem?

    Thanks, Kurt


  39. Mikal

    4 months ago

    Nenad, at some point I do think we should get rid of tunedDelay. The reliance on that inline assembler sometimes chokes certain Linux distributions. If you can come up with an alternate that doesn’t affect the timing — and that’s a big if — go for it. I’m reluctant to consume a timer resource, though, when the current implementation works well for most people.

    Mikal


  40. Mikal

    4 months ago

    Andre–

    Sorry for the slow reply. Reading through those errors, I have to conclude that in your environment NULL is not defined. It may be as simple a matter as adding this to the top of NewSoftSerial.h:

    #define NULL 0

    or possibly

    #define NULL ((void *)0)

    Mikal


  41. Mikal

    4 months ago

    Hi Kurt–

    Thanks for reminding me that I need to get back to Andre. See his response.

    Mikal


  42. Kurt Schulz

    4 months ago

    You’re right Mikal – it was as simple as defining NULL in the header file.

    Thanks!


  43. sm

    4 months ago

    Quick question… is there a way to configure only a single pin for Tx or Rx? For example, can I set up only a Tx pin to support a serial LCD unit and thus not waste a pin for Rx (since it will never be used)?

    Thanks for some great work!


  44. Mikal

    4 months ago

    sm –

    Yeah, if you just choose an invalid pin number like -1 for the direction that you don’t use, you can save the pin. For example, on a GPS app that only does receives you might do something like

    NewSoftSerial nss(3, -1);
    Mikal


  45. sm

    4 months ago

    Excellent! Thank you Mikal.


  46. aenigma

    4 months ago

    Wanting to find out if I can do all this in the same sketch on an ATmega328 running at 3.3V/8MHz:

    1. Use NewSoftSerial to communicate with GPS (pins 3,4 on Arduino)
    2. Use the GPS logging libraries here: http://www.ladyada.net/make/gpsshield/logging.html, replacing the hardware UART with NewSoftSerial, to log GPS/sensor data to SD card
    3. Read/write serial data to the hardware UART (connected to XBee, for example)

    Is this asking too much of the available processing/RAM?

    Thanks!


  47. Timc995

    4 months ago

    JDMartin,
    If you have 7 arduinos and need to have them all feed data, you might be able to set them up in a round robin. IE: #1 sends to #2. #2 echoes #1 (or generates its own data) and sends #3, etc. This way, all of the output is sequentially fed downstream and you don’t have to deal with multiple simultaneous reads at the tail end.


  48. DDD

    4 months ago

    So would I be able to have 4 seperate outputs (1 hardware UART and 3 newsoftserial) and run them all at 31250 baudrate?
    If I sent a byte to each one how out of sync would they all be?

    e.g.
    If did this:
    Serial.print(myByte);
    MySerial1.print(myByte);
    MySerial2.print(myByte);
    MySerial3.print(myByte);

    How much delay would there be between each byte being sent?


  49. Mikal

    4 months ago

    DDD, my guess is that if you were doing 4 transmits (only), this should work fine. Each call to NewSoftSerial::print() would take 0.3 ms.

    Mikal


  50. Jeff O'Brien

    4 months ago

    I noticed you added support for a 20mhz clock.
    Is there anyway to make it work with an arduino running a 12mhz clock?

    I’m using wiblock’s NB1A board that runs a 12mhz clock
    http://wiblocks.luciani.org/NB1/NB1A-index.html

    let me know if i need to bail…
    Thanks
    Jeff

24 Trackbacks For This Post
  1. NewSoftSerial 5 « Arduino

    [...] NewSoftSerial version 5 is available. A lot of people have been using this library — thanks! — but I really need to recognize the exceptional work of two contributors. [...]

  2. NewSoftSerial 6 « Arduiniana

    [...] I posted the new library. [...]

  3. เริ่มต้นสร้าง GPS จอสีกับอาดูอี้โน่ | Ayarafun Factory

    [...] ในรอบนี้ผมได้ใช้ newSoftwareSerial3 จะได้ลองด้วยว่า มีปัญหาไหม

  4. Unlogic » USB Storage and Arduino

    [...] of the first things to do is download NewSoftSerial

  5. The Hired Gun » GPS project: the Bluetooth saga

    [...] to the task at hand, which happened to be adding 3 lines of code: declaration of an instance of NewSoftSerial, calling the instance constructor with a baud rate, and a single call to pass the char from the [...]

  6. layer8 » Controlling A Roomba with an Arduino

    [...] and the XBee module has a serial interface.  So how does this really solve my problem?  Enter NewSoftSerial, an updated version of the Arduino software serial library, which basically lets you drive a serial [...]

  7. This and That » Blog Archive » Arduiniana - What else would it be?

    [...] is probably the coolest gift idea I’ve seen.  Mikal, you rock.  And also, thank you for NewSoftSerial.  [...]

  8. Interfacing the Arduino with the DS1616

    [...] way.  Let’s move onto the software.  Communication with the DS1616 is established using the NewSoftSerial library.  Getting data is essentially a case of lots of bit banging.  The DS1616 library [...]

  9. Serial Multiplexing « Interactive Environments Minor 2009-2010

    [...] So we started looking for a solution to overcome this tiny inconvenience. First we looked into a software serial but this didn’t work out, it was a bit too much for the arduino’s little processor to [...]

  10. Atmega/Arduino (Soft-) Serial Ports | Jochen Toppe's Blog

    [...] software serial port. I briefly thought about writing one, but then I found this great libary, the New SoftSerial. It is as simple to use as the original library, but unfortunately once I connect the RF receiver, [...]

  11. The Frustromantic Box, Part 4: Software « New Bright Idea

    [...] developers for the great libraries, and to Mikal Hart in particular for his work on the TinyGPS and NewSoftSerial [...]

  12. side2 » Bimeji Client for Arduino

    [...] このソースでは、PS2ライブラリとNewSoftSerialライブラリを利用しています。 コンパイルするには、これらのライブラリを有効にしておく必要があります。 [...]

  13. Live Twitter Table using New Bluetooth Shield | Club45

    [...] as a well. The shield can be wired to any of the pins on the Arduino. Right now we’re using NewSoftSerial on pins 4 and 5. It can be attached to the hardware RX and TX pins, but interferes with [...]

  14. tokyo->kobe->osaka << Motoi Ishibashi

    [...] 急遽、Arduinoでシリアル通信をふたつやる必要が発生してホテルで開発。といっても手元にハードがないので、ほとんど勘でプログラムしているようなもの。 次の日現場で試すも、予想通り動かない。そりゃそうだ。 NewSoftwareSerialなんていう便利なものがあるのを後で知った。 [...]

  15. VDIP1 USB Host Controller « Arduino Fun

    [...] chose the NewSoftSerial library to give access to the VDIP1.  The first attempt was to use the AFSoftLibrary and it just [...]

  16. Project Lab

    [...] software running on the Arduino ATMEGA328 chip utilizes the wonderfully robust NewSoftSerial library for communicating with the EM-406a GPS module and the very convenient TinyGPS library for [...]

  17. Box Round 2 « Stromberg Labs

    [...] is available here. I borrowed from a couple of people’s Arduino libraries to get this done, notably NewSoftSerial from Arduiniana and the GPS Parsing code from the Arduino website for parsing the NMEA strings. [...]

  18. Grok Think » Blog Archive » I got Arduino sending temp to the computer using xbee wireless.

    [...] I had to use this library to communicate with the xbee from the arduino:  http://arduiniana.org/libraries/newsoftserial/ [...]

  19. GPS – Welcher Chip? | Ranzow im Umbau

    [...] wird über die Serielle Schnittstelle angesteuert. Die werde ich wahrscheinlich über die NewSoftSerial Library [...]

  20. GPS – Welcher Chip? | Ranzow im Umbau

    [...] GPS Modul wird über die Serielle Schnittstelle angesteuert. Die werde ich wahrscheinlich über die NewSoftSerial Library [...]

  21. Cititor RFID 125KHz « Tehnorama

    [...] metoda de a afla codul cartelei este de a utiliza biblioteca NewSoftSerial, disponibila gratuit aici. Fisierul zip se dezarhiveaza si se copiaza in folderul libraries al distributiei [...]

  22. Lightweight software UART -> custom serial « Robotics / Electronics / Physical Computing

    [...] updated the NewSoftSerial library from Arduiniana (thanks Mikal !) so that it takes 2 extra [...]

  23. Control Camera with Arduino | SenSorApp

    [...] http://arduiniana.org/libraries/newsoftserial/ [...]

  24. GPS testing with LCD Character Display

    [...] the TinyGPS library from Arduiniana downloaded and installed for it to work. They suggest using NewSoftSerial, but I couldn’t get that to work, so I scrapped that portion. Here’s my [...]

Leave a Reply