I'm working on a project where I need to send 8 bytes of data over 6 hardware serial ports at a strict 1 kHz rate—any delay causes the motor driver to jitter.
In my current setup, I’m using an IntervalTimer to trigger the send every 1ms. When triggered, I send 8 bytes over Serial1 through Serial6 (all at 460800 baud, the max the motor driver can do). I measured the send time and it takes about 200 µs in the worst case. I'm expecting a reply from each serial port around 250 µs later, assuming it takes the same amount time to read, the whole cycle shouldn't take more than 650 µs
Here’s a simplified version of the code:
Given that the Teensy 4.1 hardware serial FIFO buffer is only 4 bytes deep, is this approach reliable for a strict 1 kHz send/receive cycle across 6 serial ports?
Are there risks of overruns or timing conflicts that could break this under real-time constraints?
In my current setup, I’m using an IntervalTimer to trigger the send every 1ms. When triggered, I send 8 bytes over Serial1 through Serial6 (all at 460800 baud, the max the motor driver can do). I measured the send time and it takes about 200 µs in the worst case. I'm expecting a reply from each serial port around 250 µs later, assuming it takes the same amount time to read, the whole cycle shouldn't take more than 650 µs
Here’s a simplified version of the code:
C++:
IntervalTimer sendTimer;
volatile bool sendFlag = false;
uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; // 8 bytes
void triggerSend() {
sendFlag = true;
}
void setup() {
Serial.begin(115200);
while (!Serial); // Wait
Serial1.begin(460800);
Serial2.begin(460800);
Serial3.begin(460800);
Serial4.begin(460800);
Serial5.begin(460800);
Serial6.begin(460800);
sendTimer.begin(triggerSend, 1000); // 1 kHz = every 1000 µs
}
void loop() {
if (sendFlag) {
sendFlag = false;
uint32_t t_start = micros();
Serial1.write(data, sizeof(data));
Serial2.write(data, sizeof(data));
Serial3.write(data, sizeof(data));
Serial4.write(data, sizeof(data));
Serial5.write(data, sizeof(data));
Serial6.write(data, sizeof(data));
Serial1.flush();
Serial2.flush();
Serial3.flush();
Serial4.flush();
Serial5.flush();
Serial6.flush();
uint32_t t_end = micros();
uint32_t duration = t_end - t_start;
Serial.print("Write duration (us): ");
Serial.println(duration);
}
}
void serialEvent()
{
}
/* based on the feedback on each port, do some math */
void serialEvent1()
{
}
void serialEvent2()
{
}
void serialEvent3()
{
}
void serialEvent4()
{
}
void serialEvent5()
{
}
void serialEvent6()
{
}
Are there risks of overruns or timing conflicts that could break this under real-time constraints?