Périphériques série et Arduino
Les fonctions intégrées Serial* communiquent avec tout ce qui apparaît comme un port COM : un
Arduino, un ESP32 ou un Raspberry Pi Pico en USB, un adaptateur USB-série, un récepteur GPS, un
lecteur de codes-barres en mode série, une imprimante de tickets ou d'étiquettes, une imprimante 3D
ou une commande numérique qui accepte du G-code, un instrument de laboratoire, ou un boîtier de
boutons, un pavé de macros, un bouton rotatif ou un contrôleur de LED fait maison. Le périphérique
envoie et reçoit des lignes de texte ; vos scripts transforment ces lignes en n'importe quelle autre
chose que sait faire Input.Observer.
Quelques idées :
- Un boîtier de boutons ou un pavé de macros. Un Arduino lit ses boutons et affiche
B1,B2, ... Un moniteur série transforme chaque ligne en raccourci, en touche multimédia ou en commande de fenêtre. - Un bouton rotatif de volume ou de défilement. Un potentiomètre ou un encodeur rotatif envoie sa position ; le moniteur règle le volume ou fait défiler.
- Des voyants d'état. Un geste ou un raccourci clavier envoie
LED 255 0 0à une carte qui pilote un ruban de LED, pour qu'une lumière indique que l'enregistrement est en cours ou que la compilation a échoué. - Des capteurs. Un minuteur demande à une carte une température ou un niveau de luminosité et l'affiche, l'écrit dans un fichier journal ou baisse la luminosité de l'écran.
- Des lecteurs et scanners. Chaque code-barres ou étiquette RFID envoyé par le lecteur devient du texte saisi, une recherche ou une consultation dans un fichier.
- Des machines. Envoyez des lignes de G-code à une imprimante ou à un traceur, un
SerialWriteTextLinepar commande.
Trouver le port
Windows donne à chaque périphérique un nom comme COM3. Le Gestionnaire de périphériques le liste
sous Ports (COM et LPT) ; l'IDE Arduino l'affiche dans son menu de cartes. Un script peut aussi
les lister :
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));
}
La liste est triée par numéro : COM3 vient donc avant COM10. Le numéro peut changer lorsque le
périphérique est branché sur un autre port USB.
Vitesse, format de trame et fins de ligne
- La vitesse (
baudRate) doit correspondre à celle du périphérique : le nombre indiqué dans leSerial.begin(...)d'un croquis Arduino, généralement9600ou115200. - Le format de trame est presque toujours 8 bits de données, sans parité, un bit d'arrêt :
8,SerialParity.None,SerialStopBits.One. Écrivez les constantes : le nombre1seul comme argument de bits d'arrêt signifie un bit et demi d'arrêt. - Fins de ligne. Une ligne reçue se termine au
terminatorque vous indiquez, qui est retiré de la ligne. Un texte vide signifie CR LF, ce qu'envoie leSerial.printlnd'Arduino. Pour un périphérique qui termine ses lignes par LF seul, utilisez"\n"; pour CR seul, utilisez"\r".SerialWriteTextLinetermine ce qu'il envoie par le même terminateur, ou par CR LF lorsque l'appel ouvre lui-même le port. Avec CR LF, un croquis Arduino qui lit avecSerial.readStringUntil('\n')reçoit la ligne avec un CR final, quetrim()retire ; avec"\n", il n'y a pas de CR à retirer. - Signaux. L'ouverture d'un port active ses signaux DTR et RTS, comme le fait l'IDE Arduino. Cela redémarre la plupart des cartes Arduino Uno et Nano, ainsi que les autres cartes dotées du même circuit de réinitialisation.
Trois façons de communiquer avec un périphérique
-
Une question, une réponse.
SerialWriteTextLineetSerialGetTextLinesur un port qui n'est pas ouvert l'ouvrent aubaudRatede l'appel, 8-N-1, le temps de cet appel. L'argumentbaudRateest ignoré lorsque le port est déjà ouvert. Convient à un périphérique qui ne redémarre pas à l'ouverture de son port. Voir Poser une question à un périphérique série. -
Un port maintenu ouvert.
SerialOpenPortouvre le port avec vos paramètres jusqu'àSerialClosePort, en recueillant chaque ligne envoyée par le périphérique pour queSerialGetTextLinela lise. La plupart des cartes Arduino Uno et Nano redémarrent chaque fois que leur port s'ouvre : ouvrez donc le port une seule fois, dans l'événement global Configuration chargée, et laissez les gestes et les raccourcis clavier y écrire.SerialOpenPortrenvoiefalsepour un port absent, débranché ou ouvert dans un autre programme ; pour un port qu'Input.Observer a déjà ouvert, ou qu'un moniteur détient, il arrête l'action avec une erreur.// 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, ""));} -
Un moniteur.
SerialMonitorCreateexécute un script pour chaque ligne envoyée par le périphérique, en arrière-plan, jusqu'àSerialMonitorDelete. La ligne estContextGetSerialTextLine(). Voir Associer les boutons d'un périphérique série à des touches multimédias et :// 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);");
Ce qu'il faut savoir sur les moniteurs.
- Les lignes sont traitées une à la fois, dans leur ordre d'arrivée : le script de la ligne suivante démarre lorsque celui de la ligne précédente est terminé. Jusqu'à 256 lignes attendent ; au-delà, les plus anciennes sont abandonnées.
- L'arrêt de toutes les actions arrête le script en cours pour une ligne et abandonne les lignes en attente. Le moniteur lui-même continue de fonctionner. Le Raccourci clavier Arrêter toutes les actions va plus loin : il supprime chaque moniteur et ferme son port.
- N'importe quel script, y compris celui du moniteur, peut envoyer des données à un port surveillé
avec
SerialWriteTextLine: un moniteur peut donc répondre à son périphérique.SerialGetTextLinene peut pas lire un port surveillé : chaque ligne va au moniteur. - Chaque nom de moniteur appartient à un seul port.
SerialMonitorCreateavec le nom du moniteur de ce port remplace ce moniteur. Il arrête l'action avec une erreur lorsque le nom surveille déjà un autre port, lorsque le port est ouvert avecSerialOpenPort, ou lorsqu'un autre moniteur détient le port. Un port absent, débranché ou ouvert dans un autre programme donnefalse. - Débrancher le périphérique met fin au moniteur et inscrit une ligne dans l'onglet Système de la
console. Rien ne relance le moniteur quand le périphérique revient. Exécutez de nouveau le
SerialMonitorCreate(depuis un raccourci clavier, ou depuis l'événement Configuration chargée au prochain démarrage).
Un seul programme à la fois peut ouvrir un port COM. Tant que le Moniteur série ou le Traceur
série de l'IDE Arduino est ouvert, Input.Observer ne peut pas ouvrir le port, et tant
qu'Input.Observer le maintient ouvert, l'IDE ne peut pas téléverser de croquis. Fermez le port
(SerialClosePort ou SerialMonitorDelete) avant le téléversement.