1 # Command Line Interface
3 These classes implement a non-blocking command line interface on the Serial
4 port. In ther words, you can implement a primitive "shell" for the Arduino.
6 These classes were initially an experiment to validate the `AceRoutine` macros
7 and classes but they seem to be useful as an independent library. They may be
8 moved to a separate project/repository later.
14 The basic steps for adding a command line interface to an Arduino sketch
15 using the `cli/` library is the following:
17 1. Create a `CommandHandler` class for each command, defining its
18 `name` and `helpString`.
19 1. Create a static array of `CommandHandler*` pointers with all the commands
20 that you would like to suport.
21 1. Create a `CommandManager` object, giving it the `CommandHandler*` array,
22 and a number of size parameters for various internal buffers (maximum line
23 buffer length, and maximum number of `argv` parameters for a command).
24 1. Insert the `CommandManager` into the `CoroutineScheduler` by calling
25 `commandManager.setupCoroutine()` just before `CoroutineScheduler::setup()`.
26 1. Run the `CoroutineScheduler::loop` in the global `loop()` method to
27 run the `CommandManager` as a coroutine.
29 ### Command Handler and Arguments
31 The `CommandHandler` class defines the command's `name`, `helpString` and
32 the `run()` method that implements the command. It takes the following
35 * `printer` is the output device, which will normally be the global `Serial`
37 * `argc` is the number of `argv` arguments
38 * `argv` is the array of `cont char*` pointers, each pointing to the words
39 of the command line delimited by whitespaces. These are identical to
40 the `argc` and `argv` parameters passed to the C-language `main(argc, argv)`
41 function. For example, `argv[0]` is the name of the command, and `argv[1]`
42 is the first argument after the command (if it exists).
46 The `CommandManager` is a templatized convenience class that creates all the
47 helper objects and buffers needed to read and parse the command line input.
50 * a `StreamLineReader` coroutine that reads the input lines from `Serial`
51 * a `CommandDispatcher` coroutine that parses the input lines
52 * a `Channel<InputLine>` from `StreamLineReader` to `CommandDispatcher`
53 * a line buffer for the input lines
54 * a array of `(const char*)` to hold the command line arguments of the command
56 You don't have to use the `CommandManager`, but it greatly simplies the creation
57 and usage of the `CommandDispatcher`.
59 ### Setup Process from Sketch
61 An Arduino `.ino` file that uses the CLI classes to implement a commmand line
62 shell will look something like this:
65 #include <AceRoutine.h>
66 #include <ace_routine/cli/CommandManager.h>
68 using namespace ace_routine;
69 using namespace ace_routine::cli;
71 class CommandA: public CommandHandler {
74 class CommandB: public CommandHandler {
81 static const CommandHandler* const COMMANDS[] = {
85 static uint8_t const NUM_COMMANDS = sizeof(COMMANDS) / sizeof(CommandHandler*);
87 uint8_t const BUF_SIZE = 64; // maximum size of an input line
88 uint8_t const ARGV_SIZE = 10; // maximum number of tokens in command
89 char const PROMPT[] = "$ ";
91 CommandManager<BUF_SIZE, ARGV_SIZE> commandManager(
92 COMMANDS, NUM_COMMANDS, Serial, PROMPT);
96 commandManager.setupCoroutine("commandManager");
97 CoroutineScheduler::setup();
101 CoroutineScheduler::loop();
107 See [examples/CommandLineShell/](../../../examples/CommandLineShell/)
108 for an demo program that implements 5 commands:
114 * `delay (on | off) millis`