MQTT / MQTTS
An MQTT client with TLS, automatic reconnection and subscriptions restored on their own. Built with IoT platforms in mind, but it works with any broker.
Install the library first — see Library. Text parameters are POINTER TO BYTE, passed with ADR().
The library at a glance
Section titled “The library at a glance”| File | nXPicoMQTT.compiled-library |
| Type | Precompiled library: no source, nothing to build |
| Exported functions | 8, listed below |
| Boards | nXPico W only |
| Requires | A configured WiFi link and, for any TLS, nXPicoX509: the trust anchor is stored only after the device identity has been generated |
Transport and authentication are two separate choices
Section titled “Transport and authentication are two separate choices”The transport is declared by the application, with the xTls argument of mqttConnect. The authentication depends on what is passed, plus what is stored on the device.
xTls | Transport | Requires |
|---|---|---|
TRUE | TLS, server verified by pinning | a trust anchor in flash, which in turn requires the device’s X.509 identity — otherwise mqttConnect returns 3 immediately |
FALSE | plain TCP | nothing |
| Credentials | Authentication |
|---|---|
pUser = token, pPass = '' | token as username — the ThingsBoard model |
pUser + pPass | username and password |
both '' | X.509 client certificate, if the device identity is in flash (mutual TLS) |
The port is just the TCP port. 0 gives the conventional one for the transport you chose: 8883 with TLS, 1883 in plain.
mqttSetTrustAnchor
Section titled “mqttSetTrustAnchor”Stores the certificate used to verify the broker. Asynchronous, once per device.
FUNCTION mqttSetTrustAnchor : DINTVAR_INPUT pPem : POINTER TO BYTE; (* server certificate, PEM *) udiLen : UDINT; (* length in bytes *)END_VAR| Return | Meaning |
|---|---|
10 | accepted, written to flash at the first opportunity |
2 | PEM missing, empty, longer than 2048 bytes or incomplete (no BEGIN/END delimiters) |
11 | a write is already in progress |
Check the outcome with mqttHasTrustAnchor(), not with the return value: the write is deferred. If the device identity is missing the function still returns 10: the refusal comes later, at write time, shows up only in the log (trust anchor RIFIUTATO: manca l'identita' X.509 del device), and mqttHasTrustAnchor() stays FALSE. Run x509GenerateDeviceCert first.
Requirements on the server certificate. PEM format with line breaks, and — if it is a self-signed certificate used as a root of trust — it must carry basicConstraints: CA:TRUE. A certificate without that extension is rejected during the handshake, even if other tools accept it.
mqttHasTrustAnchor
Section titled “mqttHasTrustAnchor”FUNCTION mqttHasTrustAnchor : BOOLmqttConnect
Section titled “mqttConnect”Requests a connection. Asynchronous: the internal state machine synchronises the clock, resolves the name, opens TLS and waits for CONNACK, retrying with growing back-off.
FUNCTION mqttConnect : DINTVAR_INPUT pHost : POINTER TO BYTE; (* hostname or IP address *) uiPort : UINT; (* 0 = 8883 with TLS, 1883 in plain *) pClientId : POINTER TO BYTE; pUser : POINTER TO BYTE; (* token or username; ADR('') for none *) pPass : POINTER TO BYTE; (* ADR('') when there is no password *) xTls : BOOL; (* TRUE = TLS, FALSE = plain TCP *)END_VARThe three ways to authenticate:
(* 1 — token as username *)diRes := mqttConnect(ADR(sHost), 1883, ADR(sId), ADR(sToken), ADR(''), FALSE);
(* 2 — username and password *)diRes := mqttConnect(ADR(sHost), 1883, ADR(sId), ADR(sUser), ADR(sPass), FALSE);
(* 3 — X.509 client certificate, over TLS *)diRes := mqttConnect(ADR(sHost), 8883, ADR(sId), ADR(''), ADR(''), TRUE);| Return | Meaning |
|---|---|
10 | request accepted |
2 | host missing or empty |
3 | xTls is TRUE but no trust anchor is stored |
Follow progress with mqttGetState().
mqttDisconnect
Section titled “mqttDisconnect”FUNCTION mqttDisconnect : DINTCloses the connection and stops retrying. Returns 0.
mqttGetState
Section titled “mqttGetState”FUNCTION mqttGetState : DINT| Return | Meaning |
|---|---|
0 | idle |
1 | connecting |
2 | connected |
-1 | name resolution failed |
-2 | network time unavailable (needed to validate certificates) |
-4 | TLS configuration failed (not enough memory, or invalid certificates) |
-5 | not enough memory to create the MQTT client |
-6 | connection refused |
-7 | handshake or CONNACK timed out |
-102 | broker: client identifier rejected |
-104 | broker: bad username or password |
-105 | broker: not authorised (wrong token, or device not enabled) |
-356 | connection dropped |
mqttPublish
Section titled “mqttPublish”Queues a message and returns immediately.
FUNCTION mqttPublish : DINTVAR_INPUT pTopic : POINTER TO BYTE; pPayload : POINTER TO BYTE; udiLen : UDINT; (* use LEN(payload) *) byQos : BYTE; (* 0 or 1 *) xRetain : BOOL;END_VAR| Return | Meaning |
|---|---|
0 | queued |
15 | topic ≥ 128 characters, or payload > 512 bytes |
17 | queue full: you are publishing faster than the network drains |
2 | topic missing or empty |
17 is not a fault — it is the mechanism that stops messages piling up without bound. Retry next cycle; if it persists, publish less often.
Limits: topic max 127 characters, payload max 512 bytes, queue of 3 messages.
mqttSubscribe
Section titled “mqttSubscribe”FUNCTION mqttSubscribe : DINTVAR_INPUT pTopic : POINTER TO BYTE; (* + and # wildcards allowed *) byQos : BYTE;END_VAR| Return | Meaning |
|---|---|
0 | registered |
17 | maximum of 4 subscriptions reached |
2 | topic missing or too long |
Call it once. The device restores its subscriptions itself on every reconnection — you do not need to redo them, and you do not need to notice the drops.
mqttGetMessage
Section titled “mqttGetMessage”Pulls one received message off the queue.
FUNCTION mqttGetMessage : DINTVAR_INPUT pTopic : POINTER TO BYTE; udiTopicSize : UDINT; pPayload : POINTER TO BYTE; udiPayloadSize : UDINT;END_VAR| Return | Meaning |
|---|---|
> 0 | length of the delivered payload |
0 | no message waiting |
-15 | buffers too small — the message is discarded |
-2 | invalid parameters |
The queue holds 3 messages and drops new ones when full — call this every cycle.
Commissioning order
Section titled “Commissioning order”- Generate the device identity —
x509GenerateDeviceCert. - Print it with
x509DumpDeviceCertand register it on the platform. - Store the broker certificate with
mqttSetTrustAnchor. mqttSubscribefor the topics you need — once.mqttConnectwithxTls := TRUEon port 8883, and watchmqttGetState()reach2.