Skip to content

Instantly share code, notes, and snippets.

@edgar-bonet
Last active February 4, 2024 12:26
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save edgar-bonet/607b387260388be77e96 to your computer and use it in GitHub Desktop.
Simple Arduino command line interpreter
/*
* 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... */
}
@RowanP4069
Copy link

Thanks for this pattern Edgar, I'm finding it very usefu for a project I'm working on. Regards, Rowan Patterson

@artelse
Copy link

artelse commented Nov 2, 2023

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