Multiple instances of Softwareserial library

Hi, I am having trouble adding 2-3 software serial ports to my Arduino Uno software.

Searching this site but also googling globally, i found not consistent info like: "SoftwareSerial can have multiple instances, on any 2 pins" vs "rx pin can be only 2 or 3 because these are the only interrupt capable pins".

I gave up searching and did some experimenting instead, with the following results:
-regardless of what the documentation says, only 1 instance of SoftwareSerial works (but there is an example with 2 software serial ports bundled with the library, so what...?).
-can work on any 2 pins.

If i could get 2 software serial ports on my Uno that would be already OK, but of course the more the better (ok i am not trying to ask for 9...).

I have also seen that there are quadruple TTL serial ports SPI "bridges", has anybody some info on them? Does anything similar exist with I2C interface instead?

Thanks and regards,

You can have multiple software serial instances in your code but you can only use one at a time.

What did you google ? “ Arduino software serial”

This plus the examples in the IDE tell you everything you need to know , pins, multiple instance and so on :

https://www.arduino.cc/en/Reference/SoftwareSerial

Or ....

Use something like the “Arduino nano every” which has multiple hardware serial ports ( more memory too !)

This example shows how to switch between 2 software serial ports.

You don't give us any idea how fast that you need to transfer data, but software serial is limited to 38400.

If you need that many serial ports, the Mega has 3 extra hardware ports.

If you need a lot of ports I2C is not the best way if there is any distance involved. RS485 may be a better alternative.

can be only 2 or 3 because these are the only interrupt capable pins

That is nonsense. Most all pins have pin change interrupt capability.

Hi,
38400 as max speed is ok for me.
Ideally, i would need 8 ports so not even a Mega would be enough for me.
I was considering I2C because i already have a couple I2C devices on board, to avoid running low on memory with the addition of SPI.
I have read the story of pins 2 and 3 on some website, I just asked for confirmation.
I started from the bundled example TwoPortReceive, i loaded it unmodified and it doesnt work. It doesnt work for other pins either. I started testing at 9600 bps.
RS485 would nice but not feasible, i cannot reprogram the slave devices to get polled or to add an ID to their messages :frowning:
The only thing that works is 1 instance of Softwareserial + the hardware serial.

nomadic68:
Ideally, i would need 8 ports so not even a Mega would be enough for me

If you really need several Serial Ports then multiple Megas may actually be the simplest (and maybe cheapest) solution.

However if the Mega can control the slaves so that only one of them can transmit at any one time then you could feed several slaves into one HardwareSerial port with a few external components. But that will ONLY work if the Mega can control which slave can talk. I can give more details if this is an appropriate solution.

...R

Using the Hardware UART, SoftwareSerial and AltSoftSerial, you can achieve up to 3, provided the baud rates are compatible and you aren't also trying to use timers and interrupts for other things.
https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

What are you trying to do?

this reply is mainly for @wildbill but everybody is welcome to help of course:

Given the unexpected problems I came across, I have taken a step back and I am currently just trying to make the unmodified TwoPortReceive sketch bundled with the SoftwareSerial library work.
For me, it does NOT work on an Arduino UNO (100% healthy, so no burned pins).
Besides of that, I have tried to change only the pins, maintaining the speed at 9600 bps.
Still no luck.
Only one instance of the library works for me.

For me, it does NOT work

What exactly does that mean ?

What is sending serial data to the Uno and how are you assuring that only data from one source is being sent at a time and not simultaneously ?

Following @UKHeliBob i elaborate better “does not work”:

-if i create only 1 instance of SoftwareSerial that works, tx and rx (with some possible error in rx)
-if i create more than 1 instance of SoftwareSerial all instances can transmit, but none of them receives.

What is sending data to that Uno is another Uno programmed to cyclically transmit messages on its SoftwareSerial ports, with 1 sec delay between each transmission: zero assumptions here, non simultaneous transmission is ensured.

I hope it is more clear now.

What are the software serial baud rates?

nomadic68:
-if i create only 1 instance of SoftwareSerial that works, tx and rx (with some possible error in rx)
-if i create more than 1 instance of SoftwareSerial all instances can transmit, but none of them receives.

If you attach any value to your own time you will just give up of Software Serial and get a Mega.

...R

When you get really tired of chasing your communication bugs, consider using RS-485 and adding addresses to each of the slave boards, so you can poll them individually and get their response. All on a single serial port.
Paul

When you get really tired of chasing your communication bugs, consider using RS-485

I suggested that in reply #3 to which the OP replied:

RS485 would nice but not feasible, i cannot reprogram the slave devices to get polled or to add an ID to their message

groundFungus:
I suggested that in reply #3 to which the OP replied:

I missed that. Thanks. Next time the OP will plan for such problems.
Paul

Hi all,
It seems that unfortunately we are getting nowhere , so i restate my question (unless moderator prefers me to open a new topic):
With an Arduino Uno, I tested the SoftwareSerial example "TwoPortReceive" as it is, without touching it, and found that it does not work as none of these software serial ports receive anything.
The sketch is configured for 2 Softwareserial instances, mapped on pins 10,11 (portOne) and (8, 9) (portTwo), RX pins being 10 and 8 respectively.
Baud rate at 9600 bps on all ports.
I am feeding this Uno with another Uno sending a message to the 1st serial port, then wait 1 sec, send another message to the 2nd serial port, then wait 1 sec, then back to the 1st serial port... (this is done with SoftwareSerial again: all multiple instances transmit as requested, with some possible occasional timing inaccuracies).

Has anybody found the same issue? Or has he/she found that this example sketch works instead?
Thanks

I think I’d want to prove that it works with a single receiving instance of software serial. I’d check each of your instances separately to be sure that it works on your selected pins.

the TwoPortReceive code is somewhat "crappy". it makes assumptions of perfect timing for sending stuff by doing

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

and assuming you don't send much (as the while loop will empty the buffer pretty quickly). If data comes in when you don't listen, it's a mess.

if you want to see this example work, I'd suggest you modify the codes so that YOU decide when to send to port1 and when to send to port2 and that the receiving end does not switch automatically (may be wait until it gets something).

ideally you would dump this idea of sticking to a UNO and move to a different solution (2 MEGAs for example). there is some hardware stuff also that could possibly help, Atlas Scientific has a 8:1 Serial Port Expander n(which I never tried - not sure how they handle buffering)

@wildbill: as i posted earlier, one instance of SoftwareSerial works (more or less: some occasional messages lost/corrupted).

@J-M-L: you are suggesting me to somehow sync the TX with the RX, right?
Looking at the code and after some testing and from what you say, i understand that the receiving Arduino is continuously switching at full speed between all instances, and it can either completely miss a transmission if it is not listening at that time. This is obvious. A less obvious thing seems to be that if an instance starts listening while a transmission is already in progress it does not recognize it and misses it.
So yes, i need to think of a hardware solution to buffer all the incoming data and cyclically check if something has arrived from somewhere. Thank you for linking the 8:1 expander, i will have a look into it.