A lightweight, high-performance, and rock-solid Command Line Interface (CLI) library for Arduino and other microcontrollers. It allows you to easily teach your MCU to understand text commands with arguments (like test 13 1), mimicking a classic Unix shell (argc/argv concept).
- Zero Dynamic Allocation (0 bytes on Heap): The entire parsing process happens inside the input buffer ("in-place" processing). This guarantees 100% protection against memory fragmentation and unexpected MCU crashes.
- Smart Tokenization (Quotes Support): Supports passing arguments with spaces inside single (
'), double ("), or backtick (`) quotes (e.g.,print_lcd "Hello World"is parsed as a single argument). - Built-in
listEngine: The core automatically intercepts thelistcommand and prints all available commands registered in your system. No manual help-function hardcoding needed! - Dual Execution Modes:
interpret()— Interactive mode (Human-to-Machine) with formatting, newlines, and>prompts.execute()— Script mode (Machine-to-Machine) for quiet execution via external Python scripts or GUI apps.
- Non-blocking Architecture: Designed to work seamlessly with
serialEvent()or custom polling loops without freezing your mainloop().
Since the library uses pure C/C++ abstractions and standard library string functions, it features zero dependencies and works on any architecture:
- 8-bit AVR: ATmega328P (Arduino Uno, Nano), ATmega2560 (Mega), LGT8F328P, etc.
- 32-bit: STM32, ESP8266, ESP32, Raspberry Pi Pico.
- Download
CommandCom.handCommandCom.cppand put them into your sketch folder. - Create your command functions and link them via
EXEC_TABLE.
Here is a minimal working example controlling the built-in LED:
#include "CommandCom.h"
// 1. Declare firmware version
#define FW_VERSION "IO Controller rev.1.0.0"
// 2. Declare command handler prototypes
static int show_version(int argc, char *argv[]);
static int test(int argc, char *argv[]);
// 3. Create the Execution Table (bind text names to functions)
// MUST be terminated with an empty string row!
const EXEC_TABLE exe_files[] =
{
{"version", show_version},
{"test", test},
{ "", NULL }
};
// 4. Instantiate the console manager
CommandCom console(exe_files);
void setup()
{
Serial.begin(115200);
console.prompt(FW_VERSION); // Print greeting and the ">" prompt
}
void loop()
{
// Your main loop remains absolutely free and non-blocked!
}
// 5. Asynchronously collect incoming data from Serial
void serialEvent()
{
static char buf[100];
static int buf_ndx = 0;
char ch;
while (Serial.available() > 0)
{
ch = Serial.read();
if (buf_ndx < 99)
buf[buf_ndx++] = ch;
// On Enter key press (CR or LF)
if(ch == 0x0D || ch == 0x0A)
{
buf[buf_ndx] = 0; // Null-terminate the string
buf_ndx = 0; // Reset index for the next command
console.interpret(buf); // Pass the buffer to the parser
}
}
}
// --- Command Handlers Implementation ---
static int show_version(int argc, char *argv[])
{
Serial.println(FW_VERSION);
return 0;
}
static int test(int argc, char *argv[])
{
// Validate argument count (command itself + pin + state = 3 tokens)
if(argc != 3)
{
Serial.println("Usage: test pin state");
Serial.println("Example: test 13 1 (LED ON)");
Serial.println(" test 13 0 (LED OFF)");
return 0;
}
int pin = atoi(argv[1]);
int state = atoi(argv[2]);
pinMode(pin, OUTPUT);
digitalWrite(pin, state);
return 0;
}Open your Serial Monitor (set to 115200 baud) and try typing these commands:
IO Controller rev.1.0.0
> list
Avalilable commands:
list version test
> version
IO Controller rev.1.0.0
> test 13 1
(The built-in LED on pin 13 turns ON!)
> test 99
Usage: test pin state
Example: test 13 1 (LED ON)
test 13 0 (LED OFF)
> unknown_command
Command unknown_command not found
This project is open-source software. You are free to use, modify, and distribute it in both personal and commercial projects.
