Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

thijse/Arduino-CmdMessenger

Open more actions menu

Repository files navigation

CmdMessenger

CmdMessenger — Arduino to PC communication

License: MIT Version Arduino Library Manager

A command-based messaging library for Arduino that enables structured communication between microcontrollers and PC host applications over serial, Bluetooth, or TCP/IP.

The protocol is simple — <cmdId>,<arg1>,<arg2>,...; — but the library handles typed arguments, binary encoding, callback dispatch, send/receive queues, connection management, and auto-reconnect for you.


Host client libraries

CmdMessenger includes first-class host-side clients for three languages. Pick the one that fits your project.

Language Location Status Transports
C# / .NET extras/CSharp/ ✅ Stable Serial, TCP, Bluetooth (Windows)
Python extras/Python/ 🚧 Alpha Serial, TCP
TypeScript / Node.js extras/TypeScript/ 🚧 Initial Serial, TCP

All three clients share the same protocol, the same queue strategies, and the same test scenarios — a sketch that works with the C# client will work unchanged with the Python or TypeScript client.


Install the Arduino library

Arduino Library Manager (recommended):

Search for "CmdMessenger" in Sketch → Include Library → Manage Libraries.

PlatformIO:

lib_deps = CmdMessenger

Arduino quickstart

#include <CmdMessenger.h>

enum { kSetLed, kStatus };

CmdMessenger cmdMessenger = CmdMessenger(Serial);

void onSetLed() {
  bool ledState = cmdMessenger.readBoolArg();
  digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW);
  cmdMessenger.sendCmd(kStatus, ledState);
}

void setup() {
  Serial.begin(115200);
  cmdMessenger.attach(kSetLed, onSetLed);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  cmdMessenger.feedinSerialData();
}

Send 0,1; from the Serial Monitor → LED on, board replies 1,1;.


C# client

Requires .NET 8 SDK or later. Works on Windows, Linux and macOS.

using CommandMessenger;
using CommandMessenger.Transport.Serial;

var transport = new SerialTransport
{
    CurrentSerialSettings = { PortName = "COM3", BaudRate = 115200, DtrEnable = true }
};
var messenger = new CmdMessenger(transport);
messenger.Connect();

messenger.Attach(1 /* kStatus */, cmd =>
    Console.WriteLine("LED is now " + (cmd.ReadBoolArg() ? "on" : "off")));

// Send command 0 (kSetLed) with argument true, wait for ACK command 1
var ack = await messenger.SendCommandAsync(new SendCommand(0, true, 1, 500));

Run the paired samples:

cd extras/CSharp/Samples/SendAndReceive
dotnet run

The sample projects are in extras/CSharp/Samples/ — numbered 1–10 matching the Arduino examples.

UI thread marshalling — if calling from a WinForms/WPF/MAUI UI thread, set:

messenger.SynchronizationContext = SynchronizationContext.Current;

This routes all callbacks to the UI thread automatically.


Python client

Requires Python 3.9+. Works on Windows, Linux and macOS.

cd extras/Python
build.bat          # Windows
bash build.sh      # macOS / Linux

This creates a .venv, installs dependencies, and installs py-cmdmessenger in editable mode.

from cmd_messenger import CmdMessenger, SendCommand, BoardType
from cmd_messenger.transport.serial import SerialTransport, SerialSettings

settings = SerialSettings(port_name="COM3", baud_rate=115200)
transport = SerialTransport(settings)

with CmdMessenger(transport, board_type=BoardType.BIT_16) as messenger:
    messenger.connect()

    def on_status(cmd):
        print("LED is now", cmd.read_bool_arg())

    messenger.attach(1, on_status)
    messenger.send_command(SendCommand(0, True))  # kSetLed, true
    import time; time.sleep(0.5)

See extras/Python/ for the full library and console + web-UI samples.


TypeScript / Node.js client

Requires Node.js 22+.

cd extras/TypeScript
npm ci
npm run build
import { BoardType, CmdMessenger, SendCommand } from 'cmd-messenger';
import { SerialTransport, SerialSettings } from 'cmd-messenger/transport/serial';

const transport = new SerialTransport(new SerialSettings({ portName: 'COM3', baudRate: 115200 }));
const messenger = new CmdMessenger(transport, BoardType.Bit16);

await messenger.connect();
messenger.attach(1 /* kStatus */, cmd =>
    console.log('LED is now', cmd.readBoolArg()));

await messenger.sendCommand(new SendCommand(0, true));  // kSetLed, true

See extras/TypeScript/ for the full library.


Arduino features

  • All primary types — bool, int16, int32, float, double, char, string, binary
  • Plain text or binary encoding — human-readable or efficient, your choice
  • Callback-drivenattach(cmdId, handler) for each command ID
  • sendArg() family — send arguments without field separator for custom packet formats
  • Configurable delimiters — field separator (,) and command separator (;) are settable
  • Multiple transports — Serial USB, Bluetooth (HC-05/HC-06), TCP over WiFi/Ethernet
  • Any Stream interface — works with Serial, SoftwareSerial, WiFiClient, BLE UART, etc.

Compatibility

Platform Notes
Arduino AVR (Uno, Mega, Nano, Pro Micro…) Full support
Arduino ARM (Due, Zero) Full support
ESP8266 / ESP32 Full support; use RtsEnable = true on the C# side for auto-reset
Teensy 3.x / 4.x Full support
Digispark (attiny85) Supported; requires Energia or Digispark core
Any Stream-compatible board Should work

Requires Arduino IDE 1.5+ or PlatformIO.


Examples

Sketch Demonstrates C# Python TypeScript
Receive Receive commands
SendAndReceive Bidirectional
SendAndReceiveArguments Typed arguments
SendAndReceiveBinaryArguments Binary encoding
DataLogging Live charting
ArduinoController GUI + queued commands
TemperatureControl PID + live chart
SimpleWatchdog Auto-reconnect
ConsoleShell Serial shell (no PC app)
SendWithoutSeparator Custom packet format

Troubleshooting

Symptom Fix
Cannot connect Verify COM port and baud rate. Test with the ConsoleShell sketch + Serial Monitor.
Callbacks not firing Enable logging on the C# side; check DtrEnable = true for boards that need DTR reset.
ESP32 / ESP8266 not resetting Set both DtrEnable = true and RtsEnable = true on the C# / Python side.
PlatformIO install fails Ensure your lib_deps uses CmdMessenger (no extra dependencies are required).
Pro Micro (32u4) Native USB — set DtrEnable = true.

Credits

Version Author
Messenger (original) Thomas Ouellet Fredericks
CmdMessenger v1 Neil Dudman
CmdMessenger v2 Dreamcat4
CmdMessenger v3–v4 Thijs Elenbaas & Valeriy Kucherenko
CmdMessenger v5 Thijs Elenbaas

License

MIT — Copyright © 2013–2026 Thijs Elenbaas.


Changelog

v5.0.0

New host clients:

  • [Python] First-class py-cmdmessenger library — full parity with C# (serial + TCP, all queue strategies, connection manager, watchdog, auto-reconnect, JsonSerialConnectionStorer)
  • [TypeScript] First-class Node.js client — serial + TCP, all queue strategies, connection manager, JsonSerialConnectionStorer

C# — async core rewrite:

  • SendCommandAsync(cmd) / await messenger.SendCommandAsync(...) — proper async ACK wait via TaskCompletionSource per pending ACK; no busy-spin, no receive-queue suspension
  • AsyncWorker replaced with async Task drain loop + CancellationTokenSource
  • EventWaiter replaced with SemaphoreSlim-based async waiter
  • System.Threading.Channels used for queue backing

C# — modernisation:

  • Target framework: netstandard2.0 (covers .NET Framework 4.6.1+, .NET Core 2+, .NET 5–11, Linux, macOS)
  • System.Windows.Forms dependency removed from core library
  • ControlToInvokeOn (WinForms-only) replaced with SynchronizationContext — works with WinForms, WPF, MAUI, console, any platform
  • All project files migrated from old verbose MSBuild format to SDK-style
  • Console samples target net8.0; WinForms samples target net8.0-windows
  • BinaryFormatter in storers replaced with JSON (JsonSerialConnectionStorer)
  • ScottPlot 5 replaces ZedGraph in charting samples
  • Callback exceptions now isolated — unhandled exceptions fire CallbackException event instead of crashing the receive pump
  • ReadCharArg() added to ReceivedCommand
  • Read(string format) format-string reader added (e.g. cmd.Read("ifs"))
  • IEnumerable<string> added to ReceivedCommand (foreach over raw arguments)
  • RtsEnable added to SerialSettings (ESP32/ESP8266 auto-reset)
  • SerialConnectionStorer now persists to JSON; BinaryFormatter removed
  • 247 xUnit unit tests (was 98)

Arduino firmware:

  • comms->print(cmdId, DEC) — fixes compile error on Digispark/Energia non-standard cores
  • CMDMESSENGER_MAXCALLBACKS used consistently throughout

Bug fixes:

  • [C#/#22] Commands arriving during ACK wait were silently dropped — fixed; non-ACK commands always queued
  • [C#/#29] ObjectDisposedException on sleep/wake / hot-unplug — fixed via proper disposal order
  • [C#/#30] Receive queue not signalled after suspend/resume — fixed

Metadata:

  • library.properties version aligned with library.json
  • Spurious Adafruit MAX31855 library dependency removed from library.json

v4.1.0

  • [Arduino] sendArg(), sendSciArg(), sendBinArg() — send arguments without field separator
  • [Arduino] unescape() applied to string reads (fixes escaped delimiter handling)
  • [Arduino] Bounds-checked readBinArg<T>() with ArgOk validation
  • [Arduino] Configurable CMDMESSENGER_MAXCALLBACKS with compile-time zero-callback support
  • [Arduino] ESP8266/ESP32 type fixes
  • [Arduino] LastArgLength tracking in argument parser
  • Fix: startCommand initialization
  • Fix: comms->print used consistently (no direct Serial.print)
  • Fix: LICENSE.md reformatted for GitHub detection

v4.0.0

  • [Arduino] Additional autoConnect sample
  • [.NET] Full threading redesign
  • [.NET] AutoConnect & watchdog functionality
  • [.NET] Tested Linux compatibility
  • [.NET] Visual Basic samples
  • [.NET] Native Bluetooth support (Windows only)

v3.6

  • [Arduino] Bugfix: ~1 in 1000 commands failed with multiple binary parameters
  • [Arduino] Bugfix: binary send of non-number compile error
  • [Arduino] Feature: send command without argument
  • [Arduino] Feature: scientific notation for full float range
  • [.NET] Unit tests, performance improvements

v3.5

  • [Arduino] Console shell sample, minor performance improvement

v3.4

  • [Arduino] Bug-fix in receiving binary values
  • [.NET] 100× faster communication, single-core support

v3.3

  • [Arduino] Speed improvements for Teensy

v3.2

  • [All] Clean transport layer interface (Bluetooth, ZigBee, Web)
  • [.NET] Adaptive throttling, smart queuing

v3.0

  • Multi-argument commands, type arguments, binary data, escaping, acknowledgements

v2

  • Arduino IDE 022, configurable separators, Base-64 encoding, Serial Monitor debugging

Releases

Packages

Used by

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.