The serial command handler is an Arduino library to decode and process commands sent to the Arduino using a serial port by MegunoLink (or any serial program). When the library receives a command it can either:

  1. Call an Arduino function
  2. Update an Arduino variable

Serial commands can be sent from MegunoLink’s Raw Serial Visualizer, Message Monitor Visualizer or you can build an Interface Panel that sends a serial command when you click a button. Commands can include multiple parameter values, limited only by the memory you set aside for the command handler in your Arduino sketch.

Arduino Library

You’ll need to install our Arduino library to use the CommandHandler class.

Blink User Interface

A simple user interface created with MegunoLink’s Interface Panel Visualizer. Clicking the Set All button sends a serial command with the Interval and Duration values to the Arduino. Clicking either Get button retrieves the value from the Arduino program and updates the controls.

Get started with a custom interface

Build a custom user interface by dragging and dropping controls then send commands by clicking buttons.

Serial Command Format

By default, commands start with a ‘!’ character and end with a carriage return (‘\r’) though both can be customized. Parameters can be included in the serial message and are separated using a space. Example commands:

  1. !SetPoint 4\r
  2. !StartMotor\r
  3. !TurnLEDsOn 1 2 3\r

Using the Serial Command Handler

To use the serial command handler in your program you need to:

  1. #include "CommandHandler.h" to make the library available to your program
  2. Create a CommandHandler<> SerialCommandHandler; variable
  3. Add the commands you want to handle
    • To call a function when a command is received use SerialCommandHandler.AddCommand(F("CommandName"), Cmd_FunctionToCall)
    • To update a variable when a command is received use SerialCommandHandler.AddVariable(F("CommandName"), VariableName)
  4. Implement the command functions. Each must take a single CommandParameter reference, even if it isn’t used.
  5. Call SerialCommandHandler.Process() in your main loop function to receive and decode commands

For a detailed walk through see Getting started processing serial commands

Automatic code generator

Boiler plate code to process messages from your interface panel is generated automatically in the designer’s example code window. Just copy and paste into your Arduino sketch.

Command limits

The maximum number of commands and variables that can be registered, and the maximum length of a command (including all parameters) is set when the command handler variable is created. The default is 10 commands and variables and 30 character commands.

The command and variable limits can be increased to register more commands and/or variables. Decreasing the limits will save memory. Each additional command uses 4 bytes of RAM on an Arduino Uno; each additional variable uses 8 bytes of RAM on an Arduino Uno. See command handler construction and example declarations below.

The command handler holds a buffer to assemble new commands. This buffer must be large enough to handle the command and all of the parameters. It can be increased to handler longer commands or decreased to save memory. See command handler construction and example declarations below.

Serial Command Handler Reference

The CommandHandler is implemented as a C++ template:
template <int MAX_COMMANDS = 10, int CP_SERIAL_BUFFER_SIZE = 30, int MAX_VARIABLES=10> class CommandHandler{…}

Command Store Size

The CommandHandler uses a fixed size array to store the command names and functions to call. By default 10 commands can be added to the handler. This can be changed using the first template parameter. You would need to increase this if you want to handle more commands. You could decrease this to save a little bit of memory. Each command slot uses 4 bytes.

See command handler constructor for examples.

Command Buffer Size

The CommandHandler uses a fixed-size buffer to store characters as they are received from the serial port until a complete message is received. By default this buffer is 30 characters long. This can be changed using the second template parameter. You could increase this if you are sending long commands, or commands with lots of parameters. You could decrease this to save memory. The buffer has to be large enough to contain the start of message character (‘!’) and the terminator (‘\r’) and all the characters in between.

See command handler constructor for examples.

Variable Store Size

The CommandHandler uses a fixed-size buffer to store the map from command name to variable. By default 10 variables can be added to the handler. This can be changed using the third template parameter. You’d need to increase this if you want to handle more variables. Decreasing this would save a little bit of memory. Each command slot uses 7 bytes.

See command handler constructor for examples.

Command Handler construction

The CommandHandler constructor takes three (optional) arguments:
CommandHandler(Stream &SourceStream = Serial, char StartOfMessage = '!', char EndOfMessage = '\r')

  • SourceStream the serial port that the command handler should listen to. Normally this is Serial, the Arduino’s default serial port. But some devices (such as the Mega support additional ports. To receive data on the second Mega serial port, you’d pass Serial2 as the first argument when creating the command handler variable,
  • StartOfMessage is the character that the command handler looks for to mark the start of a new message. By default it is a ‘!’. Whenever the command handler encounters the start character it will discard whatever it has so far and begin building a new message. So you need to make sure the start character will never be found in the message itself.
  • EndOfMesasge is the character that marks the end of a message. By default it is a carriage return (‘\r’). When the end character is found, the command handler tries to match the command it has received and call the matching function. You need to make sure the end character is never found as part of the message itself.

Example Serial Command Handler declarations

Declaration Maximum number of Commands Maximum command length Maximum number of Variables Start of Message End of Message
CommandHandler<> SerialCommandHandler; 10 (default) 30 characters (default) 10 (default) ! \r
CommandHandler<15> SerialCommandHandler; 15 30 characters (default) 10 (default) ! \r
CommandHandler<12,20> SerialCommandHandler; 12 20 characters 10 (default) ! \r
CommandHandler<10, 30, 15> SerialCommandHandler; 10 (default) 30 characters (default) 15 ! \r
CommandHandler<> SerialCommandHandler(Serial1); 10 (default) 30 characters (default) 10 (default) ! \r
CommandHandler<> SerialCommandHandler(Serial2, '#', '^'); 10 (default) 30 characters (default) 10 (default) # ^

Adding Commands

To add a command, call SerialCommandHandler.AddCommand(F("CommandName"), Cmd_CommandFunction);. This would typically be used in the setup function of your program.

CommandName is the text the command handler will look for between the start of a command message and the first space (or end of the command message). Normally a ‘!’ marks the start of the command message and a ‘\r’ marks the end of the command message. So, for example, On is the command in each of these messages: !On\r, !On 23\r. But not in this one: !Onguard 12\r. The command handler will print AddCommand: full if there isn’t enough space to store another command.

Cmd_CommandFunction is the Arduino function in your program that will be called whenever the command message is found. It can have any name you like, but it must take one parameter, a CommandParameter &. So the function should look like this:

The parameter variable lets you get any parameters that came with the command. See working with parameters below.

Adding Variables

To add a variable, call SerialCommandHandler.AddVariable(F("VariableName"), Variable);. This would typically be used in the setup function of your program. The command handler will print AddVariable: full if there isn’t enough space to store the variable.

VariableName is the text the command handler will look for between the start of a command message and the first space (or end of the command message). Normally a ‘!’ marks the start of the command message and a ‘\r’ marks the end of the command message.

Variable is the variable you want the command handler to update when the variable name in the command matches a registered variable. This variable should be in the global scope of your program. For example, a variable declared at the top of your program outside any functions.

So, for example, if you register SerialCommandHandler.AddVariable(F("SetPoint"), SetPoint) the command !SetPoint 20\r would update the SetPoint variable to 20.

The following types of variables are supported:

  • float
  • double
  • byte
  • short
  • int
  • long
  • uint8_t
  • uint16_t
  • uint32_t
  • int8_t
  • int16_t
  • int32_t

Update variables from a GUI Use input-controls and buttons to send values to your Arduino variables.

Default Handler

When first setting up a new program it can be helpful to know if messages are received that don’t match any known commands. This can point to errors in the commands you are sending, differences in spelling or case (capital vs lower case letters) or too many commands/variables were registered (by default only 10 commands and 10 variables are supported). By default, the command handler will print Unknown command if an unrecognized command is encountered.

Use SerialCommandHandler.SetDefaultHandler(UnknownMessageHandler); to register a default message handler. UnknownMessageHandler is a function in your program that will be called whenever an unrecognized command is encountered. It shouldn’t take any parameters. A typically unknown message handler would be:

Clearing Registered Commands

You can clear all the registered commands using the SerialCommandHandler.ClearCommands(); function.

Error Messages

Error messages reported by the command handler are summarized in the table below.

Command handler error messages
Message Description
AddCommand: full The command store is full. Increase the store size or reduce the number of commands registered
AddVariable: full The variable store is full. Increase the store size or reduce the number of variables registered
Unknown command An unknown command/variable was encountered. Check the command was registered (with AddCommand(…) or AddVariable(…)) and the store isn’t full (see AddCommand: full and/or AddVariable: full above.
Ovrflw The command received was too long to fit in the buffer. Reduce the command length or increase the size of the command buffer

Working with Parameters

When the handler matches a command it will call the function registered for that command. This function must take a single parameter, a CommandParameter &. So a typical command handler function would look like this:

You need to include the parameter, even it is not used in the command handler function. Otherwise your program won’t build.

The CommandParameter provides access to any parameters that were included in the serial message. Parameters are separated by spaces.

A CommandParameter supports the following methods:

  • NextParameter() returns the next parameter (as text) in the serial message
  • RemainingParameters() returns the rest of the message as text
  • NextParameterAsInteger(Default) interprets the next parameter as an integer (16 bit) value; returns Default if the next parameter isn’t a valid integer
  • NextParameterAsLong(Default) interprets the next parameter as an long (32 bit) value; returns Default if the next parameter isn’t a valid integer
  • NextParameterAsUnsignedLong(Default) interprets the next parameter as an unsigned long (32 bit) value; returns Default if the next parameter isn’t valid
  • NextParameterAsDouble(Default) interprets the next parameter as an double value; returns Default if the next parameter isn’t valid

Example

Sending !SetTurtleCount 5\r from MegunoLink Pro will update the NumberOfTurtles variable in this simple example. Sending !GetTurtleCount\r will print the current value of the NumberOfTurtles variable to the serial port.

These commands can be sent from the Arduino serial monitor or MegunoLink’s serial monitor. Or you can build a custom user interface with buttons that send commands so you don’t have to remember them all.

Start typing and press Enter to search