Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

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

A Python interface to this library is also available:
https://github.com/harmsm/PyCmdMessenger

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)

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.

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();
int   readIntArg ();
char  readCharArg ();
float readFloatArg ();
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.

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.

Changelog

CmdMessenger v3

  • Wait for acknowlegde 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)
  • Bugfixes
  • 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 Arduinos)
  • More reliable process() loop.
  • User can set their own cmd and field seperator
 (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.