I have 4 Arduino boards pushing data over UART to 4 serial ports on the Arduino Due at 115200
baud rate.
Data format - <Short URL>,<Number of the Node>
Eg: px.ht/d/mCxG,1"
Arduino Due has 4 hardware serial ports and one native USB port. I want to interface all the 4 UART nodes to each hardware serial of the Due and then push this data onto the SerialUSB
port which is native USB at baud rate of 2000000
.
What did I try?
- Sequential read of all Serial ports - Obviously poor performance
- Used Serial Events - For some reason never able to get the callback triggered.
- Used some FreeRTOS library and there are a lot of data misses.
When using RTOS, the data from multiple nodes is getting mixed up and printed incorrectly. I'm looking for some efficient way to read parallel data from all UARTs without data overlap and stream data and given the MCU on Arduino Due is very powerful I don't think that's what is bottlenecking the performance.
1 Answer 1
It seems the arduino's wrappers for serial API's are very slow
They aren't. There are some functions that depend on timeouts: these can
indeed be very slow. However, if you read the ports in a non blocking
fashion, everything should be fast. Non blocking basically means never
waiting, and never trying to read more bytes than what is currently
available()
. For example:
const int buffer_size = 64; // tune to taste
char buffer1[buffer_size];
int size1 = 0;
// same for buffer2, size2, etc.
void loop() {
while (Serial1.available()) {
char c = Serial1.read();
if (size1 < buffer_size - 1)
buffer1[size1++] = c; // buffer the incoming character
if (c == '\n') { // found end-of-message
buffer1[size1] = '0円'; // terminate the string
Serial.print(buffer1); // send through USB
size1 = 0; // get ready for next message
}
}
// then the same for Serial2, ...
}
If you know a bit about object oriented programming, you can easily rewrite this in a more elegant way, with no repeated code.
-
Thanks @EdgarBonet, I'll definitely try out this logic, however I'm wondering if there's a way I can utilize DMA of the SAM3X to directly push data from UART buffer into the USB buffers. I believe this significantly increases performance. What do you say? Is there a DMA wrapper you're aware of that I can use with Arduino IDE?Hako– Hako2023年11月10日 16:09:29 +00:00Commented Nov 10, 2023 at 16:09
-
There is no DMA-specific support in the Arduino APIs that I know about. But given that you have a fast CPU, I would expect you don't need it.Edgar Bonet– Edgar Bonet2023年11月10日 16:12:30 +00:00Commented Nov 10, 2023 at 16:12
-
@Hako don't lose sight of the fact that the data arrives at snail's pace ... if the computer was a person, a byte would arrive once a weekjsotola– jsotola2023年11月10日 16:14:12 +00:00Commented Nov 10, 2023 at 16:14
-
@jsotola hahahaha, ofcourse i understand sam3x runs at high frequencies but my concern is these nodes might increase in future and I need my code to be scalable. Anyway, let me first try out the edgar's code and come back with some quick results.Hako– Hako2023年11月10日 16:16:53 +00:00Commented Nov 10, 2023 at 16:16
Sequential read of all Serial ports - Obviously poor performance
... why should the performance be poor? ... have you tested this?'\n'
). This will make your life much easier.\n
and not print until it is found?