Zum Hauptinhalt springen

Serielle Geräte und Arduino

Die Serial*-Funktionen kommunizieren mit allem, was als COM-Anschluss erscheint: einem Arduino, ESP32 oder Raspberry Pi Pico über USB, einem USB-Seriell-Adapter, einem GPS-Empfänger, einem Barcodescanner im seriellen Modus, einem Bon- oder Etikettendrucker, einem 3D-Drucker oder einer CNC-Steuerung, die G-Code annimmt, einem Laborgerät oder einer selbst gebauten Tastenbox, einem Makropad, einem Drehknopf oder einer LED-Steuerung. Das Gerät sendet und empfängt Textzeilen; Ihre Skripts machen aus diesen Zeilen alles andere, was Input.Observer kann.

Einige Ideen:

  • Eine Tastenbox oder ein Makropad. Ein Arduino liest seine Tasten und gibt B1, B2, ... aus. Ein serieller Monitor macht aus jeder Zeile eine Tastenkombination, eine Medientaste oder einen Fensterbefehl.
  • Ein Lautstärke- oder Scrollknopf. Ein Potentiometer oder Drehgeber gibt seine Position aus; der Monitor stellt die Lautstärke ein oder scrollt.
  • Statusleuchten. Eine Geste oder ein Hotkey sendet LED 255 0 0 an ein Board, das einen LED-Streifen steuert, sodass ein Licht anzeigt, dass die Aufnahme läuft oder der Build fehlgeschlagen ist.
  • Sensoren. Ein Timer fragt ein Board nach Temperatur oder Helligkeit und zeigt den Wert an, protokolliert ihn in einer Datei oder dimmt den Bildschirm.
  • Scanner und Lesegeräte. Jeder Barcode und jedes RFID-Tag, das das Lesegerät sendet, wird zu getipptem Text, einer Suche oder einer Abfrage in einer Datei.
  • Maschinen. Senden Sie G-Code-Zeilen an einen Drucker oder Plotter, ein SerialWriteTextLine pro Befehl.

Den Anschluss finden​

Windows gibt jedem Gerät einen Namen wie COM3. Der Geräte-Manager führt es unter Anschlüsse (COM & LPT) auf; die Arduino IDE zeigt es in ihrem Board-Menü. Auch ein Skript kann sie auflisten:

n = SerialEnumeratePorts();
if (n == 0) UtilityPrint("No COM ports. Is the board plugged in?");
for (i = 0; i < n; i = i + 1) {
UtilityPrint(SerialGetEnumeratedPortAt(i));
}

Die Liste ist nach Nummer sortiert, daher kommt COM3 vor COM10. Die Nummer kann sich ändern, wenn das Gerät an einen anderen USB-Anschluss wechselt.

Geschwindigkeit, Rahmenformat und Zeilenenden​

  • Die Geschwindigkeit (baudRate) muss zum Gerät passen: die Zahl in Serial.begin(...) eines Arduino-Sketches, meist 9600 oder 115200.
  • Das Rahmenformat ist fast immer 8 Datenbits, keine Parität, ein Stoppbit: 8, SerialParity.None, SerialStopBits.One. Schreiben Sie die Konstanten aus: Die bloße Zahl 1 als Stoppbit-Argument bedeutet eineinhalb Stoppbits.
  • Zeilenenden. Eine empfangene Zeile endet an dem von Ihnen angegebenen terminator, der aus der Zeile entfernt wird. Leerer Text bedeutet CR LF, was Serial.println von Arduino sendet. Für ein Gerät, das Zeilen nur mit LF beendet, verwenden Sie "\n"; nur für CR verwenden Sie "\r". SerialWriteTextLine beendet das Gesendete mit demselben terminator oder mit CR LF, wenn der Aufruf den Anschluss selbst öffnet. Mit CR LF erhält ein Arduino-Sketch, der mit Serial.readStringUntil('\n') liest, die Zeile mit einem abschließenden CR, das trim() entfernt; mit "\n" gibt es kein CR zu entfernen.
  • Signale. Das Öffnen eines Anschlusses schaltet seine Signale DTR und RTS ein, wie es die Arduino IDE tut. Dadurch starten die meisten Arduino-Uno- und -Nano-Boards neu, ebenso andere Boards mit derselben Reset-Schaltung.

Drei Wege, mit einem Gerät zu kommunizieren​

  • Eine Frage, eine Antwort. SerialWriteTextLine und SerialGetTextLine öffnen einen nicht geöffneten Anschluss für diesen einen Aufruf mit dem baudRate des Aufrufs, 8-N-1. Das Argument baudRate wird ignoriert, wenn der Anschluss bereits geöffnet ist. Das genügt für ein Gerät, das beim Öffnen seines Anschlusses nicht neu startet. Siehe Ein serielles Gerät etwas fragen.

  • Ein offen gehaltener Anschluss. SerialOpenPort öffnet den Anschluss mit Ihren Einstellungen bis zu SerialClosePort und sammelt jede Zeile, die das Gerät sendet, damit SerialGetTextLine sie lesen kann. Die meisten Arduino-Uno- und -Nano-Boards starten neu, sobald ihr Anschluss geöffnet wird; öffnen Sie den Anschluss daher einmal, im globalen Ereignis „Konfiguration geladen“, und lassen Sie Gesten und Hotkeys darauf schreiben. SerialOpenPort gibt false für einen Anschluss zurück, der fehlt, getrennt ist oder in einem anderen Programm geöffnet ist; für einen Anschluss, den Input.Observer bereits geöffnet hat oder den ein Monitor belegt, beendet es die Aktion mit einem Fehler.

    // Load global event: open the port once, at the sketch's speed. An Uno or Nano
    // restarts every time its port opens, so a port opened per command would lose
    // the command while the board boots.
    if (!SerialOpenPort("COM4", 115200, SerialParity.None, 8, SerialStopBits.One, "")) {
    UtilityPrint("COM4 isn't available: unplugged, or open in the Arduino IDE's Serial Monitor?");
    }

    // Any gesture or hotkey: send a command line and read the board's reply.
    // (The sketch reads a line with Serial.readStringUntil('\n') and answers OK.)
    if (SerialWriteTextLine("COM4", "LED 255 0 0", 115200)) {
    reply = SerialGetTextLine("COM4", 1, 115200);
    if (reply != "OK") UtilityPrint(StringFormat("Board said: {0}", reply, ""));
    }
  • Ein Monitor. SerialMonitorCreate führt für jede Zeile, die das Gerät sendet, im Hintergrund ein Skript aus, bis SerialMonitorDelete. Die Zeile ist ContextGetSerialTextLine(). Siehe Tasten eines seriellen Geräts Medientasten zuordnen und:

    // Arduino side: a potentiometer on A0, one reading per line.
    // void setup() { Serial.begin(115200); }
    // void loop() { Serial.println(analogRead(A0)); delay(50); }
    // Empty text as the terminator means CR LF, which Serial.println sends.
    SerialMonitorCreate("knob", "COM4", 115200, SerialParity.None, 8, SerialStopBits.One, "",
    "line = ContextGetSerialTextLine(); if (StringIsNumber(line, true)) MultimediaSetVolume(AudioEndpoint.Playback, StringToNumber(line, true) / 1023.0);");
hinweis

Was Sie über Monitore wissen sollten.

  • Die Zeilen laufen nacheinander, in der Reihenfolge ihres Eintreffens: Das Skript für die nächste Zeile startet, wenn das Skript für die vorherige beendet ist. Bis zu 256 Zeilen warten; darüber hinaus werden die ältesten verworfen.
  • Das Beenden aller Aktionen beendet das Skript, das gerade für eine Zeile läuft, und verwirft die wartenden Zeilen. Der Monitor selbst läuft weiter. Der Hotkey „Alle Aktionen beenden“ geht weiter: Er löscht jeden Monitor und schließt dessen Anschluss.
  • Jedes Skript, auch das eigene Skript des Monitors, kann mit SerialWriteTextLine an einen überwachten Anschluss senden, sodass ein Monitor seinem Gerät antworten kann. SerialGetTextLine kann einen überwachten Anschluss nicht lesen: Jede Zeile geht an den Monitor.
  • Jeder Monitorname gehört zu einem Anschluss. SerialMonitorCreate mit dem Namen des Monitors dieses Anschlusses ersetzt diesen Monitor. Es beendet die Aktion mit einem Fehler, wenn der Name bereits einen anderen Anschluss überwacht, wenn der Anschluss mit SerialOpenPort geöffnet ist oder wenn ein anderer Monitor den Anschluss belegt. Ein Anschluss, der fehlt, getrennt ist oder in einem anderen Programm geöffnet ist, ergibt false.
  • Das Trennen des Geräts beendet den Monitor und schreibt eine Zeile in die Registerkarte System der Konsole. Nichts startet den Monitor neu, wenn das Gerät wieder angeschlossen wird. Führen Sie SerialMonitorCreate erneut aus (über einen Hotkey oder beim nächsten Start im Ereignis „Konfiguration geladen“).
warnung

Nur ein Programm kann einen COM-Anschluss geöffnet haben. Solange der serielle Monitor oder der serielle Plotter der Arduino IDE geöffnet ist, kann Input.Observer den Anschluss nicht öffnen, und solange Input.Observer ihn geöffnet hat, kann die IDE keinen Sketch hochladen. Schließen Sie den Anschluss (SerialClosePort oder SerialMonitorDelete) vor dem Hochladen.