Other Software Development
A Command line library
Topic: A Command line library
(Read 2567 times)
A Command line library
Nov 28, 2019, 01:45 pm
I've developed a comprehensive command line library for Arduino, mostly aimed at devices with good memory resources (like the Zero, or other Arm Cortex devices and the ESP32). Its not really aimed at the total beginner but is designed to make it easier to build sophisticated text based command interfaces. I've finally got around to releasing the first version, available on Github, and hopefully it will appear in the library manager soon:
To date most of the development and testing has been done with either Adafruits Feather and ItsyBitsy Mo and M4 boards, some custom boards using the ATSamD21 and D51 microcontrollers, and an ESP32.
Commander allows you to define a list of text commands, a function to handle each command, and some help text that can be displayed when the 'help' command is sent. All the work of reading the incoming stream data, identifying the appropriate function and calling the handler is done by the commander object. It will run on most Arduino boards but is more suited to devices with large memory.
Commander is attached to Stream objects so it can be used with Serial ports, files on a SD cards, or Bluetooth Serial and other Stream based objects on wireless capable Arduinos such as the ESP32.
Commander can have up to three Stream objects connected at once, an input stream, output stream and auxiluary stream. As well as reading commands and passing them to the handler functions Commander can route or copy data to another port, echo data back to you and redirect or copy responses to a different port. When using SDFat Commanders input Stream can be attached to one file to read commands, and the output Stream attached to a second file for logging any responses generated by the command handler, with the aux stream copying all those responses to a serial port.
Commander is designed so that the list of commands and associated handlers and help text is seperate from the Commander object, this allows command lists to be shared between several instances of a Commander object, for example where the same command set needs to be available via USB and Bluetooth Serial. It also allows different command lists to be dynamically loaded so multiple command lists, and multiple Commander objects can be combined to produce hierarchical command structures.
Commander can also handle nested commands and incorporates a set of functions for extracting any payload that comes after a command and for parsing variables in the payload. It can also augment responses sent to its output and auxiluary Streams to add prefix and postfix text, for example enclosing each line with opening and closing html tags, or prefixing specified lines with a command.
Built in commands like Help will generate a help page listing all the commands and any help text for them. Additional built in commands can be used to toggle error reporting and port echoing and all built in commands can be overidden by the user with their own handler.
Commander can use an optional command prompt with user defined text to emulate the feel of a command line, this prompt can be changed dynamically to indicate the current context, for example it can show the working directory of a file system, or the title of a sub command list. Commander also has a user defined 'reaload' character that will reload the last command. By default this is / so, for example, if you sent a command called 'print sensors' and then want to send the same command again, you just need to type / to repeat it. A user defined 'comment' character (# by default) can be put in front of a line to tell Commander to ignore it.
The following list of examples demonstrate various ways to use Commander:
Demonstrated setting and getting integer and float values with a command list.
Demonstrates an in built method for packing some commands in a single command handler for faster coding whilst retaining the help system for listing commands.
Uses a BluetoothSerial object so commands can be sent vial bluetooth.
Open an SD card file that contains a set of commands and read the contents into Commander. Responses to commands are fed back to a Serial port.
Open an SD card file that contains a set of commands and read the contents into Commander. Responses to commands are written to another file and copied to a Serial port.
Used SDFat and a set of commands for listing files, navigating and creating directories, renaming and deleting files and directories and printing out files.
Shows how to use the pre and posfix formating, and nested commands so formatting for another command can be invoked.
Shows how three command lists can be used with one Commander object to create a multi level command structure. This example has sub commands for setting variable, and more for reading back variables. These commands can be invoked from the top level (e.g 'get int') or the sub level can be invoked ('get') and then commands from that level invoked directly ('int') before an 'exit' command returns you to the top level. The help command can be used for every level.
This example behaves in an almost identical way to SimpleMultiLayer but uses three Commander objects. Navigating between different levels is handled by passing control from one Commander object to another rather than loading different command lists into the same object.
Re: A Command line library
Dec 05, 2019, 06:20 pm
For those interested ... I have updated the library to include a feature called 'prefabs' - prefabricated command structures and handlers. The first prefab is for file navigation and manipulation and allows you to navigate SD card file structures, read, write and delete files and directories.
Writing to files is best done with something other than the Arduino serial port because to terminate a file write you need to send the ASCII value 4. On some terminal apps this can be done with CONTROL+D, but not with Arduino.
Also added since my first post is a locking system so you can impliment passwords. Locks can be hard or soft. Soft locks still permit internal commands such as help. Hard locks block all commands except the unlock command.