Какова минимально возможная задержка между Arduino и ПК?
Характеристики корпуса:
- Операционная система ПК: Debian 9, 64-разрядная версия.
- Начальная точка: у меня есть буфер размером 1 КБ на Arduino, который я хочу отправить на хост-компьютер
- Конечная точка времени: я получил буфер в специально написанном приложении C\C++, запущенном на хост-компьютере
- Я хочу отправлять такой буфер раз в секунду
Какова минимально возможная задержка — время, прошедшее между начальной и конечной точками? и при каком типе связи? (последовательная?)
@xakepp35, 👍0
2 ответа
Лучший ответ:
Коммуникация с малой задержкой — это нечто большее, чем просто передача данных с максимально возможной скоростью (хотя это важная ее часть).
Одна вещь, о которой люди часто забывают, заключается в том, что Arduino может (легко) делать только одну вещь за раз. Пока вы отправляете буфер на ПК, он не может производить выборку и заполнять ваш буфер. Если у вас есть буфер, который заполняется в течение 1 секунды, и вы хотите отправить этот буфер на ПК, когда он заполнится, что произойдет в следующую секунду, пока вы отправляете буфер? Буфер не может заполняться во время отправки.
Использование обычного соединения UART-USB, которое используют большинство обычных плат Arduino (Uno, Mega и т. д.), обеспечивает самую высокую скорость, на которую можно рассчитывать, — около 1 Мбод. Это около 100 кБ/с. Меньше, если использовать дешевый китайский клон с CH340G. Даже при 100 кБ/с ваш буфер размером 1 кБ, если он будет отправлен полностью сырым и в двоичном виде, займет около 10 мс. Но заставить компьютер осмыслить эти сырые данные будет сложно. Поэтому вам придется обернуть их в какой-то протокол (разработать его вам...), так что вы можете получить половину этой скорости (или даже хуже, в зависимости от конструкции вашего протокола).
И за это время ничего больше произойти не может.
Для плавной передачи данных с низкой задержкой гораздо предпочтительнее использовать буферы «пинг-понга» и выборку данных с прерываниями или DMA. Это означает, что один буфер получает ваши данные из любого источника, а другой отправляется на ПК. После заполнения первого буфера они меняются ролями. Однако маленькие 8-битные Arduino не очень подходят для таких вещей:
- У них не так много оперативной памяти, чтобы тратить ее на два буфера
- У них нет прерываний с приоритетами, позволяющих производить выборки во время отправки
- У них нет DMA для фоновой передачи данных на/с периферийных устройств
Если задержка действительно так критична, вам лучше использовать один из Arduino на базе ARM, например Due, где вы также можете воспользоваться высокоскоростным собственным интерфейсом USB, который может обеспечить гораздо более высокую пропускную способность, чем соединение UART. Ваш выбор конечной точки USB также может повлиять на задержку вашего проекта:
- Изохронный — наименьшая задержка, небольшие пакеты, доставка не гарантируется
- Прерывание — средняя задержка, небольшие пакеты, гарантированная доставка
- Оптовая доставка — высокая задержка, большие пакеты, гарантированная доставка
Изохронный используется в основном для аудио, где вы заметите малейшую задержку звука, но не обязательно заметите или будете беспокоиться о небольшом сбое в качестве. Прерывание используется для таких вещей, как HID, где вам нужно, чтобы он реагировал на нажатие клавиш на клавиатуре быстро и аккуратно, но вы никогда не отправляете много данных (ограничение пакета в 64 байта при передаче прерываний). Массовый используется для таких вещей, как CDC/ACM (последовательный через USB), где вы можете захотеть передать много данных, но не заметите, если он время от времени останавливается на несколько мс (HS USB имеет ограничение пакета в 512 байт при массовой передаче, FS USB имеет ограничение в 64 байта).
Одной из замечательных особенностей прямого USB-подключения является то, что оно полностью основано на пакетах, поэтому вы можете использовать его в качестве протокола передачи, если знаете, что делаете. Не полагайтесь только на «трубу» CDC/ACM, а вместо этого используйте базовый USB-протокол для отправки отдельных пакетов, которые принимающая программа затем может понять и разбить на нужные данные без добавления дополнительных накладных расходов протокола.
Для более продвинутого программирования USB ядра Teensy и chipKIT имеют гораздо более развитую поддержку USB, чем ядро Arduino, поэтому вы можете рассмотреть их предложения в плане плат, которые могут лучше соответствовать вашим потребностям.
это не совсем то, что вы спрашиваете, но вчера я проверил скорость с помощью этого скетча:
void setup() {
Serial.begin(460800);
delay(5000);
}
void loop() {
Serial.println();
unsigned long start = millis();
for (unsigned long i = 0; i < 1000000L; i++) {
Serial.write('A');
}
Serial.flush();
Serial.println();
Serial.println(millis() - start);
while(true);
}
для получения на Linux в файл:
stty -F /dev/ttyACM0 460800
(stty raw; cat > received.txt) < /dev/ttyACM0
Скетч измерил 20000 мс, чтобы передать этот 1 МБ через последовательный порт. Arduino - это Mega 2560. При скорости 921600 бод не все данные были переданы.
РЕДАКТИРОВАНИЕ: клон Nano 328p с CH340 завершен только на скорости 230400 бод за 45000 мс
- Как передать строковые данные с помощью библиотеки rc-switch?
- Какой максимальный размер статического документа Json в Arduino JSON?
- Очистка строкового буфера с помощью memset после последовательного чтения
- Использует ли Arduino Mega один буфер или несколько буферов?
- Проблема с очисткой строки, считанной из последовательного буфера
- Ошибка обработки строк и символов
- Два радиомодуля nRF24L01 на Arduino
- Arduino IDE, эквивалентный DataView?