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).
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:
Master sets it MAX485 for XIAO N to transmit (digital pin to DE/RE to written HIGH)
Master dispatches a Serial.write()
Master sets its MAX485 for XIAO N to receive (digital pin to DE/RE to written LOW)
Slave is checking Serial.available in a tight loop - notices data
Slave N sets its MAX485 to transmit
Slave N writes it's byte of data
Slave N sets its MAX485 to receive
Master sits checking Serial.available
Receives data & calls .read()
Master sets it MAX485 for XIAO N to receive
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.
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
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.