CmdMessenger Replaces Messenger

CmdMessenger Library

Description

CmdMessenger is a messaging library for the Arduino Platform (and .NET/Mono platform). It uses the serial port as transport layer. To use CmdMessenger, we define a list of command identifiers, then attach callback / handler functions for received messages.

The message format is:

Cmd Id, param 1, [...] , param N;
The library gives the following functionality:

  • Sending and receiving commands
  • Calling of associated functions on received commands
  • Sending and receiving zero to many arguments per command
  • Sending and receiving of all primary types. This includes bytes, longs, ints, floats and doubles.
  • Sending and receiving in plain text form (human readable, robust) or in binary form (efficient)

With version 3 also comes a full implementation of the library in C#, which runs both in Mono (http://monodevelop.com/Download) and Visual Studio (http://www.microsoft.com/visualstudio/eng#downloads) This enables full 2-way communication between the Arduino controller and the PC.

Download the library here:
http://thijs.elenbaas.net/downloads/?did=9

And find more background and and example of the functionality here:
http://thijs.elenbaas.net/2013/09/arduino-to-pc-messaging

Library usage

Initializing the library

The library needs to be instantiated with the serial port:

CmdMessenger (Stream& Serial)

If desired, we can change the field_separator, command_separator and escape_character

CmdMessenger (Stream& Serial, const char field_separator, const char command_separator, const char escape_character);

For readability we can turn on adding new lines at the end of every character

void printLfCr (bool addNewLine=true);

Incoming serial data should be processed in the Loop() function by calling

void feedinSerialData ();

Sending a command

When sending a command without parameters, the format is

sendCmd (int cmdId)

When sending a command with an argument

sendCmd (int cmdId, T arg)
where T is the data type of the argument we want to send

If we want to send a command, and wait for a response, use:

bool sendCmd (int cmdId, T arg, bool reqAc, int ackCmdId, int timeout)

where

  • reqAc determines whether we want to wait for a response (set to true)
  • ackCmdId is the command to wait for and timeout is the timout in milliseconds.
  • the return valueis true if the response was received before timeout, else false.

Note that all commands other than the acknowledge command will be ignored (until time out)

Sending a command with multiple arguments

In order to send multiple arguments, we can split the send command up:

sendCmdStart (int cmdId);
sendCmdArg (T arg)
sendCmdEnd ();

or

bool sendCmdEnd (bool reqAc, int ackCmdId, int timeout);

Between sendCmdStart and sendCmdEnd, we can send as many arguments as we want using sendCmdArg. Arguments may have diffent data types

Sending formatted, escaped and binary parameters

Floats are similarly send as ASCII digits, defaulting to two decimal places. If we want to send over more decimal places we can do this by

sendCmdArg (float arg, int n)

Because of limitations of Arduino, this function is only able to send floats(and doubles) in the range of from -2,147,483,648 to 2,147,483,647. With the following function we can send floats in scientific format, and that span the full range of -3.4028235E+38 to -3.4028235E+38.

cmdMessenger.printSci (arg, n)

If we want to format am argument with printf like syntax we can use

sendCmdfArg (char *fmt, ...);

Please note that formatted floating point variables are currently not supported on the Arduino platform.

If we want to string that may contain the , or ; character, we can escape it before sending. These characters can now be sent safely. The string needs to be unescaped upon reading

sendCmdEscArg (char *arg);

In order to send binary arguments we use

sendCmdBinArg (T arg)

where T is the type of the argument to send. It is prudent to use explicit casting for binary types. Unlike plain text sending is, the parameter types must match precisely between sending and receiving sides. For this reason use int16_t and int32_t when sending integers: these have the same definition on all platforms

Attaching callback functions

Attach callback functions to a message ID using

attach (byte msgId, messengerCallbackFunction CallBackFunction);

Attach a callback function for messages that have no explicitly attached function using

attach (messengerCallbackFunction CallBackFunction);

Reading receive command arguments

In your callback function you can read out the parameters that where send together with the command ID

To check if there is (another) argument is available, use

bool available ();

If so, you can read the arguments with the following functions

bool  readBoolArg();
int16_t readInt16Arg ();
int32_t readInt32Arg ();
char  readCharArg ();
float readFloatArg ();
float readDoubleArg ();
char* readStringArg ();

Note that readStringArg behaves a bit differently, in that the string is only available as long as no new command has been read. To have a persistent string argument, we can use the following function to make a copy

copyStringArg (char *string, uint8_t size);

In order to compare a string with the current argument

uint8_t compareStringArg (char *string);

To read a binary argument use the function

T readBinArg ()

This function can also be used to unescape strings

Requirements

[Arduino IDE Version 1.0.5 or later](http://www.arduino.cc/en/Main/Software). Earlier versions of the Arduino IDE may work but have not been tested.

Getting Started

Get to know the library, by trying the examples,from simple to complex:

Receive

The 1st example will make the PC toggle the integrated led on the arduino board.

SentandReceive

This example expands the previous Receive example. The Arduino will now send back a status.

SendandReceiveArguments

This example expands the previous SendandReceive example. The Arduino will now receive multiple and sent multiple float values.

SendandReceiveBinaryArguments

This example expands the previous SendandReceiveArguments example. The Arduino will receive and send multiple Binary values, demonstrating that this is more efficient way of communication.

DataLogging

This example expands the SendandReceiveArguments example. The PC will now sends commands to the Arduino when the trackbar is pulled. Every TrackBarChanged events will queue a message to the Arduino to set the blink speed of the internal / pin 13 LED.

ArduinoController

This example expands the SendandReceiveArguments example. The PC will now sends commands to the Arduino when the trackbar is pulled. Every TrackBarChanged events will queue a message to the Arduino to set the blink speed of the internal / pin 13 LED.

TemperatureControl

This example expands the previous ArduinoController example. The PC will now send a start command to the Arduino, and wait for a response from the Arduino. The Arduino will start sending temperature data and the heater steering value data which the PC will plot in a chart. With a slider we can set the goal temperature, which will make the PID software on the controller adjust the setting of the heater. This example shows how to design a responsive performance UI that sends queued commands and add queue strategies.

ConsoleShell

This example shows how to use CmdMessenger as a shell, and communicate with it using the Serial Console This example is different from the others: there is no PC counterpart and it will only receive commands, instead of sending commands it will use Serial.Print

All samples are heavily documented and should be self explanatory. 1. Open the Example sketch in the Arduino IDE and compile and upload it to your board. 2. Open de CmdMessenger.sln solution in Visual Studio or Mono Develop/Xamarin Studio 3. Set example project with same name as the Arduino sketch as startup project, and run 4. Enjoy!

Trouble shooting

  • If the PC and arduino are not able to connect, chances are that either the selected port on the PC side is not correct or that the Arduino and PC are not at the same baud rate. Try it out by typing commands into the Arduino Serial Monitor.
  • If the port and baud rate are correct but callbacks are not being invoked, try looking at logging of sent and received data. See the SendandReceiveArguments project for an example

Notes

An example for use with Max5 / MaxMSP was included up until version 2. (it can still be found here https://github.com/dreamcat4/CmdMessenger). Since we have not been able to check it wil Max/MaxMSP, the example was removed.

Alternative C# Implementation

An alternative C# implementation of the library can be found on Code Project.

http://www.codeproject.com/Articles/842951/CmdMessenger

This implementation of the library does not support Mono or sending messages in binary form. However, the library does support modern C#5 features and is a simplified implementation. The article also acts as a good example of applying the library.

Changelog

CmdMessenger v3.0 - 3.6

  • Wait for acknowledge commands
  • Sending of common type arguments (float, int, char)
  • Multi-argument commands
  • Escaping of special characters in strings
  • Sending of binary data of any type (uses escaping, no need for Base-64 Encoding)
  • Bug-fixes
  • Added code documentation
  • Added multiple samples

CmdMessenger v2

  • Updated to work with Arduino IDE 022
  • Enable / disable newline (print and ignore)
  • New generic example (works with all Arduino's)
  • More reliable process() loop.
  • User can set their own cmd and field separator
 (defaults to ';' and ',')
  • Base-64 encoded data to avoid collisions with ^^
  • Works with Arduino Serial Monitor for easy debugging

Credit

Copyright

CmdMessenger is provided Copyright © 2013 under MIT License.

Share