Можно ли использовать Serial.print(сообщение), когда USB-кабель не подключен к хост-компьютеру?

Часто я добавляю кучу Serial.print( F("отладочные сообщения") ) в свой скетч Arduino.

Обычно эти сообщения передаются по кабелю USB на хост-компьютер, чтобы их можно было увидеть на последовательном мониторе.

Я хочу установить этот Arduino как часть автономной системы вдали от любого ПК и подключить «хост»-конец USB-кабеля к настенному зарядному устройству USB.

Без устройства, принимающего эти сообщения, буфер Arduino в конце концов заполняется, верно? Нужно ли мне что-то делать, чтобы Arduino не переполнялась и не зависала, когда он не подключен к хост-компьютеру?

Есть ли какая-то разница, если я использую (1) «одночиповый» Arduino-совместимый процессор, в котором процессор включает встроенный USB, и (2) Arduino-совместимый с отдельным «интерфейсным чипом USB»? а "чип процессора"? (Под «одночиповым Arduino-совместимым» я подразумеваю такие устройства, как Arduino Leonardo, Arduino Yun, LilyPad Arduino USB, Arduino Micro, Teensy-LC и т. д.)

, 👍11


1 ответ


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

8

Можно записывать последовательные данные без каких-либо подключений.

В случае (2) «чип интерфейса Arduino + USB» arduino не знает, подключено ли что-либо или прослушивает последовательный порт. Код будет передавать байты и действовать точно так же, независимо от того, подключен ли он к чему-либо или нет.

В случае (1) "arduino со встроенным USB" у него есть некоторое представление, но он просто отбрасывает байты, которые будут переданы, когда порт USB не подключен.

Аппаратный последовательный порт (вариант 2) имеет выходной буфер, но это просто делает программу немного быстрее. Когда буфер пуст, вызов serial.{print, write поместит байты в буфер и продолжит работу. Когда он заполнится, Serial.{print,write} будет ждать, пока не будет достаточно места, чтобы поместить остальную часть сообщения в буфер, и двигаться дальше. Аппаратный UART и генерируемые им прерывания будут продолжать извлекать байты из буфера и передавать их с постоянной скоростью независимо от того, подключено что-то или нет. В любом случае буфер имеет фиксированный размер и никогда не переполняется.

Насколько я могу судить, USB-Serial (вариант 1) буферизует только входящие данные. Поскольку вызовы Serial.{print, write ничего не делают, когда нет подключения, они могут занять меньше времени, чем в противном случае. Если ваш код действительно небезопасен в отношении времени, это может вызвать проблему, но я сомневаюсь, что это произойдет.

Многие примеры, которые поставляются с Arduino IDE, содержат следующий фрагмент кода, который приостанавливает использование родных USB-совместимых Arduino-совместимых устройств до тех пор, пока USB-соединение не будет инициализировано:

  while (!Serial) {
    ; // ждем подключения последовательного порта. Требуется только для родного порта USB
  }

Этот код запрещает Arduino выполнять какие-либо действия до тех пор, пока USB-кабель не будет подключен. Закомментируйте или удалите эти 3 строки, если вы хотите, чтобы Arduino работал «автономно». без подключения USB-кабеля (Поваренная книга Arduino, стр. 117) -- после того, как вы удалите эти строки, если вы позже подключите USB-кабель, USB будет правильно инициализирован, и затем вы увидите на своем последовательном мониторе все, что напечатано любым более поздним последовательным команды .print(), которые выполняются. (Проверено на Teensy LC).

,

Когда он заполнится, Serial.{print,write} будет ждать - поясню, он заполняется из-за скорости (т.е. вы печатаете слишком быстро), а не из-за того, что ничего не подключено., @Nick Gammon

В случае (1), когда вы говорите «отбрасывает байты, которые будут переданы, когда USB-порт не подключен», вы имеете в виду, что он передает их (возможно, в ничто) через аппаратный TX?, @ChemiCalChems

Извините, @NickGammon, но мне кажется, что, по крайней мере, на плате на базе Leonardo (с поддержкой USB в ЦП), если я загружу довольно сложный скетч с большим количеством Serial.print (проверено как на 9600, так и на 115200) , я вижу, что: 1) если я включаю плату, с внешним USB, подключенным к ПК; все работает отлично. И все равно работать, если я "отключу" кабель; 2) если я включу питание платы _БЕЗ подсоединенного кабеля, плата никогда не войдет даже в основной контур()! - Мне кажется, что при "заполнении" буфера все зависает. Является ли это ожидаемым поведением (... которое я должен обойти на уровне приложения)?, @Damiano Verzulli

Скетчи с микросхемами в стиле Леонардо со встроенным USB часто имеют цикл в настройке: while (!Serial.available()) { }, который бесконечно повторяется, пока последовательное соединение не будет установлено через USB. Именно эта петля заставляет его зависать. На других платах этот вызов немедленно возвращается, и любые отправленные данные просто исчезают «с конца провода», если ничего не подключено. Вы всегда можете выйти из этого цикла после (скажем) 10 000 итераций или через пару секунд. ., @Nick Gammon