Serial communication between 1 master and 2 slaves very slow

Hello,

For a project I want to connect 2 slave Dues to 1 master Due.

The schematic is attached to this post.

The sketch for the master:

void setup() {
Serial.begin(115200);
Serial2.begin(38400);
Serial3.begin(38400);

Serial.println("Master started ...");

}

int start=0;

int counter=0;
void loop() {
if (counter++ % 2) {
start = millis();
Serial2.println("data");
while (!Serial2.available())
;
Serial.print("Serial2: ");
Serial.println(Serial2.readString());
Serial.println(millis()-start);
} else {
start = millis();
Serial3.println("data");
while (!Serial3.available())
;
Serial.print("Serial3: ");
Serial.println(Serial3.readString());
Serial.println(millis()-start);
}
}

The sketch for the 2 slaves:

void setup() {
Serial2.begin(38400);
}

int number = 0;

void loop() {
if (Serial2.available()) {
Serial2.readString();
Serial2.print(number++);
}
}

The output is:

Master started ...
Serial3: 0
2001
Serial2: 0
2001
Serial3: 1
2001
Serial2: 1
2001
Serial3: 2
2001
Serial2: 2
2001
Serial3: 3
2001
Serial2: 3
2000
Serial3: 4
2001

To my understanding, the master should output new numbers from both slaves at a high rate, however, sending and waiting for reception takes 2 seconds, resulting in very poor performance.

he Arduino Due has two USB ports available, each of them can establish ONE serial port, so with a DUE you can use Serial and Serial1, but Serial2 and Serial3 is bullshit. The MEGA2560 is aboard with 4 serial ports(Serial, Serial1, Serial2, Serial3).

readString has to timeout. Why use it? Can you use read?

Maybe it is readString causing you the problem. Normally strings are terminated with a 0 byte. If it doesn't get a 0, it will wait, then time out(?). I use read, but you should be able to use readStringUntil('\n'). edit: ...if the slaves use println.

I now updated the sketches to use readStringUntil, no success, still slow.

Master:

void setup() {
Serial.begin(115200);
Serial2.begin(38400);
Serial3.begin(38400);

Serial.println("Master started ...");

}

int start=0;

int counter=0;
void loop() {
if (counter++ % 2) {
start = millis();
Serial2.println("d");
while (!Serial2.available())
;
Serial.print("Serial2: ");
Serial.println(Serial2.readStringUntil('\n'));
Serial.println(millis()-start);
} else {
start = millis();
Serial3.println("data");
while (!Serial3.available())
;
Serial.print("Serial3: ");
Serial.println(Serial3.readStringUntil('\n'));
Serial.println(millis()-start);
}
}

Slave:

void setup() {
Serial2.begin(38400);
}

int number = 0;

void loop() {
if (Serial2.available()) {
Serial2.readStringUntil('\n');
Serial2.print(number++);
}
}

Any advice?

You must use Serial2.println on the slave. Like this:

void loop() {
  if (Serial2.available()) {
    Serial2.readStringUntil('\n');
    Serial2.println(number++);
  }
}

SurferTim:
You must use Serial2.println on the slave. Like this:

void loop() {

if (Serial2.available()) {
   Serial2.readStringUntil('\n');
   Serial2.println(number++);
 }
}

Thank you SurferTim, now it is working as expected, stupid mistake :wink:

Use either example 2 or 3 from Serial Input Basics. Simple reliable and non-blocking.

If you want to receive from 2 ports use two separate copies of the function - with suitably modified variable names.

...R