The Command Handler is an Arduino library, bundled with MegunoLink, to simplify receiving and decoding serial commands.

Commands are serial messages that start with a ! and end with the escape-codes \r\n.

After you’ve registered command names with command functions, the command handler will call the registered function whenever it receives the command name.

interface panel

An Interface Panel sends commands to the Arduino when buttons are clicked.

Anatomy of a Command

A command is a serial message made up of 4 parts:

  1. Start marker: a ! that marks the beginning of the command.
  2. Command name: the unique name that identifies the command made up from upper and lower case letters, numbers and underscore (_) characters
  3. Command parameters: optional parameters for the command; parameters are separated by spaces
  4. End marker: a carriage return and new-line character marking the end of the command (\r\n)
Serial command anatomy

A command is made up of four parts.

Setup the Command Handler

To use the command handler, in your Arduino sketch, you need to:

  1. #include "CommandHandler.h"
  2. Create a global variable CommandHandler<> SerialCommandHandler;
  3. Register the commands you want to handle in your setup() function
  4. Implement the command functions
  5. Call SerialCommandHandler.Process() in your loop() function to receive and decode commands

You’ll need to install our Arduino Library to use the Command Handler

A Command Handler Variable

The global SerialCommandHandler; looks after three things:

  1. keeps track of the functions to call when a command is received;
  2. reads serial messages and looks for commands;
  3. calls the registered function whenever it finds a command

The command handler is a template so make sure to include the <> right after the CommandHandler type name. You can customize the command handler’s behavior by adding parameters between the <>‘s.

Registering Commands

Registering commands in your setup() function links the name of the command to the function that will be called when the command is received.

Register commands using: SerialCommandHandler.AddCommand(F("CommandName"), Cmd_FunctionToCall). Where:

  • CommandName is the command text to match
  • Cmd_FunctionToCall is the Arduino function that will be called when the command is received

Implementing Command Functions

Command functions are called by the SerialCommandHandler whenever it receives the registered command name. They need to be defined like this:

Parameters gives you access to any parameters included after the command name. It must be included, even if you don’t use any parameters.

Working with Command Parameters

Parameters are the optional part of a command which follow the command name. There is 1 space between the command and the first parameter; each parameter is separated by 1 space.

Parameters can be retrieved inside the command handler function. The CommandParameter &parameters argument includes methods to retrieve each parameter value in turn. These methods include:

  • parameters.NextParameter(): returns the next parameter as text
  • parameters.NextParameterAsInteger(Default): returns the next parameter as an integer value, or Default value if there aren’t any more parameters
  • parameters.RemainingParameters(): returns the rest of the parameters (including any spaces) up to the end marker

For example, the following command handler function retrieves a single integer parameter from a command like !SetOnTime 120\r\n. This implementation just prints the value, but you could save it or use it to perform an action such as move a robot:

Handling Unknown Commands

Sending incorrect commands is the most common problem when using the serial command handler. Building an Interface Panel visualizer to send the commands is an easy way to avoid typing mistakes when sending commands. You can also setup a function to handle unknown commands. It can print an error message to let the user know the command was received, but not understood.

Arduino Command Processing Example

This example extends the classic Arduino blink program with serial commands to control how long the LED is on and off. It uses

Open this example in MegunoLink to follow along:

  1. In MegunoLink, open Library ExamplesMegunoLinkInterfacePanelMegunoLink Blink2.
  2. Then choose Open (open project)Open Arduino Code.

The sketch accepts these commands:

  • !SetOnTime 40\r\n Sets the time the LED remains on to 40 ms
  • !SetOffTime 100\r\n Sets the time the LED remains off to 100 ms
  • !ListAll\r\n Lists the current setting of all parameters

Values for the on- and off-time commands come from the Interface Panel.

Arduino Blink Interface Panel

The Interface Panel sends to change the on-time and off-time of the LED when the Set buttons are clicked.

First we’ll look at the entire sketch and then break it down:

Detailed Example Walk-through

Blinking the LED

Blinking the LED using delay(…) won’t work for this sketch because the delay function prevents the Arduino from doing much else. That’s a problem for our command handler. If the Arduino is busy waiting for the next blink it can’t receive serial commands.

So we use time to decide when to blink the LED instead. The code responsible for this is:

The first block sets up the variables needed:

  • LastBlink: the time that the LED was last turned on. This comes from the Arduino’s millis() timer, and is measured in milliseconds since the Arduino was last reset.
  • OnTime: time that the LED spends on (in milliseconds).
  • OffTime: time that the LED spends off (in milliseconds).

The OnTime and OffTime variables are changed when we receive the serial commands !SetOnTime and !SetOffTime (more on that a bit later). Changing these values will change the blink rate.

The second block lives in the program loop. It is responsible for turning the LED on and off. Each time through the loop we:

  1. put the current time in uNow, and
  2. if the time since we last turned the led on (LastBlink) is less than the amount of time the LED should be on then the LED is turned on, otherwise it it is turned off.
  3. If it has been longer than the total amount of time the LED should be on and off, then LastBlink is reset so blinking continues.

So the blinking rate will change when the OnTime and OffTime variables are changed. Before looking at how these are changed by the serial commands, lets look at how the command handler is setup.

Setup the Command Handler

There are three blocks of code that setup and run the command handler.

First, include the library and create global command handler variable:

The SerialCommandHandler variable is declared at file scope so it can be used in the setup() and loop() functions.

The angle brackets (<>) are needed after the CommandHandler type name because it is a template. You can change the maximum number of commands supported (10) and the size of the serial buffer (30 characters) by putting values between the angle brackets. Check out the command handler reference for more information.

Next, add each command to the command handler inside the setup function. Of course, the Arduino Serial library has to be initialized too:

Finally, at the start of the loop() function, the Process() method is called. This method receives characters from the serial port and calls the appropriate function whenever a command is received:

Command Functions

Command functions are called by the SerialCommandHandler when the matching serial command is received. This example registers 3 command functions:

  • Cmd_SetOnTime: called for the SetOnTime command.
  • Cmd_SetOffTime: called for the SetOffTime command.
  • Cmd_ListAll: called for the ListAll command.

Here’s the implementation for the Cmd_SetOnTime function (the others are similar):

The SerialCommandHandler passes a CommandParameter variable to the function when it is called. This variable provides access to any parameters following the command.

In this example, the new time to turn the LED on is retrieved as an integer parameter using Parameters.NextParameterAsInteger(OnTime) and saved in the global variable OnTime to set a new flashing rate.

The current value of OnTime is passed to NextParameterAsInteger, which uses it as the default value. So if the command sent doesn’t include a valid integer, the function will simply return the current value by default and the flash rate won’t change.

You must include CommandParameter &parameters as a parameter, even if you don’t use it in the function. Check out the command handler documentation for other methods you can use to retrieve parameters.

What's Next?

Once you’ve added a basic command handler to your Arduino sketch you can:

Start typing and press Enter to search