Welcome, Arduino developers! The Arduino port of USMP wraps the core C protocol in an ergonomic, developer-friendly C++ class: USMPClient. This guide walks you through the library structure, API signatures, and transport configurations.
Installation
USMP is packaged as a standard offline ZIP library to keep private repository references out of your builds:
- Locate
usmp-X.Y.Z-arduino.zipin your releases archive. - Open Arduino IDE.
- Go to Sketch ➔ Include Library ➔ Add .ZIP Library...
- Choose the zip file to complete the import.
To include it in your sketch:
#include <USMP.h>
API Reference
Constructor
USMPClient(const char *psk);
Creates a new USMP client instance.
psk: The Pre-Shared Key. This must match the key configured on your gateway.
Connection Management
begin (TCP)
bool begin(USMPTCPTransport transport);
Establishes the connection and performs the handshake over TCP.
- If Wi-Fi SSID and password are configured on the transport,
begin()automatically connects to Wi-Fi first.
begin (UDP)
bool begin(USMPUDPTransport transport);
Establishes the connection and performs the handshake over UDP.
- If Wi-Fi SSID and password are configured on the transport,
begin()automatically connects to Wi-Fi first.
maintain
void maintain();
Performs background driver tasks. You must call this inside your main loop() function.
- Checks for incoming data, triggers registered callbacks, handles keepalive pings, and automatically reconnects if the socket drops.
keepalive
void keepalive(uint32_t ms);
Sets the interval (in milliseconds) for keepalive heartbeat checks (default: 30000 / 30 seconds).
Caution:
Order of Configuration
You must call keepalive() after calling begin(). The begin() method executes a memset on the internal context, which overrides any custom keepalive interval back to the default 30 seconds.
alive
bool alive();
Checks if your secure session is currently connected and active.
deviceId & sessionId
String deviceId();
String sessionId();
deviceId(): Returns the station MAC device identifier formatted as a hex string.sessionId(): Returns the active 128-bit session identifier as a hex string (or empty string if disconnected).
setLogLevel
void setLogLevel(usmp_log_level_t level);
Configures internal protocol logging thresholds (USMP_LOG_NONE, USMP_LOG_ERROR, USMP_LOG_WARN, USMP_LOG_INFO, USMP_LOG_DEBUG).
reconnect
bool reconnect();
Manually initiates a socket reconnection and executes a fresh cryptographic handshake.
close
void close();
Gracefully closes the session (sends a BYE frame) and shuts down the connection.
Sending and Receiving Data
send
bool send(const char *str);
bool send(const String &str);
bool send(const uint8_t *data, size_t len);
Encrypts and transmits a payload to the gateway.
- Supports automatic fragmentation for payloads up to ~1.8 KB.
Polling API (Simple Style)
If you prefer a simple sequential flow, you can query the client inside your loop():
if (usmp.available()) {
String msg = usmp.read();
Serial.println(msg);
}
available(): Returnstrueif a decrypted packet is ready.read(): Reads the next decrypted packet as aString.read(buf, max_len): Copies raw decrypted bytes into a buffer and returns the length.
Callback API (Asynchronous Style)
For event-driven sketches, register callbacks in your setup():
void onConnect(void (*cb)());
void onDisconnect(void (*cb)());
void onReconnect(void (*cb)());
void onMessage(void (*cb)(const uint8_t *data, size_t len));
onConnect: Triggered on every session establishment — the initialbegin()and every successful reconnect. Use it for work that must run whenever a live session exists (e.g. re-announcing device state to the gateway).onDisconnect: Triggered when a live session is lost (send/receive/keepalive failure, or the gateway sendsBYE).onReconnect: Triggered additionally (just beforeonConnect) when a reconnection handshake completes. Use it for reconnect-specific work.onMessage: Triggered when a new decrypted message arrives.
Note:
A reconnect fires both onReconnect and onConnect (in that order). If you call send() in both handlers, a reconnect sends from both — this is intentional, not a bug.
Important:
Do Not Mix Callbacks and Polling
If you register an onMessage callback, do not call usmp.available() or usmp.read(). Doing so will interfere with data flow and cause dropped frames.
Transport Configuration Builder
Create your transport adapter configuration using the USMP:: namespace:
TCP Transport
USMP::TCP(const char *gateway_ip, uint16_t port = 9000);
- Configures a TCP socket connection.
- To let USMP manage your Wi-Fi, chain
.wifi("SSID", "Password").
UDP Transport
USMP::UDP(const char *gateway_ip, uint16_t port = 9000);
- Configures a connectionless UDP socket connection.
- To let USMP manage your Wi-Fi, chain
.wifi("SSID", "Password").
Advanced: Receive Timeouts
Once a session is established, receives are bounded so maintain() can never block indefinitely on a stalled peer or a stray packet. The bounds are compile-time overridable via -D build flags (e.g. in platformio.ini build_flags):
USMP_UDP_RECV_TIMEOUT_MS(default50) — per-attempt UDP receive wait. The core retries up to ~10× per read, so the effective budget for an in-flight fragment is ~10× this value (~500 ms).USMP_TCP_RECV_TIMEOUT_MS(default2000) — TCP no-progress stall timeout; trips only when zero bytes arrive for this long mid-frame, so a large-but-flowing frame is never cut off.
Handshake receives are unbounded regardless — they must wait for the gateway's reply. Raise these on high-latency links; lower them for snappier failure detection.