Лучшее решение для параллельного чтения 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.< /п>

Что я пробовал?

  1. Последовательное чтение всех последовательных портов — явно низкая производительность.
  2. Используются последовательные события — по какой-то причине не удается запустить обратный вызов.
  3. Использовал какую-то библиотеку FreeRTOS, и в ней много пропущенных данных.

При использовании RTOS данные с нескольких узлов смешиваются и печатаются неправильно. Я ищу какой-то эффективный способ чтения параллельных данных со всех UART без перекрытия данных и потоковой передачи данных, и, учитывая, что MCU на Arduino Due очень мощный, я не думаю, что это является узким местом в производительности.

, 👍2

Обсуждение

«Последовательное чтение всех последовательных портов — очевидно низкая производительность»… почему производительность должна быть плохой? ... вы это проверяли?, @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


1 ответ


Лучший ответ:

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