Лучшее решение для параллельного чтения UART с помощью Arduino Due
У меня есть 4 платы Arduino, передающие данные через UART на 4 последовательных порта Arduino Due со скоростью 115200
бод.
Формат данных - <Короткий URL>,<Номер узла>
Например: px.ht/d/mCxG,1»
Arduino Due имеет 4 аппаратных последовательных порта и один собственный порт USB. Я хочу подключить все 4 узла UART к каждому последовательному аппаратному обеспечению Due, а затем передать эти данные на порт SerialUSB
, который является собственным USB-портом со скоростью передачи данных 2000000
.< /п>
Что я пробовал?
- Последовательное чтение всех последовательных портов — явно низкая производительность.
- Используются последовательные события — по какой-то причине не удается запустить обратный вызов.
- Использовал какую-то библиотеку FreeRTOS, и в ней много пропущенных данных.
При использовании RTOS данные с нескольких узлов смешиваются и печатаются неправильно. Я ищу какой-то эффективный способ чтения параллельных данных со всех UART без перекрытия данных и потоковой передачи данных, и, учитывая, что MCU на Arduino Due очень мощный, я не думаю, что это является узким местом в производительности.
@Hako, 👍2
Обсуждение1 ответ
Лучший ответ:
Похоже, что оболочки Arduino для последовательных API работают очень медленно
Это не так. Есть некоторые функции, которые зависят от таймаутов: они могут
действительно быть очень медленным. Однако если вы читаете порты в неблокирующем
мода, все должно быть быстро. Неблокировать по сути означает никогда
ожидание и никогда не пытающееся прочитать больше байтов, чем сейчас
доступно()
. Например:
const int buffer_size = 64; // настраиваем по вкусу
char buffer1[buffer_size];
int size1 = 0;
// то же самое для буфера2, размера2 и т. д.
void loop() {
while (Serial1.available()) {
char c = Serial1.read();
if (size1 < buffer_size - 1)
buffer1[size1++] = c; // буферизуем входящий символ
if (c == '\n') { // найден конец сообщения
buffer1[size1] = '\0'; // завершаем строку
Serial.print(buffer1); // отправляем через USB
size1 = 0; // готовимся к следующему сообщению
}
}
// то то же самое для Serial2, ...
}
Если вы немного разбираетесь в объектно-ориентированном программировании, вы легко сможете перепишите это более элегантно, без повторного кода.
Спасибо @EdgarBonet, я обязательно опробую эту логику, однако мне интересно, есть ли способ использовать DMA SAM3X для прямой передачи данных из буфера UART в буферы USB. Я считаю, что это значительно увеличивает производительность. Что ты говоришь? Есть ли оболочка DMA, о которой вы знаете, которую я могу использовать с Arduino IDE?, @Hako
Насколько мне известно, в API Arduino нет поддержки DMA. Но учитывая, что у вас быстрый процессор, я ожидаю, что он вам не понадобится., @Edgar Bonet
@Хако, не упускай из виду тот факт, что данные поступают со скоростью улитки ... если бы компьютер был человеком, байт приходил бы раз в неделю, @jsotola
@jsotola хахахаха, конечно, я понимаю, что sam3x работает на высоких частотах, но меня беспокоит то, что количество узлов может увеличиться в будущем, и мне нужно, чтобы мой код был масштабируемым. В любом случае, позвольте мне сначала опробовать код Эдгара и вернуться с быстрыми результатами., @Hako
- Может ли Arduino Leonardo одновременно использовать USB-порт и последовательные контакты RX TX?
- SerialUSB на Arduino Due
- Какой чип USB-UART обеспечивает самую высокую скорость передачи данных с платами Arduino?
- Использование последовательных контактов TX/ RX для связи по USB
- Связь с пользовательским USB-ведомым устройством осуществляется с помощью DUE?
- Невозможно загрузить скетч в Lolin S3 Pro (ESP32-S3)
- Arduino Mega Loopback Test с несколькими портами TX/RX
- Сброс соединения UART на Due
«Последовательное чтение всех последовательных портов — очевидно низкая производительность»… почему производительность должна быть плохой? ... вы это проверяли?, @jsotola
Добавьте признак завершения строки в ваш формат данных (например,
'\n'
). Это сделает вашу жизнь **намного** проще., @Edgar Bonet@jsotola Кажется, оболочки Arduino для последовательных API работают очень медленно, а чтение/управление данными происходит очень медленно. Да, я проверял это, @Hako
@EdgarBonet Да, у меня есть разделитель в конце, но какая у вас идея, которая могла бы упростить задачу? Вы хотите, чтобы я реализовал логику, которая будет искать этот
\n
и не печатать, пока он не будет найден?, @Hakoэто может помочь... https://gammon.com.au/serial, @jsotola
@Ergophobia - Кстати, «Grammer» пишется *gramm**a**r*, то есть с «*a*», а не с «e»., @Greenonline