How would the algorithm look like so I do not lose any data if only one micro is used?
Something like this:
Code:
unsigned char buffer1[600];
unsigned char buffer2[600];
unsigned char buffer3[600];
void loop() {
if (Serial1.available()) {
// read whatever is available into buffer1
// parse buffer1 for messages
}
if (Serial2.available()) {
// read whatever is available into buffer2
// parse buffer2 for messages
}
if (Serial3.available()) {
// read whatever is available into buffer3
// parse buffer3 for messages
}
}
The key to making this work is avoiding delay, so whatever you do, don't call the delay() function!
The main point is the interrupts and 64 byte buffering built into Serial1, Serial2 and Serial3 gives you about 5 ms before you risk losing incoming data (assuming 115200 baud). So in a worst case scenario where all 3 serial ports have messages arriving simultaneously, you need to make sure the work you do to parse and consume the data takes less than 1.6 ms, because all 3 of those available() functions might tell you data has arrived. If all 3 arrive at exactly the same moment, you might need to parse and consume the data from all 3 buffers. As long as you always complete the task fast enough, the buffers built into Serial1, Serial2, Serial3 will be able to capture incoming data.
As you develop this code, you'll probably do something like this:
Code:
if (Serial3.available()) {
elapsedMicros usec;
// read whatever is available into buffer3
// parse buffer3 for messages
Serial.print("Serial3 processing took ");
Serial.print((uint32_t)usec);
Serial.println(" us");
}
As data arrives on Serial3, you'll watch in the Arduino Serial Monitor while a flood of lines are printed the number of microseconds you spent. Almost all will be very small, since normally you'll read only the small amount of data that has arrived but it not yet a full message. The key point is you want to get the data out of Serial3's small buffer ASAP and into your big 600 byte buffer that you know is always enough to hold your message.
When you actually do something with the data, the microseconds printed will probably be more. This is where you need to focus your attention. Maybe you'll even add a little extra code to skip printing the message in the case where you didn't do the parsing. When you do, you want to make sure you're under 1600 microseconds. Then if all 3 happen to make 1600, you know that worst possible case is still less time than 60 bytes can arrive. Maybe if you're paranoid you'll add up all the very shot time take to read each byte and only put it into the buffer and consider than in your total 1600 time budget.
Of course all that printing of timing info will slow your program slightly, so when you delete it, you'll know you were able to meet the incoming data speed while suffering that overhead, so your final program will be even better.
If you get into this and you discover you're spending more than 1600 us, you could edit the serial driver code to increase the buffer size. Or you could ask here for ideas of how to make your code do its work faster. Or use Teensy 4.0 instead of Teensy 3.2, which will run your code at least 10X faster.
But if your code is slow for reasons other than the CPU speed, like you wait for some external thing to happen before you do work, then the incredible speed of Teensy 4.0 won't help. But we might. The key to getting good help here when you have a code problem is to show us the complete code that's not working. If you withhold pieces of the code or info about the data or other details, we might still be able to help with blind guesswork to fill in the details. But we do much better at helping when you show complete code, which is why we have the "Forum Rule" in red at the top of every page.
Just in case it's not obvious from all this, you absolutely should not get into the interrupts and buffering code inside Serial1, Serial2, Serial3. The only thing you should even think about doing there is editing the define for the buffer size. Otherwise, don't mess with that code. It's not a place to play unless you are an expert at device drivers. That code is very mature (on Teensy 3.x... everything is new on Teensy 4.0) and works very well. Just use the serial functions and focus on making sure your code always reads and processes the data in less time than the serial buffers would fill up. If you meet that timing need under all cases, then you will always be able to process the incoming data while the Serial1,2,3 driver code does all the work of actually acquiring the simultaneous incoming streams.