Interface en ligne de commande Arduino UNO : Rapide et fiable
Composants et fournitures
| Arduino UNO | ×1 |
À propos du projet
Interface en ligne de commande
Il arrive un moment où vous devez lire la valeur d'un capteur ou ordonner à votre robot de faire quelque chose comme « avancer à gauche ». Peut-être avez-vous besoin de demander à votre programme la valeur d'exécution d'une variable, ou de définir la valeur d'un potentiomètre numérique.
Ce dont vous avez besoin, c'est d'une ligne de commande. Oui, il est facile de faire répondre votre Arduino à des commandes textuelles.
Voici une interface en ligne de commande (CLI) simple, rapide et très efficace en mémoire que vous pouvez copier-coller en quelques minutes dans votre propre code. Les commandes consistent en un nom suivi de plusieurs arguments. Elle prend même en charge la touche Retour arrière lors de la saisie.
Vue d'ensemble rapide
Chaque sketch possède une fonction loop(). La vôtre pourrait être aussi simple que celle ci-dessous. Elle appelle deux routines dans un onglet séparé nommé CommandLine.h.
Boucle principale (Loop)
Fonctionnement : À chaque exécution de loop(), elle vérifie si une commande est arrivée sur le port série via getCommandLineFromSerialPort(). La variable CommandLine est déclarée dans CommandLine.h. Lorsqu'une commande complète a été reçue et copiée dans le tampon de commande :
char commandLine[COMMAND_BUFFER_LENGTH + 1];
Alors loop() appelle DoMyCommand() pour exécuter la commande appropriée.
Examen de CommandLine.h
Le fichier CommandLine.h est inclus à la fin de cet article. Chaque ligne à modifier est marquée du commentaire //Modifier ici. Le fichier inclut deux commandes d'exemple add et sub et montre comment elles sont appelées depuis DoMyCommand.
Analyse approfondie
Dans CommandLine.h, on inclut d'abord <string.h>, une bibliothèque standard C. On utilise uniquement la routine strtok() (string to token) qui lit un mot délimité par certains caractères.
On inclut aussi <stdlib.h> pour atoi() (conversion ASCII vers entier).
Une macro optionnelle print2 permet d'afficher facilement un libellé et une valeur :
#define print2(x,y) (Serial.print(x), Serial.println(y))
// Utilisation : print2("myVar = ", myVar);
// Affiche : myVar = 25
getCommandLineFromSerialPort() assemble une ligne de commande depuis le port série. À chaque appel, elle lit le port série et stocke l'entrée dans le tampon global CommandLine[]. Quand elle atteint un caractère de retour (return), elle renvoie true.
Le tampon assemblé est passé à DoMyCommand() qui détermine quelle fonction l'utilisateur demande et l'appelle.
Commandes Add et Sub
Chaque fonction de commande analyse ses propres arguments. Pour cet exemple, deux commandes sont définies : add et sub. Toutes deux utilisent des arguments numériques, mais readWord (qui pourrait s'appeler readStringToken) permet de retourner un mot.
La méthode la plus rapide pour démarrer
Si vous avez un fichier de boucle principale comme indiqué ci-dessus, créez un nouvel onglet dans l'IDE Arduino (via la flèche vers le bas à droite), copiez le fichier CommandLine.h ci-dessous, et vous pourrez taper les commandes add et sub. C'est à vous de jouer !
Code complet
Interpréteur de ligne de commande simple pour Arduino
/*****************************************************************************
Comment utiliser CommandLine :
1. Créez un sketch. Copiez l'exemple de setup et loop ci-dessous.
2. Créez un nouvel onglet (menu déroulant à droite de l'éditeur Arduino).
3. Nommez l'onglet CommandLine.h et collez ce fichier.
4. Incluez-le dans votre fichier principal : #include "CommandLine.h"
5. Testez : Téléversez le sketch, ouvrez le moniteur série.
Tapez : add 5, 10 puis subtract 10, 5
*****************************************************************************/
// Onglet : CommandLine.h
#include <string.h>
#include <stdlib.h>
#define print2(x,y) (Serial.print(x), Serial.println(y))
#define CR '\r'
#define LF '\n'
#define BS '\b'
#define NULLCHAR '\0'
#define SPACE ' '
#define COMMAND_BUFFER_LENGTH 25
char CommandLine[COMMAND_BUFFER_LENGTH + 1];
const char *delimiters = ",\n";
const char *addCommandToken = "add";
const char *subtractCommandToken = "sub";
bool getCommandLineFromSerialPort(char *commandLine) {
static uint8_t charsRead = 0;
while (Serial.available()) {
char c = Serial.read();
switch (c) {
case CR:
case LF:
commandLine[charsRead] = NULLCHAR;
if (charsRead > 0) {
charsRead = 0;
Serial.println(commandLine);
return true;
}
break;
case BS:
if (charsRead > 0) {
commandLine[--charsRead] = NULLCHAR;
Serial.write(BS); Serial.write(SPACE); Serial.write(BS);
}
break;
default:
if (charsRead < COMMAND_BUFFER_LENGTH) {
commandLine[charsRead++] = c;
}
commandLine[charsRead] = NULLCHAR;
break;
}
}
return false;
}
int readNumber() {
char *numTextPtr = strtok(NULL, delimiters);
return atoi(numTextPtr);
}
char *readWord() {
char *word = strtok(NULL, delimiters);
return word;
}
void nullCommand(char *ptrToCommandName) {
print2("Command not found: ", ptrToCommandName);
}
int addCommand() {
int firstOperand = readNumber();
int secondOperand = readNumber();
return firstOperand + secondOperand;
}
int subtractCommand() {
int firstOperand = readNumber();
int secondOperand = readNumber();
return firstOperand - secondOperand;
}
bool DoMyCommand(char *commandLine) {
int result;
char *ptrToCommandName = strtok(commandLine, delimiters);
if (strcmp(ptrToCommandName, addCommandToken) == 0) {
result = addCommand();
print2("> The sum is = ", result);
} else if (strcmp(ptrToCommandName, subtractCommandToken) == 0) {
result = subtractCommand();
print2("> The difference is = ", result);
} else {
nullCommand(ptrToCommandName);
}
return true;
}
Processus de fabrication
- Maîtriser les commentaires C# : Types, bonnes pratiques et documentation XML
- Maîtriser les interfaces C# : Définition, implémentation et cas d'utilisation pratiques
- Maîtriser les interfaces Java : concepts, implémentation et bonnes pratiques
- Capteur sans fil fiable pour longues allées – Intégration facile Raspberry Pi
- Capteur de proximité infrarouge low-cost pour Raspberry Pi utilisant uniquement les broches numériques
- ANDY – Le robot humanoïde polyvalent
- Simple Pi Robot – Construire un rover autonome 2 roues motrices avec Raspberry Pi
- Maîtriser les arguments de ligne de commande en C : Guide pratique
- Maîtriser les interfaces C# : contrats de conception pour une POO robuste