Industrial IoT

CODESYS MQTT Client: SPS-Variablen an einen Broker veröffentlichen

Konfigurieren Sie die CODESYS IIoT MQTT Client Library, um SPS-Variablen als JSON zu veröffentlichen, prüfen Sie sie auf broker.connectmq.com und wechseln Sie dann zu einem privaten Broker mit Zugangsdaten und TLS.

CODESYS-Entwicklungsumgebung mit einem Structured-Text-Programm, das SPS-Variablen an einen Cloud-Broker veröffentlicht, als Darstellung von CODESYS MQTT
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

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

  1. Öffnen Sie den Bibliotheksverwalter Ihrer Applikation und wählen Sie Bibliothek hinzufügen.
  2. Suchen Sie nach MQTT Client SL und fügen Sie sie hinzu. Der Namensraum der Bibliothek ist MQTT.
  3. 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.
  4. Ü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:

  1. Erstellen Sie einen Broker im ConnectMQ-Portal und notieren Sie den generierten Benutzernamen, das Passwort und die Client-ID.
  2. Ö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.
  3. Setzen Sie uiPort := 8883, aktivieren Sie TLS am Client-Funktionsbaustein und referenzieren Sie den TLS-Kontext wie in der Bibliotheksdokumentation beschrieben.
  4. Setzen Sie sClientId := 'YOUR_CLIENT_ID' und übergeben Sie YOUR_USERNAME und YOUR_PASSWORD an die Zugangsdaten-Eingänge des Clients.
  5. Ä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, etwa acme/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

  1. 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.
  2. 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.
  3. Veröffentlicht nur einmal. xExecute wird nie zurückgesetzt; siehe das Handshake in Schritt 3.
  4. Payload abgeschnitten. Der STRING ist zu kurz, oder udiPayloadSize wurde aus einer anderen Variablen berechnet.
  5. 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.
  6. 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.

Verwandte Artikel

Industrial DataOps: Werksdaten kontextualisieren und steuern

Was Industrial DataOps in der Praxis bedeutet: Kontextualisierung, Normalisierung, Qualitätsprüfungen und Governance von OT-Daten und wie Sie diese Schicht auf einem MQTT-Namespace betreiben.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.