Как эта строка кода определяет, подключен ли последовательный интерфейс?

Я работаю с некоторым кодом для удаленных узлов датчиков температуры. Они включают и выключают интерфейс отладки в зависимости от того, подключено что-либо к последовательному порту или нет.

Код находится на Github здесь. Строка 111 представляет интерес:

if (Serial) debug = 1; else debug=0; //если подключен последовательный UART к USB, покажите отладку O/P.

Итак, простой вопрос: как это работает на аппаратном и программном уровне? Я не вижу ничего в HardwareSerial или потоке, что возвращало бы true/false, если бы что-то было подключено или нет.

Обратите внимание, что я не уверен, что это действительно работает. Этот простой тест показывает, что он не работает, так как светодиод мигает независимо от наличия последовательного адаптера или подключения:

boolean debug;

const int toggle = 6;

void setup()
{
  if (Serial) debug = 1; else debug = 0;

  pinMode(toggle, OUTPUT);
  digitalWrite(toggle, LOW);

  if (debug)
  {
    Serial.begin(9600);
    Serial.println("Setup");
    digitalWrite(toggle, HIGH);
    delay(1000);
    digitalWrite(toggle, LOW);
  }
}

void loop()
{
  if (debug)
  {
    Serial.println("Loop");
    digitalWrite(toggle, HIGH);
    delay(1000);
    digitalWrite(toggle, LOW);
    delay(1000);
  }
}

, 👍11

Обсуждение

Примечание: Для традиционного RS232 единственный способ действительно определить, подключено ли что-то, - это отправить данные и посмотреть, получите ли вы ответ. Другого универсального механизма обнаружения соединений не существует. Вот почему последовательные устройства в Windows все еще иногда распознаются как мышь. ОС предполагает, что определенный набор символов означает наличие мыши, поскольку у нее нет другого способа подтвердить это предположение, она просто работает с ним., @Connor Wolf


2 ответа


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

14

Вы правы - в большинстве случаев это не работает и почти всегда возвращает истину. Единственная плата, на которой она действительно работает, - это Леонардо. Согласно официальной документации:

На Леонардо, если (последовательный) указывает, открыто или нет последовательное соединение USB CDC. Для всех остальных экземпляров, включая if (Serial1) на Leonardo, это всегда будет возвращать значение true.

Базовые последовательные соединения (используемые большинством ардуино) обычно не заботятся о том, действительно ли что-то прослушивается. Нередко встроенные устройства отправляют отладочную информацию по последовательному каналу, даже если ее никто не получает. Это имеет то преимущество, что время и поведение кода не изменятся при отладке, что может вызвать всевозможные проблемы, если вы пытаетесь диагностировать проблему, о которой сообщается в поле.

,

6

Хотя может оказаться невозможным определить, подключено ли устройство к последовательному соединению Arduino или нет, можно включить отладочные сообщения по последовательному соединению на основе наличия устройства в последовательном соединении.

Учитывая, что вы будете использовать интерфейс отладки своего скетча только при подключении к компьютеру, способному к последовательной связи, в скетч можно включить простой тест, в зависимости от того, включен режим отладки или нет.

При запуске скетча вы можете проверить, доступны ли какие-либо данные в последовательном соединении или нет. Если есть, значит, устройство присутствует и можно включить отладку. На стороне компьютера каждый раз, когда вы хотите запустить режим отладки на Arduino, просто отправьте байт по последовательному соединению во время фазы настройки и расслабьтесь.

Вот примерный скетч, показывающий то же самое:

int debug = 0;

void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(9600);

  //Подождите четыре секунды или до тех пор, пока данные не будут доступны на последовательном,
  //в зависимости от того, что произойдет раньше.
  while(Serial.available()==0 && millis()<4000);

  //По тайм-ауту или наличию данных мы приходим сюда.
  if(Serial.available()>0)
  {
    //Если данные доступны, мы вводим здесь.
    int test = Serial.read(); //Затем мы очистим входной буфер

    Serial.println("ОТЛАДКА"); //Режим указания обратной связи

    debug = 1; //Включить отладку
  }
}

void loop()
{
  if(debug==1) Serial.println("ON");
  digitalWrite(13,HIGH);
  delay(1000);
  if(debug==0) Serial.println("OFF");
  //Выключите, если Serial недоступен
  digitalWrite(13,LOW);
  delay(1000); 
}
,

Это в значительной степени та техника, которую я использую в своем собственном коде., @Cybergibbons

Имхо, вы также можете включить последовательный вывод, как только он получит символ. Или используйте другие режимы сборки (в расширенной среде IDE), или, может быть, даже проверьте, поступает ли входное напряжение от USB., @Paul