Last active
January 8, 2025 22:09
-
-
Save edgar-bonet/607b387260388be77e96 to your computer and use it in GitHub Desktop.
Simple Arduino command line interpreter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* interpreter.ino: Simple Arduino command line interpreter. | |
* | |
* This is intended solely as a template for building richer, | |
* application-specific interpreters. Add your specific commands to the | |
* exec() function, and whatever you need to setup() and loop(). | |
* | |
* Usage: | |
* Talk to it through the serial port at 9600/8N1. Commands should be | |
* terminated by CR (\r), answers are terminated by CRLF (\r\n). This | |
* should play well with typical terminal emulators. For the list of | |
* supported commands, see the answer to the "help" command. | |
* | |
* Copyright (c) 2016 Edgar Bonet Orozco. | |
* Released under the terms of the MIT license: | |
* https://opensource.org/licenses/MIT | |
*/ | |
#include <avr/pgmspace.h> | |
#define BUF_LENGTH 128 /* Buffer for the incoming command. */ | |
static bool do_echo = true; | |
/* Execute a complete command. */ | |
static void exec(char *cmdline) | |
{ | |
char *command = strsep(&cmdline, " "); | |
if (strcmp_P(command, PSTR("help")) == 0) { | |
Serial.println(F( | |
"mode <pin> <mode>: pinMode()\r\n" | |
"read <pin>: digitalRead()\r\n" | |
"aread <pin>: analogRead()\r\n" | |
"write <pin> <value>: digitalWrite()\r\n" | |
"awrite <pin> <value>: analogWrite()\r\n" | |
"echo <value>: set echo off (0) or on (1)")); | |
} else if (strcmp_P(command, PSTR("mode")) == 0) { | |
int pin = atoi(strsep(&cmdline, " ")); | |
int mode = atoi(cmdline); | |
pinMode(pin, mode); | |
} else if (strcmp_P(command, PSTR("read")) == 0) { | |
int pin = atoi(cmdline); | |
Serial.println(digitalRead(pin)); | |
} else if (strcmp_P(command, PSTR("aread")) == 0) { | |
int pin = atoi(cmdline); | |
Serial.println(analogRead(pin)); | |
} else if (strcmp_P(command, PSTR("write")) == 0) { | |
int pin = atoi(strsep(&cmdline, " ")); | |
int value = atoi(cmdline); | |
digitalWrite(pin, value); | |
} else if (strcmp_P(command, PSTR("awrite")) == 0) { | |
int pin = atoi(strsep(&cmdline, " ")); | |
int value = atoi(cmdline); | |
analogWrite(pin, value); | |
} else if (strcmp_P(command, PSTR("echo")) == 0) { | |
do_echo = atoi(cmdline); | |
} else { | |
Serial.print(F("Error: Unknown command: ")); | |
Serial.println(command); | |
} | |
} | |
void setup() | |
{ | |
Serial.begin(9600); | |
} | |
void loop() { | |
/* Process incoming commands. */ | |
while (Serial.available()) { | |
static char buffer[BUF_LENGTH]; | |
static int length = 0; | |
int data = Serial.read(); | |
if (data == '\b' || data == '\177') { // BS and DEL | |
if (length) { | |
length--; | |
if (do_echo) Serial.write("\b \b"); | |
} | |
} | |
else if (data == '\r') { | |
if (do_echo) Serial.write("\r\n"); // output CRLF | |
buffer[length] = '\0'; | |
if (length) exec(buffer); | |
length = 0; | |
} | |
else if (length < BUF_LENGTH - 1) { | |
buffer[length++] = data; | |
if (do_echo) Serial.write(data); | |
} | |
} | |
/* Whatever else needs to be done... */ | |
} |
Tried a few CLI libraries, but this one is just simple and straightforward; thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this pattern Edgar, I'm finding it very usefu for a project I'm working on. Regards, Rowan Patterson