Mit der MQTT-Unterstützung von CODESYS wird jede CODESYS-basierte Steuerung, von der Hersteller-SPS bis zum Raspberry Pi mit CODESYS-Runtime, zu einem direkten Publisher von Anlagendaten. In diesem Tutorial fügen Sie einem Projekt die CODESYS IIoT MQTT Client Library hinzu, veröffentlichen SPS-Variablen mit Structured Text als JSON, prüfen sie auf einem öffentlichen Broker und sichern die Verbindung anschließend mit Zugangsdaten und TLS ab. Unterwegs lernen Sie die Fallstricke kennen, die typischerweise einen Inbetriebnahmetag kosten.
Warum sich CODESYS MQTT lohnt
CODESYS ist die Runtime hinter einem großen Teil der SPSen und Industriesteuerungen weltweit, vertrieben unter vielen Herstellermarken. Ein einziger Integrationsansatz deckt also viel Hardware ab. Das direkte Veröffentlichen aus der Steuerung hat klare Vorteile:
- Bei kleinen Installationen keine zusätzliche Gateway-Hardware oder -Software zu pflegen.
- Die Daten verlassen die Steuerung genau in dem Format und zu dem Zeitpunkt, den der SPS-Programmierer festlegt.
- Die Report-by-Exception-Logik liegt direkt beim Prozess, wo Totbänder und Zustände am besten verstanden werden.
Der Kompromiss: Der SPS-Programmierer verantwortet nun Netzwerkcode. Wenn Sie viele Steuerungen verschiedener Hersteller anbinden, vergleichen Sie diesen Ansatz vorab mit gatewaybasierten Designs unter SPS-Anbindung an die Cloud.
Voraussetzungen
| Element | Hinweise |
|---|---|
| CODESYS Development System V3.5 | Ein aktuelles Service Pack; das Paket IIoT Libraries SL über den CODESYS Installer installieren |
| Eine CODESYS-Runtime | Eine Hersteller-SPS, CODESYS Control Win zum Testen oder CODESYS Control for Raspberry Pi |
| Lizenz | IIoT Libraries SL ist ein lizenzpflichtiges Add-on; ohne Lizenz läuft es zeitlich begrenzt im Demo-Modus |
| Netzwerk | Ausgehend TCP 1883 zum Testen, TCP 8883 für TLS, und DNS auf der Steuerung konfiguriert |
| Test-Tools | mosquitto_sub oder ein beliebiger MQTT-Desktop-Client |
Die Bibliothek MQTT Client SL ist Teil des Pakets IIoT Libraries SL, zusammen mit JSON- und Web-Client-Bibliotheken. Die genauen Pin-Namen der Funktionsbausteine können sich zwischen Bibliotheksversionen leicht unterscheiden. Halten Sie daher beim Arbeiten die Bibliotheksdokumentation im Bibliotheksverwalter geöffnet.
Schritt 1: Die MQTT-Bibliothek hinzufügen
- Öffnen Sie den Bibliotheksverwalter Ihrer Applikation und wählen Sie Bibliothek hinzufügen.
- Suchen Sie nach MQTT Client SL und fügen Sie sie hinzu. Der Namensraum der Bibliothek ist
MQTT. - Wenn Sie JSON mit Hilfsfunktionen der Bibliothek erzeugen möchten, fügen Sie auch JSON Utilities SL hinzu. Dieses Tutorial baut das JSON von Hand, um die Abhängigkeiten minimal zu halten.
- Übersetzen Sie das Projekt einmal, um zu bestätigen, dass die Bibliothek fehlerfrei aufgelöst wird.
Schritt 2: Die Variablen deklarieren
Legen Sie ein Programm an, zum Beispiel PRG_Mqtt, das von einer Task mit einer Zykluszeit von 20 bis 100 ms aufgerufen wird. Netzwerk-Funktionsbausteine müssen in jedem Zyklus aufgerufen werden, damit ihre internen Zustandsautomaten voranschreiten.
PROGRAM PRG_Mqtt
VAR
// Prozesswerte (in einem echten Projekt stammen sie aus Ihrer Steuerungslogik)
rTemperature : REAL := 21.5;
rPressure : REAL := 1.82;
xPumpRunning : BOOL := TRUE;
// MQTT-Client und Publisher
mqttClient : MQTT.MQTTClient;
mqttPublish : MQTT.MQTTPublish;
sHost : STRING := 'broker.connectmq.com';
uiPort : UINT := 1883;
sClientId : STRING := 'codesys-demo-k8q2x7'; // darf nicht leer sein und muss eindeutig sein
wsTopic : WSTRING(255) := "connectmq/demo/k8q2x7/plant1/utilities/pumpstation1/telemetry";
sPayload : STRING(512);
tonPublish : TON;
xTrigger : BOOL;
rLastTemp : REAL;
xLastRunning : BOOL;
END_VAR
Zwei Details sind hier wichtig. Erstens darf die Client-ID nicht leer sein und muss eindeutig sein; zwei Steuerungen mit derselben ID werfen sich gegenseitig immer wieder vom Broker. Zweitens beträgt die Standardlänge eines STRING in CODESYS 80 Zeichen, was für die meisten JSON-Payloads zu kurz ist. Deklarieren Sie daher eine explizite Länge.
Schritt 3: Mit Structured Text verbinden und veröffentlichen
Das Programm aktiviert den Client, baut eine JSON-Payload auf und veröffentlicht entweder alle 10 Sekunden oder sofort, wenn sich die Temperatur um mehr als 0,5 Grad ändert oder der Pumpenzustand wechselt.
// 1. Den Client in jedem Zyklus laufen lassen
mqttClient(
xEnable := TRUE,
sHostname := sHost,
uiPort := uiPort,
eMQTTVersion := MQTT.MQTT_VERSION.V3_1_1,
sClientId := sClientId,
uiKeepAlive := 30
);
// 2. Entscheiden, wann veröffentlicht wird: periodischer Heartbeat oder Report by Exception
tonPublish(IN := NOT tonPublish.Q, PT := T#10S);
IF tonPublish.Q
OR ABS(rTemperature - rLastTemp) > 0.5
OR xPumpRunning <> xLastRunning THEN
xTrigger := TRUE;
END_IF
// 3. Die JSON-Payload aufbauen
IF xTrigger AND NOT mqttPublish.xBusy THEN
sPayload := CONCAT('{"temperature":', REAL_TO_STRING(rTemperature));
sPayload := CONCAT(sPayload, ',"pressure":');
sPayload := CONCAT(sPayload, REAL_TO_STRING(rPressure));
sPayload := CONCAT(sPayload, ',"pump_running":');
IF xPumpRunning THEN
sPayload := CONCAT(sPayload, 'true}');
ELSE
sPayload := CONCAT(sPayload, 'false}');
END_IF
rLastTemp := rTemperature;
xLastRunning := xPumpRunning;
END_IF
// 4. Bei steigender Flanke von xExecute veröffentlichen
mqttPublish(
xExecute := xTrigger AND mqttClient.xConnectedToBroker,
mqttClient := mqttClient,
wsTopicName := wsTopic,
pbPayload := ADR(sPayload),
udiPayloadSize := TO_UDINT(LEN(sPayload)),
eQoS := MQTT.QoS.AtLeastOnce,
xRetain := FALSE
);
IF mqttPublish.xDone OR mqttPublish.xError THEN
xTrigger := FALSE; // xExecute zurücksetzen, damit der nächste Trigger eine neue steigende Flanke erzeugt
END_IF
Merken Sie sich das Execute/Done-Handshake-Muster. MQTTPublish startet bei einer steigenden Flanke von xExecute und meldet einige Zyklen später xDone oder xError. Setzen Sie xExecute nie zurück, wird kein zweites Mal veröffentlicht. Setzen Sie es in jedem Zyklus, überfluten Sie den Broker.
Schritt 4: Auf dem öffentlichen MQTT-Broker prüfen
Laden Sie die Applikation, starten Sie sie und abonnieren Sie von einem PC aus:
mosquitto_sub -h broker.connectmq.com -p 1883 -i codesys-watch-k8q2x7 \
-t 'connectmq/demo/k8q2x7/#' -v
Sie sollten alle 10 Sekunden eine Nachricht sehen, plus zusätzliche Nachrichten, wenn Sie in der Online-Ansicht eine neue Temperatur schreiben oder xPumpRunning umschalten:
{"temperature":21.5,"pressure":1.82,"pump_running":true}
Der öffentliche MQTT-Broker ist ideal für diese Inbetriebnahmephase und für Prototypen, nicht aber für Produktivdaten: anonym, ohne Einrichtung und mit schnellem Feedback. Er ist für jeden lesbar, verwenden Sie also ein zufälliges Topic-Präfix und keine echten Prozessdaten. Außerdem begrenzt er jeden Client auf 10 Nachrichten pro Sekunde und 64 KB pro Nachricht, eine nützliche Leitplanke, während Sie Ihre Trigger abstimmen.
Schritt 5: Wechsel zu einem privaten Broker mit TLS
Für den Produktivbetrieb verbinden Sie sich mit Ihrem eigenen Broker mit Zugangsdaten und Verschlüsselung:
- Erstellen Sie einen Broker im ConnectMQ-Portal und notieren Sie den generierten Benutzernamen, das Passwort und die Client-ID.
- Öffnen Sie auf der Steuerung in CODESYS den Security Screen und importieren Sie die Root-CA des Broker-Zertifikats in den Speicher vertrauenswürdiger Zertifikate. Broker mit Let's-Encrypt-Zertifikaten führen auf ISRG Root X1 zurück.
- Setzen Sie
uiPort := 8883, aktivieren Sie TLS am Client-Funktionsbaustein und referenzieren Sie den TLS-Kontext wie in der Bibliotheksdokumentation beschrieben. - Setzen Sie
sClientId := 'YOUR_CLIENT_ID'und übergeben SieYOUR_USERNAMEundYOUR_PASSWORDan die Zugangsdaten-Eingänge des Clients. - Ändern Sie das Topic auf Ihre produktive Hierarchie, etwa
plant1/utilities/pumpstation1/telemetry. Bauen Sie diese Hierarchie entlang der ISA-95-Anlagenhierarchie (Enterprise → Site → Area → Line → Cell) auf, etwaacme/werk-stuttgart/versorgung/pumpstation-1/telemetry, dann wird die Steuerung direkt Teil eines Unified Namespace (UNS), den MES, SCADA und ERP abonnieren können.
Bei ConnectMQ sind Client-IDs an die ausgegebenen Zugangsdaten gebunden. Ein kopiertes Projekt auf einer zweiten Steuerung mit derselben ID wird daher abgewiesen, statt still die Sitzung zu übernehmen. Geben Sie jeder Steuerung eigene Zugangsdaten. Der Live-Topic-Explorer des Brokers zeigt Ihre Nachrichten, sobald der TLS-Handshake gelingt.
Wenn Sie Ihre Zeit nicht in Betrieb und Patchen eines eigenen Brokers stecken möchten, nimmt Ihnen ein verwalteter MQTT-Broker Zertifikate, Upgrades und Monitoring ab.
Fehlerbehebung bei CODESYS MQTT
- Client verbindet sich nie. Prüfen Sie DNS und das Standard-Gateway auf der Steuerung. Testen Sie mit einer IP-Adresse, um Probleme bei der Namensauflösung einzugrenzen.
- TLS-Handshake schlägt fehl. Das CA-Zertifikat fehlt im Vertrauensspeicher der Steuerung, oder die Uhr der Steuerung geht falsch und das Zertifikat erscheint noch nicht gültig. Konfigurieren Sie NTP.
- Veröffentlicht nur einmal.
xExecutewird nie zurückgesetzt; siehe das Handshake in Schritt 3. - Payload abgeschnitten. Der
STRINGist zu kurz, oderudiPayloadSizewurde aus einer anderen Variablen berechnet. - Verbindung bricht alle paar Sekunden ab. Ein anderes Gerät nutzt dieselbe Client-ID, oder der Task-Zyklus ist so langsam, dass Keep-Alive-Pakete zu spät kommen.
- Demo-Modus stoppt nach einer Weile. Die Lizenz für IIoT Libraries SL ist auf dem Zielgerät nicht aktiviert.
Checkliste für den Produktivbetrieb
- Eindeutige Client-ID und Zugangsdaten pro Steuerung.
- TLS auf Port 8883 mit vertrauenswürdiger CA und NTP-Zeitsynchronisation.
- Payload-Aufbau gegen String-Überlauf geschützt.
- Report by Exception plus periodischer Heartbeat.
- Ein Status-Topic mit Last Will, damit Konsumenten offline von untätig unterscheiden können.
- Topics folgen der ISA-95-Namenskonvention des Werks und damit der Struktur des UNS; Hintergründe dazu liefert Sparkplug B und Unified Namespace.
Beckhoff-Steuerungen nutzen für dieselbe Aufgabe eine andere Bibliothek; den Vergleich finden Sie unter Beckhoff TwinCAT MQTT, für das TIA Portal das Siemens-S7-MQTT-Tutorial. Für das größere Architekturbild beginnen Sie mit dem Leitfaden zu Industrial IoT mit MQTT.
Veröffentlichen Sie Ihre CODESYS-Daten an ConnectMQ
Wenn Ihre Steuerung bereit ist, den öffentlichen MQTT-Broker zu verlassen, geben Sie ihr einen sicheren MQTT-Broker in der Cloud. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte, und fügen Sie die generierten Zugangsdaten in Ihr CODESYS-Projekt ein.
Häufig gestellte Fragen
Ist die CODESYS-MQTT-Bibliothek kostenlos?
Die Bibliothek MQTT Client SL ist Teil des lizenzpflichtigen Pakets IIoT Libraries SL. Sie kann im Demo-Modus getestet werden, der nach begrenzter Laufzeit stoppt, bis eine Lizenz aktiviert ist.
Unterstützt CODESYS MQTT auch TLS?
Ja. Importieren Sie die Root-CA des Brokers über den Security Screen in den Zertifikatsspeicher der Steuerung, aktivieren Sie TLS am Client und verbinden Sie sich mit Port 8883.
Kann CODESYS auch MQTT-Topics abonnieren?
Ja, die Bibliothek enthält einen Funktionsbaustein zum Abonnieren. Validieren Sie jeden empfangenen Wert sorgfältig, bevor er die Steuerungslogik beeinflusst.
Welche MQTT-Version verwendet der CODESYS-Client?
Die Bibliothek unterstützt MQTT 3.1.1, neuere Versionen ergänzen MQTT 5; prüfen Sie die Dokumentation Ihrer installierten Version. Beginnen Sie für maximale Kompatibilität mit 3.1.1.



