The Arduino Command Line Interface, aka CmdArduino, is a simple shell that can be run on an Arduino. It's nothing fancy and its main purpose is to allow users to easily call their functions on a running Arduino via a simple serial terminal. It also allows users to pass in arguments from the command line into the functions they wrote so they can easily toggle pins, set blinking speed, set pwm duty cycles, or whatever else might need command line user input. Using it is fairly simple and just requires unzipping the files into the "Arduino/libraries" sub-directory in the Arduino program folder. The following is a tutorial that goes into more detail about how to implement CmdArduino in a sketch and easily add user functions to the command table.
Before we start, I need to mention that you'll need to use a serial terminal program to access the Arduino. The Serial Monitor built into the Arduino IDE does not allow carriage returns, ie: the Enter key, to be passed through the serial interface. For Windows, I'd recommend using a free program like Teraterm Pro or RealTerm . For Linux, I'd recommend picocom . And for Mac, you can simply use the "screen" command built into Mac OSX. You don't really need all that fancy scripting either ;)
Now, let's get started...
- Unzip files into Arduino /libraries sub-folder:
- Next, start up the Arduino application and check out the examples. They can be found in: “Files/Examples/Cmd/”
You’ll find that there are multiple examples. This tutorial will be skipping between different examples but I’d personally recommend starting from the beginning. Let’s start off with Example 1 (cmd_line_ex1_hello).
Example 1 is your standard “hello world” example, but applied to the command line interface. The goal of this example is just to print “hello world” when you type “hello” at the command line. Let’s dissect the code. Here's a shot of what it does:
It's a very simple sketch, but it demonstrates how a function can be called from a command line shell running on the Arduino. Now let's take a look at some of the important points of implementing CmdArduino in your sketch. Here's the complete code listing, minus comments, from Example 1:
void hello(int arg_cnt, char **args)
Let's dissect this code:
1) The first thing you need to do is include the Cmd library into the sketch. This tells the sketch that the functions being called can be found in the files inside the Cmd folder. You would add this at the top of the sketch:
2) The next thing that needs to be done is to initialize the Cmd library. The main thing to do is to set up the serial port speed. You can use any of the standard serial port speeds. In this case, I’m using 57,600 bits per second.
3) You’ll also see that the commands are added in the setup() portion of the code. The cmdAdd function takes two arguments. The first argument is the “friendly” name that gets used on the command line. The second argument is the name of the function in the sketch that will get executed when you type in the “friendly” name at the command line. You can add multiple commands to the command line, but in this example, we’re only adding one.
4) In the loop() portion of the code, the function cmdPoll() is called. It just checks to see if any commands have been typed into the command line.
5) This is the actual function that will get executed when you type “hello” at the command line. The “friendly” name and the function name do not need to match. In this example, they do, but in other examples, you’ll see that they’re completely different. One thing you’ll probably notice is that the function has a specific format. All functions that get called from the command line need to have this particular format because the command line will use the two function arguments to send data into the function. Let’s take a look at the function arguments and why they’re needed:
void hello(int arg_cnt, char **args)
Actually, I could have simplified things a lot by not requiring any function arguments. In that case, the format for any function would look something like this:
The only problem is that this is of limited use. At the command line, you could type in the function name and the function would get executed. That’s fine for something like the “hello” function that prints “hello world” because its static. But in many cases, you’ll want to pass in command line arguments to the function you’re calling. An example would be a function that changes the PWM duty cycle of an LED (cmd_line_ex4_pwm).
Rather than just typing in:
and having the LED turn on at a fixed brightness, the function becomes much more useful when you can also send in a command line argument. If you could change the PWM duty cycle on the fly, then you can experiment with different brightnesses to see which one suits your application:
If you could support command line arguments, then you can experiment with the different brightnesses dynamically rather than having to re-code the function and download it into the board.
To support generic command line arguments that can be used in any function, I used the convention that’s commonly found in command line shell code. Shells usually pass in two pieces of data to any function called by the shell
- The number of arguments,
- An ASCII list of the arguments.
So in order to support passing in arguments to the function from the command line, I made the command line function template like this:
void func_name(int arg_count, char **args)
The arg_count is the number of arguments typed into the command line and this includes the command itself. The second variable requires more explanation. Truthfully, I would have liked to avoid something that looked like
because it scares people off. However I’m hoping that a bit of explanation will help clear things up.
In C, when you see something like “char *something”, that just means that you have an array of characters, ie: a string. When you see something like “char **something”, that means you have an array of an array of characters, in other words, an array of strings. That’s all that “char **args” is. It’s the complete list of the command line arguments that the user typed in. The command line chops up whatever’s typed in at the command line, based on spaces (space-delimited), and then puts them in a string array. It then counts how many items are in the array and passes both to the function.
In Example 2, there’s a command line function that just shows how the chopping occurs and what the data passed into the functions look like. The output is just the raw output of the “char **args” data that’s passed to the function. The command line, aka “friendly”, name in Example 2 is called “args” and here’s what it does:
CMD >> args 3 45 67 hello world i love you yayAs the implementor of the function, its up to you to decide which arguments you want to use and which to ignore.
Arg 0: args
Arg 1: 3
Arg 2: 45
Arg 3: 67
Arg 4: hello
Arg 5: world
Arg 6: i
Arg 7: love
Arg 8: you
Arg 9: yay
One more thing that you need to know to use the arguments that get passed into the function is that the numeric arguments are passed in as ASCII strings. They’ll need to be converted to integers to be used in the actual application. I’ve also implemented a function that does this:
int cmdStr2Num(string, base);The string variable is just the numeric string that you want to convert to a usable integer value and the base is the numeric base you want to use for the conversion. So for a decimal number, you’ll want base=10 and for a hexadecimal number, you’ll want base=16. Here’s an example of how to use it. It’s actual Example 3 (cmd_line_ex3_led_blink) from the library:
led_blink_delay_time = cmdStr2Num(args, 10);If you run Example 3 and type this in at the command line:
blink 100then the command line arguments passed into the led_blink function look like this:
args = “blink”
args = “100”
We’ll need to convert the ASCII string “100” to a usable integer and to do that, the function “cmdStr2Num” is used as shown above. Once we have a usable integer, then we can use it inside the sketch. You’ll also see an example of how to control PWM from the command line in Example 4.
Hopefully that helps in understanding how to use the command line. If you have any questions, you can post a comment or post in the forums.
Hope you enjoy this lib. Here's a quick reference on what functions exist and their arguments:
- void cmdInit(speed)
Usage: This goes into the setup() loop and initializes the command line interface's serial speed.
- void cmdPoll()
Usage: This goes into the loop() function and checks if there are any new commands that have been entered.
- void cmdAdd(cmd_line_name, function_name)
Usage: This is used in the setup() section and adds a command to the command table. The cmd_line_name is the alias that is used at the command line to trigger the execution of the function. The function_name is the name of the function that will be executed.
- int cmdStr2Num(numeric_string, base)
Usage: This is used to convert a numeric string to an integer. numeric_string is a number in ASCII string form. base is the numeric base. Most people will probably only set base to 10 (decimal) or 16 (hexadecimal).
pwmVal = cmdStr2Num(args, 10);
- Command Line Function Template
All functions that will be called from the command line must follow this format.
void func_name(int arg_cnt, char **args)
Note: You'll notice that the source code has a .cpp extension but is really written in C. There was some weird error messages for the Arduino Serial library when I compiled with a .c extension as opposed to when I used a .cpp extension. There's probably something I'm missing, but since I'm still getting used to the Arduino dev environment (it's only my second day using an Arduino, ya know), I decided to go with the .cpp extension. This will probably get fixed in a later release.