Go Down

Topic: software serial limitations (Read 399 times) previous topic - next topic

gcjr

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
greg - somerset, nj

wildbill

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.

vaj4088

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?


groundFungus

You will save everyone's time if you read and follow the forum guidelines.  https://forum.arduino.cc/index.php/topic,148850.0.html

gcjr

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 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 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
}


greg - somerset, nj

Robin2

i rebuilt the application for an Uno using software serial.
Stick with the Mega. Life will be a lot simpler.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

srnet

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.

srnet

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.

gcjr

#8
May 23, 2020, 11:17 pm Last Edit: May 23, 2020, 11:37 pm by gcjr
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
greg - somerset, nj

groundFungus

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.
You will save everyone's time if you read and follow the forum guidelines.  https://forum.arduino.cc/index.php/topic,148850.0.html

vaj4088

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


gcjr

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.   
greg - somerset, nj

wildbill

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.

srnet

#13
May 24, 2020, 06:30 am Last Edit: May 24, 2020, 06:38 am by srnet
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.

Nick_Pyner

#14
May 24, 2020, 10:32 am Last Edit: May 24, 2020, 10:59 am by Nick_Pyner
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.


Go Up