SoftwareSerial usage on Nano Every

Hey all!

Looking for a bit of help understanding the limitations of the SoftwareSerial library with an Arduino Nano Every.

Basically, I have seven XIAO-RP2040 microcontrollers attempting to transmit only (only TX is connected) across RS485/Ethernet to a single Nano Every. In turn, the Nano Every is attempting to receive only - and does not care about the ordering/timing on how each XIAO is read - only that it is read after a certain interval.

The XIAO-RP2040s are constantly transmitting a (possibly changing) byte value across their lines - which the Nano Every wants to read (from each XIAO) every X milliseconds, akin to:

SoftwareSerial portOne(19, 14);
SoftwareSerial portTwo(20, 15);
SoftwareSerial portThree(21, 16);
// Etc - more ports

void setup() {
  portOne.begin(9600);
  portTwo.begin(9600);
  portThree.begin(9600);
 // Etc - more ports

  // Un-related init of some variables
}

void loop() {
    if (lastSenseTimeMs + 150 < millis())
    {
      portOne.listen();
      new_position_one = portOne.read();
      delay(10);

      portTwo.listen();
      new_position_two = portTwo.read();
      delay(10);

      portThree.listen();
      new_position_three = portThree.read();
      delay(10);

      // Etc for more ports

      lastSenseTimeMs = millis();
    }

    // Do something with the above positions
}

Each 'portX' is a SoftwareSerial object/port. This works if a single XIAO's port is setup to be .read(), but siezes up the moment I enable more than one. Is there something simple I am missing before I start looking into an MC with more HW serial ports? Thanks!

With RS485 you can let the master (Nano Every) poll the slaves (XIAO-RP2040). So N asks X1 for data, gets the data, next asks X2 for data, gets the data and so on. That will make life probably easier and you only need one additional serial port which is available on pins 0 and 1 (not interfering with the communication with the PC).

A Nano Every has four hardware serial ports that you can use; see Arduino Nano Every Serial Ports – Kevin's Blog. I know that it's not seven but can be useful to know.

Hey @sterretje - that's a good idea - I'm guessing the flow would be something like:

  • Master initialize its MAX485's for all XIAO N to receive
  • Slaves initialize with their MAX485's set to receive

With the same HW Serial TX/RX pins connected from the Nano to every MAX485 RX/TX. Then in a loop for every XIAO/every X milliseconds:

  1. Master sets it MAX485 for XIAO N to transmit (digital pin to DE/RE to written HIGH)
  2. Master dispatches a Serial.write()
  3. Master sets its MAX485 for XIAO N to receive (digital pin to DE/RE to written LOW)
  4. Slave is checking Serial.available in a tight loop - notices data
  5. Slave N sets its MAX485 to transmit
  6. Slave N writes it's byte of data
  7. Slave N sets its MAX485 to receive
  8. Master sits checking Serial.available
  9. Receives data & calls .read()
  10. Master sets it MAX485 for XIAO N to receive
  11. Go to step 1 for XIAO N + 1/end of loop

I guess - beyond the complexity, is there any worry of contention? If I have the MAX485's on both sides for a given XIAO set to receive, does that effectively 'cut it off'? Thanks again for the help!

RS485 is a bus; you only need one MAX485 at the master side and connect it to all MAX485 at the slave sides.

The master sends a command (up to you to decide) which includes the number (ID) of the slave. All slaves are listening if one sees its ID it will reply.

  1. Master in transmit
    • Send e.g. <3, 1> to ask slave 3 to give the data or <3, 2, N> to write some data to the slave.
    • Master switches to 'listening' mode
  2. Slave is in 'listening' mode
    • Receive data
    • Check ID
    • Accept message if ID matches
    • If it's a write request (not applicable in your case), store received data
    • If it's a read request
      Switch to transmit mode
      Send the data
      Switch back to 'listening' mode'

How you implement the exact protocol is up to you. The <> are markers to indicate begin and end of a message, the command can also be e.g. 'r' for read and 'w' for write.

You can study Gammon Forum : Electronics : Microprocessors : RS485 communications for starters.

In general, softwareSerial implementations can only "receive" from one port at a time.

:man_facepalming: @sterretje That'll be way more simple - really appreciate the help! & will definitely check out the link, I have a lot to learn.