Wie erkennt diese Codezeile, ob eine serielle Schnittstelle angeschlossen ist?

7

Ich arbeite mit einem Code für entfernte Temperatursensorknoten. Sie schalten die Debug-Schnittstelle ein und aus, je nachdem, ob etwas an die serielle Schnittstelle angeschlossen ist oder nicht.

Der Code ist auf Github hier . Zeile 111 ist die interessierende Zeile:

if (Serial) debug = 1; else debug=0; //if serial UART to USB is connected show debug O/P.

Eine einfache Frage: Wie funktioniert das auf Hardware- und Softwareebene? Ich kann in HardwareSerial oder Stream nichts sehen, was true / false zurückgeben würde, wenn etwas verbunden wäre oder nicht.

Beachten Sie, dass ich nicht sicher bin, ob es tatsächlich funktioniert. Dieser einfache Test zeigt an, dass er nicht funktioniert, da die LED unabhängig vom Vorhandensein eines seriellen Adapters oder einer seriellen Verbindung blinkt:

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);
  }
}
Cybergibbons
quelle
2
Nebenbemerkung: Bei herkömmlichem RS232 besteht die einzige Möglichkeit, wirklich festzustellen, ob eine Verbindung besteht, darin, Daten zu senden und zu prüfen, ob Sie eine Antwort erhalten. Es gibt keinen anderen universellen Verbindungserkennungsmechanismus. Aus diesem Grund werden serielle Geräte unter Windows manchmal immer noch als Maus erkannt. Das Betriebssystem geht davon aus, dass ein bestimmter Zeichensatz bedeutet, dass eine Maus vorhanden ist, da es keine andere Möglichkeit gibt, diese Annahme zu bestätigen. Es wird nur damit ausgeführt.
Connor Wolf

Antworten:

12

Sie haben Recht - es funktioniert in den meisten Fällen nicht und gibt fast immer true zurück. Das einzige Board, auf dem es tatsächlich funktioniert, ist das Leonardo. Laut offizieller Dokumentation :

Wenn (seriell) auf dem Leonardo anzeigt, ob die serielle USB-CDC-Verbindung offen ist oder nicht. In allen anderen Fällen, einschließlich if (Serial1) auf dem Leonardo, wird immer true zurückgegeben.

Grundlegende serielle Verbindungen (von den meisten Arduinos verwendet) kümmern sich normalerweise nicht darum, ob tatsächlich etwas zuhört. Es ist nicht ungewöhnlich, dass eingebettete Geräte Debug-Informationen seriell senden, auch wenn sie von nichts empfangen werden. Dies hat den Vorteil, dass sich das Timing und Verhalten des Codes beim Debuggen nicht ändert. Dies kann zu allen möglichen Problemen führen, wenn Sie versuchen, ein im Feld gemeldetes Problem zu diagnostizieren.

Peter Bloomfield
quelle
4

Während möglicherweise nicht erkannt werden kann, ob ein Gerät an die serielle Arduino-Verbindung angeschlossen ist oder nicht, können die Debug-Meldungen über die serielle Verbindung basierend auf dem Vorhandensein eines Geräts in der seriellen Verbindung aktiviert werden .

Da Sie die Debug-Oberfläche Ihrer Skizze nur verwenden, wenn Sie an einen Computer angeschlossen sind, der serielle Kommunikation ermöglicht, können Sie einen einfachen Test in die Skizze integrieren, basierend darauf, welcher Debug-Modus aktiviert ist oder nicht.

Wenn die Skizze beginnt, können Sie überprüfen, ob Daten für die serielle Verbindung verfügbar sind oder nicht. Wenn dies der Fall ist, ist ein Gerät vorhanden und das Debuggen kann aktiviert werden. Auf der Computerseite senden Sie jedes Mal, wenn Sie den Debugging-Modus auf dem Arduino starten möchten, während der setupPhase einfach ein Byte über die serielle Verbindung und lehnen Sie sich zurück.

Hier ist eine Beispielskizze, die dasselbe zeigt:

int debug = 0;

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

  //Wait for four seconds or till data is available on serial, 
  //whichever occurs first.
  while(Serial.available()==0 && millis()<4000);

  //On timeout or availability of data, we come here.
  if(Serial.available()>0)
  {
    //If data is available, we enter here.
    int test = Serial.read(); //We then clear the input buffer

    Serial.println("DEBUG"); //Give feedback indicating mode

    debug = 1; //Enable debug
  }
}

void loop()
{
  if(debug==1) Serial.println("ON");
  digitalWrite(13,HIGH);
  delay(1000);
  if(debug==0) Serial.println("OFF");
  //Turn off if serial is not available
  digitalWrite(13,LOW);
  delay(1000); 
}
asheeshr
quelle
Dies ist so ziemlich die Technik, die ich für meinen eigenen Code verwende.
Cybergibbons
Imho, Sie können auch die serielle Ausgabe aktivieren, sobald ein Zeichen empfangen wird. Oder verwenden Sie verschiedene Build-Modi (in einer erweiterten IDE) oder prüfen Sie sogar, ob die Eingangsspannung vom USB stammt.
Paul