Interfaz de línea de comandos simple
Componentes y suministros
| × | 1 |
Acerca de este proyecto
Línea de comando
Llega un momento en el que necesitas encontrar el valor de un sensor o quieres decirle a tu robot que haga algo como "muévete a la izquierda". Tal vez necesite preguntarle a su programa el valor de tiempo de ejecución de una variable, o necesita establecer el valor de un potenciómetro digital.
Lo que necesitas es una línea de comando. Sí, es fácil hacer que tu Arduino responda a comandos de texto.
Aquí hay uno en el que puede basarse. Es una interfaz de línea de comandos simple, rápida y muy eficiente en memoria (CLI) que puede cortar y pegar en unos minutos en su propio código y estar listo y funcionando. Los comandos constan de un nombre seguido de varios argumentos. Incluso admite retroceso cuando escribe sus comandos.
Descripción general rápida
Cada boceto tiene un loop ()
función. El tuyo podría ser tan simple como el que se muestra a continuación. Llama a dos rutinas en una pestaña separada llamada CommandLine.h
. Lo guiaré a través de estos dos archivos y estará listo y funcionando.
Bucle
Qué hace: Cada vez que loop ()
lo ejecuta verifica si tenemos un comando desde el puerto serie, llamando a getCommandLineFromSerialPort ()
. La variable CommandLine
se declara en CommandLine.h
pero estilísticamente, es posible que desee moverlo a la pestaña principal de Loop. Cuando un comando completo ha llegado al puerto serie y se ha copiado en el búfer de comandos:
char commandLine [COMMAND_BUFFER_LENGTH + 1];
Luego loop ()
llama a DoMyCommand ()
para ejecutar el comando adecuado.
Ahora echemos un vistazo a lo que hay en CommandLine.h
. Debo señalar que puse todo el código en CommandLine.h
, porque entonces todo lo que tiene que hacer es cortar y pegar este código en una nueva pestaña en su IDE de Arduino (asegúrese de darle a la pestaña un nombre que termine con " .h
"). Luego, incluya este archivo en su archivo principal, es decir,
#include "CommandLine.h"
Lo que hace es permitirle poner todo el código de la línea de comandos en una pestaña y, sin embargo, consultar sus rutinas en otras partes de su programa sin ningún código adicional.
Buscando en CommandLine.h
El archivo CommandLine.h
se incluye al final de esta publicación. Dentro de CommandLine.h
, cada línea que necesita modificar está marcada con el comentario, // Modificar aquí
. El archivo incluye dos comandos de muestra add
y sub
y muestra cómo se llaman desde DoMyCommand
.
Para muchos de ustedes, eso es todo lo que necesitarán. Simplemente revise CommandLine.h
. Para aquellos que deseen una vista más detallada, sigan leyendo.
Mirando más profundo
Dentro de CommandLine.h
primero incluimos
. String.h
es una biblioteca estándar de C . Si no ha encontrado bibliotecas de C antes, haga una búsqueda rápida en Internet de "El lenguaje de programación C". La Biblia en C fue escrita hace años por Brian Kernigan y Dennis Ritchie y se ha mantenido actualizada. La mayoría de las personas poseen una copia, pero puede encontrarla en línea de forma gratuita.
Solo usaremos strtok ()
rutina (cadena a token) de
. Esta rutina lee un token, es decir, una palabra delimitada por ciertos caracteres (el segundo parámetro de strtok
). Funciona así.
- Cuando lo llama por primera vez, le pasa una cadena
ptr
y devolverá el primer token
- En llamadas posteriores, (aquí viene la parte gloriosa del truco) páselo NULL en lugar de una cadena
ptr
y continuará donde lo dejó con la cadena inicial, obteniendo así un token (aproximadamente una palabra) a la vez.
También incluimos
del cual solo usamos atoi ()
para la conversión de ascii a entero. No se preocupe, el compilador solo incluirá esta rutina, no toda la biblioteca, pero es posible que desee verificar las otras rutinas en estas bibliotecas, ya que son útiles.
Lo siguiente es una pequeña macro opcional que escribí llamada print2:
#define print2 (x, y) (Serial.print (x), Serial.println (y)
Siempre quiero imprimir una etiqueta y una cadena. Lo usa así:
print2 ("myVar =", myVar);
Si myVar es 25, esto se imprimirá en la ventana de serie:
myVar =25
CommandLine.h
contiene getCommandLineFromSerialPort ()
que ensambla una línea de comando desde el puerto serie. Cada vez que se llama, lee desde el puerto serie y almacena la entrada en el búfer de entrada global, CommandLine []
. Cuando llega a un return
carácter que significa el final del comando devuelve true
.
El búfer completamente ensamblado ahora se pasa a DoMyCommand ()
que averigua qué función está solicitando el usuario y la llama. Con una gran cantidad de comandos, puede obtener una declaración if-the-else bastante difícil de manejar.
Si tiene una cantidad realmente enorme de comandos, hay muchas formas de acelerar las cosas, como adoptar lo que se llama función hash. Alternativamente, puede hacer que los comandos solo tengan un carácter y luego usar ese carácter como la etiqueta de una declaración de cambio de mayúsculas y minúsculas. Encuentro que ninguno de estos es necesario muy a menudo. Una palabra es mucho más fácil de recordar que un solo carácter y dado que se trata de un Arduino, ¿cuántos comandos puede tener realmente antes de quedarse sin espacio en el chip?
Agregar y Sub
Cada función de comando es responsable de analizar sus propios argumentos. Esta es una forma sencilla de hacerlo y bastante fácil de modificar. Una alternativa a esto es leer todos los argumentos inmediatamente en DoMyCommand
. Puede poner argumentos individuales en una matriz global de cadenas argv []
.
Para los propósitos de este ejemplo, he definido dos comandos: add
y sub
. Ambos usan argumentos numéricos pero he incluido readWord
(que podría llamarse readStringToken
) para devolver una palabra. También puede modificar este readStringToken
para permitir cadenas como " esta es una cadena
". Considérelo un ejercicio que se deja al lector.
La forma más rápida de correr
Si tiene un archivo de bucle principal como se muestra arriba, cree una nueva pestaña usando el triángulo que apunta hacia abajo a la derecha de su ventana IDE de Arduino, y copie CommandLine.h
(abajo) en él, debería poder escribir add
y sub
comandos.
¡Ahora le toca a usted!
Código
- Intérprete de línea de comandos simple para Arduino
Intérprete de línea de comandos simple para Arduino C / C ++
Vea los comentarios en este artículo o en el código para agregar una línea de comando simple a su boceto de Arduino.Puede agregar comandos como este:
sumar 5, 10
restar 10, 5
O cualquier otra cosa que necesite
/ ************************************** *********************************** Cómo utilizar CommandLine:Cree un boceto. Busque a continuación una configuración de muestra y un código de bucle principal y cópielo y péguelo en el nuevo boceto. Crea una nueva pestaña. (Use el menú desplegable (pequeño triángulo) en el extremo derecho del Editor Arduino. Nombra la pestaña CommandLine.h Pega este archivo en él. Prueba:Descarga el boceto que acabas de crear en tu Arduino como de costumbre y abre la Ventana Serial. Escriba estos comandos seguidos de return:sumar 5, 10 restar 10, 5 ¡Mire los comandos de sumar y restar incluidos y luego escriba el suyo! ********************* *********************************************** ****** Esto es lo que está pasando bajo las sábanas ********************************** *************************************** Intérprete de línea de comandos simple y claro Este archivo permitirá debe escribir comandos en la ventana serial como, agregue 23,599 blink 5 playSong Yesterday a su boceto que se ejecuta en el Arduino y ejecútelos. intérprete, probablemente también tenga poco espacio y el objeto String tiende a ser ineficiente en cuanto al espacio. 1) Los comandos de protocolo simple son palabras y números, ya sea en espacios o comas La primera palabra es el comando, cada palabra adicional es un argumento "\ n" termina cada comando 2) Usando la rutina de la biblioteca C strtok:Un comando es una palabra separada por espacios o comas. Una palabra separada por ciertos caracteres (como espacio o coma) se llama símbolo. Para obtener tokens uno por uno, utilizo el strtok de enrutamiento de C lib (parte de C stdlib.h, vea a continuación cómo incluirlo). Es parte de la biblioteca de lenguaje Cque puede buscar en línea. Básicamente, usted:1) le pasa una cadena (y los delimitadores que usa, es decir, espacio y comando) y devolverá el primer token de la cadena 2) en llamadas posteriores, páselo NULL (en lugar de la cadena ptr) y lo hará continúe donde lo dejó con la cadena inicial. He escrito un par de rutinas auxiliares básicas:readNumber:usa strtok y atoi (atoi:ascii to int, nuevamente parte de C stdlib.h) para devolver un entero. Tenga en cuenta que atoi devuelve un int y si está utilizando entradas de 1 byte como uint8_t, tendrá que obtener lowByte (). readWord:devuelve un ptr a una palabra de texto 4) DoMyCommand:Una lista de if-then-elses para cada comando. Podría convertir esto en una declaración de caso si todos los comandos fueran un solo carácter. Usar una palabra es más legible. Para los propósitos de este ejemplo tenemos:Add Subtract nullCommand * // ****************** ejemplo de código de bucle principal ************* *********************** #include "CommandLine.h" void setup () {Serial.begin (115200); } bucle vacío () {bool recibido =getCommandLineFromSerialPort (CommandLine); // CommandLine global se define en CommandLine.h if (recibido) DoMyCommand (CommandLine); } ********************************************** ********************************* /// Nombra esta pestaña:CommandLine.h # include #include // esta siguiente macro es buena para depurar, p. ej. print2 ("myVar =", myVar); # 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 // longitud del búfer serial para los comandos entranteschar CommandLine [COMMAND_BUFFER_LENGTH + 1]; // Leer comandos en este búfer desde Serial. +1 de longitud para una terminación charconst char * delimiters =", \ n"; // los comandos se pueden separar por retorno, espacio o coma / *********************************** *********************************************** ********************** Aquí los nombres de sus comandos * / const char * addCommandToken ="agregar"; // Modificar hereconst char * subtractCommandToken ="sub"; // Modificar aquí / ******************************************* *********************************************** ************** getCommandLineFromSerialPort () Devuelve la cadena del siguiente comando. Los comandos están delimitados por el retorno "Manejar el carácter de retroceso Hacer todos los caracteres en minúsculas ********************************** *********************************************** ********************** / boolgetCommandLineFromSerialPort (char * commandLine) {static uint8_t charsRead =0; // nota:COMAND_BUFFER_LENGTH debe tener menos de 255 caracteres // leer de forma asincrónica hasta la entrada completa del comando while (Serial.available ()) {char c =Serial.read (); switch (c) {case CR:// probablemente tenga el comando completo en el búfer ahora, los comandos terminan con CR y / o LS case LF:commandLine [charsRead] =NULLCHAR; // nulo termina nuestro comando char array if (charsRead> 0) {charsRead =0; // charsRead es estático, así que hay que restablecer Serial.println (commandLine); return true; } break; case BS:// manejar el retroceso en la entrada:poner un espacio en el último carácter if (charsRead> 0) {// y ajustar commandLine y charsRead commandLine [- charsRead] =NULLCHAR; Serial < La suma es =", resultado); } else {if (strcmp (ptrToCommandName, subtractCommandToken) ==0) {// Modificar aquí resultado =subtractCommand (); // Cadena K &R.h pág. 251 print2 ("> La diferencia es =", resultado); } else {nullCommand (ptrToCommandName); }}}
Proceso de manufactura
- Comentarios de C#
- interfaz C#
- Interfaz Java
- Interfaz para el sensor de entrada inalámbrico
- Un sensor de proximidad analógico simple con interfaz digital (para Raspberry Pi) [última actualización:7 de febrero de 2014]
- ANDY:Un robot “humanoide” multiusos
- Robot Pi simple
- C - Argumentos de línea de comando
- C# - Interfaces
- ¿Qué es la línea de corte longitudinal de bobinas de acero?
- Fabricantes de líneas de corte a medida de un vistazo