Arduino Forum

Using Arduino => Programming Questions => Topic started by: gcjr on May 23, 2020, 08:39 pm

Title: software serial limitations
Post by: gcjr on May 23, 2020, 08:39 pm
i have an Arduino Mega application that uses 3 serial interfaces that works.

this is DCC model railroad application that translates commands from the PC thru one serial to an NCE (cabbus) command station thru another serial interface.   Both are rs-485.  The 3rd interface (USB) is used for debugging.

i rebuilt the application for an Uno using software serial.    I used pins 8 (RX) and 9 for one interface and 10 (RX) and 12 for the 2nd.

i was unable to read serial data while other code was running.   the other code checks for received data on corresponding interfaces and processes that data.

but when I simplified the code to simply check the one soft serial interface and echo it on the serial monitor it worked.   It seems like the soft serial interface needs to be constantly queried to work

this is a big disappointment and I have to wonder how useful a soft serial interface can be if very little else can be done
Title: Re: software serial limitations
Post by: wildbill on May 23, 2020, 08:47 pm
The softwareSerial library can only read data from one instance at a time, i.e. only one can be active at any moment. It sounds like this was your issue.
Title: Re: software serial limitations
Post by: vaj4088 on May 23, 2020, 08:52 pm
There are several different Software Serial interfaces, each with its own limitations.  You did not say which one you have, and you did not show your code.

The Software Serial that I am most familiar with will only listen on one port at a time, yet I have used this to link hundreds of Unos.  Each Uno had one hardware serial port for debugging, and two software serial ports to link to adjacent Unos.

Were you attempting to exceed the limitations of your implementation?

Title: Re: software serial limitations
Post by: groundFungus on May 23, 2020, 09:18 pm
This page explains how to use 2 software serial ports. (https://www.arduino.cc/en/Tutorial/TwoPortReceive)
Title: Re: software serial limitations
Post by: gcjr on May 23, 2020, 09:32 pm
There are several different Software Serial interfaces, each with its own limitations.  You did not say which one you have, and you did not show your code.
i didn't know there were several different SoftwareSerial libraries.   The one I have has the following
Code: [Select]
SoftwareSerial.cpp (formerly NewSoftSerial.cpp)



The Software Serial that I am most familiar with will only listen on one port at a time, yet I have used this to link hundreds of Unos.  Each Uno had one hardware serial port for debugging, and two software serial ports to link to adjacent Unos.
Here's a Two Port Receive example  (https://www.arduino.cc/en/Tutorial/TwoPortReceive) which I assume works, but does very little, and which I inferred implies that multiple ports can be used simultaneously[/quote]


Were you attempting to exceed the limitations of your implementation?
i certainly wasn't attempt to exceed the limitations.   My understanding is the limitation is 57600 bps (https://www.arduino.cc/en/Reference/softwareSerial) and RX pins are restricted to RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

simplified code that works inside #if/#else

Code: [Select]
// NCE USB Cab Interface

const char *version  = "CabUsb 200522b";

#include "CabUsb.h"
#include "cabbus.h"
#include "jmriIf.h"

#if defined __AVR_ATmega328P__      // Uno
SoftwareSerial Serial1 (RX1, TX1);
SoftwareSerial Serial3 (RX3, TX3);
#endif

extern void pcRead (void);

#if 0
unsigned int debug  = 0;
#elif 0
unsigned int debug  = DBG_BUS_RESP;
#else
unsigned int debug  = DBG_BUS_RESP| DBG_JMRI_MON;
#endif

// ---------------------------------------------------------
byte ioPins [] = {Hb, TxEn1, TxEn3 };
#define NumIoPins sizeof(ioPins)

// -----------------------------------------------------------------------------
void
loop (void)
{
#if defined __AVR_ATmega328P__      // Uno
    Serial1.listen ();
    if (Serial1.available()) {
        uint8_t c = Serial1.read ();
        Serial.println (c, HEX);
    }

#else
    jmriIf ();

    busProcess ();
    pcRead ();
#endif
}

// ---------------------------------------------------------
void
setup (void)
{
    char s [40];
    Serial.begin (115200);

    Serial1.begin(9600);
    if (! Serial1)
        Serial.println ("Serial1 begin failed");
    else {
        sprintf (s, "%s: RX1 %d, TX1 %d", __func__, RX1, TX1);
        Serial.println (s);
    }

    Serial3.begin(9600);
    if (! Serial3)
        Serial.println ("Serial3 begin failed");
    else {
        sprintf (s, "%s: RX3 %d, TX3 %d", __func__, RX3, TX3);
        Serial.println (s);
    }

    for (uint8_t i= 0; i < NumIoPins; i++)  {
        pinMode      (ioPins [i], OUTPUT);
        digitalWrite (ioPins [i], LOW);     // disable TX
    }

    Serial.println (version);

#if defined __AVR_ATmega328P__      // Uno
    Serial.println ("Uno");
#endif

#if defined __AVR_ATmega2560__
    Serial.println ("Mega");
#endif
}


Title: Re: software serial limitations
Post by: Robin2 on May 23, 2020, 09:36 pm
i rebuilt the application for an Uno using software serial.
Stick with the Mega. Life will be a lot simpler.

...R
Title: Re: software serial limitations
Post by: srnet on May 23, 2020, 10:10 pm
this is a big disappointment and I have to wonder how useful a soft serial interface can be if very little else can be done
Its not a disappointment at all, used correctly, and within its limitations, it allows Arduinos such as Unos and pro Minis to talk to serial devices, which is a good thing.
Title: Re: software serial limitations
Post by: srnet on May 23, 2020, 10:17 pm
My understanding is the limitation is and RX pins are restricted to RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
You implied in the first post you were using a UNO, in which case you can use all pins.

You appear to have posted the restrictions for a Mega.
Title: Re: software serial limitations
Post by: gcjr on May 23, 2020, 11:17 pm
Its not a disappointment at all, used correctly, and within its limitations, it allows Arduinos such as Unos and pro Minis to talk to serial devices, which is a good thing.
how am I using it "incorrectly"?

how is it not a disappointment if it won't work at 9600 bps when presumably it's limitation is 57600 bps
Title: Re: software serial limitations
Post by: groundFungus on May 24, 2020, 12:27 am
I have actually tested the SoftwareSerial library and found that reliable communication is possible up to 38400 at most.  I do not know if any of the other software serial libraries (NeoSWSerial, AltSoftSerial, ... ) are any faster.
Title: Re: software serial limitations
Post by: vaj4088 on May 24, 2020, 12:30 am
Quote
The board listens on one virtual port (portOne) until it receives a "?" character. After that, it listens on the second virtual port (portTwo).
Also:


Quote
When using two software serial ports, you have to switch ports
 by listen()ing on each one in turn. Pick a logical time to switch
 ports, like the end of an expected transmission, or when the
 buffer is empty. This example switches ports when there is nothing
 more to read from a port
from Two Port Receive Example (https://www.arduino.cc/en/Tutorial/TwoPortReceive)

Title: Re: software serial limitations
Post by: gcjr on May 24, 2020, 12:44 am
so it seems that the software serial ports cannot be used as replacements for the hardware serial ports on the Mega.

in my case, one of the ports i'm trying to use as a software serial port has traffic at least every 4 ms.   
Title: Re: software serial limitations
Post by: wildbill on May 24, 2020, 01:00 am
Not with that library they're not. Maybe there's one that will do two software ports simultaneously, but I suspect not.

If you're switching boards for physical size reasons, take a look at the Teensy range, I see that the 3.1 has three serial ports.
Title: Re: software serial limitations
Post by: srnet on May 24, 2020, 06:30 am
how is it not a disappointment if it won't work at 9600 bps.
I have used it on a great may projects reading 9600baud GPSs on 8Mhz Arduino Pro Minis and no-doubt countless others have as well. This works.  

What Software serial cannot do, as the documentation makes clear, is listen to two or more instances at the same time.

The Two Port Receive example you quoted, shows two Software serial ports defined, with each being read in turn using port.listen(). That you switch between the Software serial instances in this way should make clear that the two ports cannot be used simultaneously.
Title: Re: software serial limitations
Post by: Nick_Pyner on May 24, 2020, 10:32 am
how am I using it "incorrectly"?

how is it not a disappointment if it won't work at 9600 bps when presumably it's limitation is 57600 bps
Its limitation is 38400. If it isn't working at 9600, you are doing something incorrectly. I think we can be quite sure that nobody is using it like you do with any success, and nobody else has bothered to look at your code, which is mostly junk as far as comms is concerned. You can start with this bit
Code: [Select]
SoftwareSerial Serial1 (RX1, TX1);
SoftwareSerial Serial3 (RX3, TX3);

And while you are at it, you might consider including the software serial library, any software serial library, as you won't get far without it. Now I don't have any software serial libraries, but the examples in yours will surely tell you how to do that. Further, if you can't work out whether you have a Uno or a Mega in your hand, swapping it all for a train set would be a good idea. So you as well get rid of all that that Uno<>Mega stuff, as it may just be adding to your problem, and a simple "hello world" test would be well in order.
Since you have a Mega, you would be well-advised to read reply#5 again, twice.

Title: Re: software serial limitations
Post by: gcjr on May 24, 2020, 12:21 pm
The Two Port Receive example you quoted, shows two Software serial ports defined, with each being read in turn using port.listen(). That you switch between the Software serial instances in this way should make clear that the two ports cannot be used simultaneously.
which version of SoftwareSerial do you use?

isn't that what the example code (posted below from TwoPortReceive (https://www.arduino.cc/en/Tutorial/TwoPortReceive)) is doing?   it executes listen() on one port and checks available() then does the same for the the other port.

of course this a do nothing example.   the limited delay in listening between each port is when processing a byte from the other port.

it's not clear to me how often and when specifically listen() needs to run.

Code: [Select]
void loop() {
  // By default, the last intialized port is listening.
  // when you want to listen on a port, explicitly select it:
  portOne.listen();
  Serial.println("Data from port one:");
  // while there is data coming in, read it
  // and send to the hardware serial port:
  while (portOne.available() > 0) {
    char inByte = portOne.read();
    Serial.write(inByte);
  }

  // blank line to separate data from the two ports:
  Serial.println();

  // Now listen on the second port
  portTwo.listen();
  // while there is data coming in, read it
  // and send to the hardware serial port:
  Serial.println("Data from port two:");
  while (portTwo.available() > 0) {
    char inByte = portTwo.read();
    Serial.write(inByte);
  }

  // blank line to separate data from the two ports:
  Serial.println();
}
Title: Re: software serial limitations
Post by: gcjr on May 24, 2020, 12:35 pm
I think we can be quite sure that nobody is using it like you do with any success,
is that because SoftwareSerial is too limited for such an application?

and nobody else has bothered to look at your code, which is mostly junk as far as comms is concerned.
got the interface working in a couple hours using a Mega

And while you are at it, you might consider including the software serial library,
which version of the library do you use?

Further, if you can't work out whether you have a Uno or a Mega in your hand,
i want to use the same code on either an Uno or Mega.   The code determines the hardware using a defined macro.

Code: [Select]
#if defined __AVR_ATmega328P__      // Uno
Title: Re: software serial limitations
Post by: Nick_Pyner on May 24, 2020, 04:44 pm
is that because SoftwareSerial is too limited for such an application?
In your case, no. I'm afraid it is because you don't know what you are doing.
Quote
got the interface working in a couple hours using a Mega
Good. I guess you now see the advantage of the Mega
Quote
which version of the library do you use?
I don't use software serial ever. Mostly I use a Mega, but I don't use it on a Uno or my Pro Mini either. There is no need. There certainly are cases where you have no option but to use software serial, but it is more rare than you would think, and when you do it is under sufferance. Quite often software serial is just a refuge for the lazy and incompetent.
Quote
i want to use the same code on either an Uno or Mega.   The code determines the hardware using a defined macro.

Code: [Select]
#if defined __AVR_ATmega328P__      // Uno
That sounds like a particularly dumb idea. God only knows what the motivation for that is and, if it means you are obliged to use software serial on a Mega, that would be code you should definitely not show your mother. Most code that will run on a Uno will run essentially verbatim on a Mega, but one of the major differences, thereby requiring different code, is serial communication.
Title: Re: software serial limitations
Post by: gcjr on May 24, 2020, 05:15 pm
I don't use software serial ever.
wow!  ??


God only knows what the motivation for that is and, if it means you are obliged to use software serial on a Mega, that would be code you should definitely not show your mother.
the purpose is not to use SoftwareSerial unnecessarily on a Mega but be able switch back to the Mega to verify that any changes don't break the code.

it's pretty common in industry.  i guess you've never had to write code professionally that needs to operate on different types of hardware.   I've had to work on RF code that supports different RF hardware that operates on different bands with various restrictions
Title: Re: software serial limitations
Post by: Nick_Pyner on May 24, 2020, 05:35 pm
wow!  ??
No wow, just no need. My serial peripheral adventures involve just one Bluetooth connected at 115200. In that situation, there is never ever a need to use software serial, and it wouldn't work at that speed anyway.
Quote
the purpose is not to use SoftwareSerial unnecessarily on a Mega but be able switch back to the Mega to verify that any changes don't break the code.
Whatever floats your boat.... Don't bother explaining why you wouldn't use another Uno to do that. I assume no RTC or SD card is involved in your exercise, and you confine software serial to pins that work on a Mega.
Title: Re: software serial limitations
Post by: UKHeliBob on May 24, 2020, 05:40 pm
Quote
My serial peripheral adventures involve just one Bluetooth connected at 115200In that situation, there is never ever a need to use software serial
What do you do if you are using hardware Serial to connect to a peripheral such as a Bluetooth adaptor and need to print messages for debugging or other purposes ?
Title: Re: software serial limitations
Post by: Nick_Pyner on May 24, 2020, 06:17 pm
What do you do if you are using hardware Serial to connect to a peripheral such as a Bluetooth adaptor and need to print messages for debugging or other purposes ?
I don't, the data is from sensors, and any messages go out via Bluetooth - as one would expect.. The debugging is done through hardware serial in the normal manner with Bluetooth disconnected. Bluetooth on software serial is more a hinderance than a help in debugging, and anyway, once you have the need to connect bluetooth, at 115200, the debugging is done.