Industrial IoT

Beckhoff TwinCAT MQTT: Strukturierte SPS-Daten an einen Broker senden

Nutzen Sie die IoT-Funktionen von TwinCAT 3, um strukturierte SPS-Daten als JSON zu veröffentlichen, prüfen Sie sie auf dem öffentlichen MQTT-Broker und verbinden Sie sich dann mit TLS, Zugangsdaten und Last Will mit einem privaten Broker.

Beckhoff-Industrie-PC mit TwinCAT 3, der Maschinendaten an einen Cloud-Broker veröffentlicht, als Darstellung von Beckhoff TwinCAT 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 Beckhoff TwinCAT veröffentlicht ein Beckhoff-Industrie-PC Maschinendaten direkt aus der SPS-Runtime, ohne separates Gateway im Schaltschrank. In diesem Tutorial nutzen Sie die IoT-Funktionen von TwinCAT 3, um sich mit einem MQTT-Broker zu verbinden, einen strukturierten Datentyp als JSON zu serialisieren, ihn bei Änderung und per Timer zu veröffentlichen und die Verbindung schließlich mit TLS und Zugangsdaten abzusichern. Dasselbe Muster skaliert vom einzelnen Prüfstand bis zur Maschinenflotte und passt gut zu Industrie-4.0-Projekten im Maschinenbau, wo Beckhoff-Steuerungen weit verbreitet sind.

TwinCAT-MQTT-Optionen im Vergleich

Beckhoff bietet mehr als einen Weg zu MQTT, und die richtige Wahl von Anfang an erspart Nacharbeit.

Option Was es ist Wer es konfiguriert Am besten für
TF6701 IoT Communication SPS-Bibliothek (Tc3_IotBase) mit einem MQTT-Client-Funktionsbaustein SPS-Programmierer in Structured Text Volle Kontrolle über Topics, Payloads und Timing
TF6720 IoT Data Agent Konfigurationsbasiertes Gateway, das ADS-Symbole auf MQTT abbildet Konfigurator-GUI, kein SPS-Code Vorhandene Symbole veröffentlichen, ohne das SPS-Programm zu ändern
Externes ADS-Gateway Eigener Dienst, der Symbole per ADS liest und per MQTT veröffentlicht Softwareteam Individuelle Pipelines, viele Steuerungen, nicht standardisierte Formate

Dieses Tutorial nutzt TF6701, weil es die häufigste Wahl für Maschinenbauer ist, die das MQTT-Verhalten als Teil des versionierten SPS-Projekts haben möchten. TF6701 und TF6720 sind lizenzpflichtige TwinCAT-Functions; eine 7-Tage-Testlizenz reicht zum Mitmachen aus.

Voraussetzungen

  • TwinCAT 3.1 XAE (Visual Studio oder TwinCAT XAE Shell) und ein Zielsystem: ein Beckhoff-IPC oder Ihr Engineering-PC im Run-Modus zum Testen.
  • Die Function TF6701 auf dem Zielsystem installiert und eine Test- oder Volllizenz aktiviert.
  • Ausgehender Netzwerkzugang vom Zielsystem zum Broker auf TCP 1883 zum Testen und 8883 für TLS.
  • Die SPS-Bibliotheken Tc3_IotBase und Tc3_JsonXml in den Projektreferenzen.
  • Mosquitto-Clients auf einem PC zur Überprüfung.

Schritt 1: Einen strukturierten Datentyp definieren

Eine Struktur statt loser Variablen zu veröffentlichen, hält zusammengehörige Werte beisammen und die Zeitstempel konsistent. Fügen Sie einen DUT hinzu:

TYPE ST_PressData :
STRUCT
    rForce_kN       : REAL;
    rTemperature_C  : REAL;
    nCycleCount     : UDINT;
    bRunning        : BOOL;
    sState          : STRING(20);
END_STRUCT
END_TYPE

Schritt 2: Mit FB_IotMqttClient verbinden

FB_IotMqttClient aus Tc3_IotBase wird über Properties konfiguriert und durch den Aufruf seiner Methode Execute in jedem Zyklus betrieben. Rufen Sie ihn aus einer Task mit einem Zyklus von 10 ms oder schneller auf; der Client erledigt seine Kommunikation im Hintergrund, kommt aber nur voran, wenn Execute aufgerufen wird.

PROGRAM MAIN
VAR
    fbMqttClient   : FB_IotMqttClient;
    bSetParameter  : BOOL := TRUE;
    bConnect       : BOOL := TRUE;

    fbJson         : FB_JsonSaxWriter;
    stPress        : ST_PressData;
    stLastPress    : ST_PressData;

    sTopicData     : STRING(255) := 'connectmq/demo/t3w9p1/plant1/stamping/cell4/press1/telemetry';
    sPayload       : STRING(1023);
    fbHeartbeat    : TON;
    bPublish       : BOOL;
END_VAR

// --- Einmalige Client-Konfiguration ---
IF bSetParameter THEN
    bSetParameter := FALSE;
    fbMqttClient.sHostName  := 'broker.connectmq.com';
    fbMqttClient.nHostPort  := 1883;
    fbMqttClient.sClientId  := 'twincat-demo-t3w9p1';   // nicht leer und eindeutig
    fbMqttClient.nKeepAlive := 30;
END_IF

// --- Verbindung in jedem Zyklus aufrechterhalten ---
fbMqttClient.Execute(bConnect);

// --- Entscheiden, wann veröffentlicht wird: bei Änderung oder alle 10 s ---
fbHeartbeat(IN := NOT fbHeartbeat.Q, PT := T#10S);
bPublish := fbHeartbeat.Q
            OR ABS(stPress.rForce_kN - stLastPress.rForce_kN) > 1.0
            OR stPress.bRunning <> stLastPress.bRunning
            OR stPress.sState <> stLastPress.sState;

// --- Serialisieren und veröffentlichen ---
IF bPublish AND fbMqttClient.bConnected THEN
    fbJson.ResetDocument();
    fbJson.StartObject();
    fbJson.AddKey('force_kN');       fbJson.AddReal(stPress.rForce_kN);
    fbJson.AddKey('temperature_C');  fbJson.AddReal(stPress.rTemperature_C);
    fbJson.AddKey('cycle_count');    fbJson.AddUdint(stPress.nCycleCount);
    fbJson.AddKey('running');        fbJson.AddBool(stPress.bRunning);
    fbJson.AddKey('state');          fbJson.AddString(stPress.sState);
    fbJson.EndObject();
    fbJson.CopyDocument(sPayload, SIZEOF(sPayload));

    fbMqttClient.Publish(
        sTopic       := sTopicData,
        pPayload     := ADR(sPayload),
        nPayloadSize := LEN(sPayload),
        eQoS         := TcIotMqttQos.AtLeastOnceDelivery,
        bRetain      := FALSE,
        bQueue       := FALSE);

    stLastPress := stPress;
END_IF

Einige Anmerkungen zu den obigen Entscheidungen:

  • CopyDocument statt GetDocument. GetDocument liefert einen Standard-String mit 255 Zeichen, der größere Payloads stillschweigend abschneidet. Das Kopieren in einen ausreichend großen Puffer vermeidet das.
  • Report by Exception. Das Totband für die Kraft und die Zustandsvergleiche veröffentlichen echte Änderungen sofort, während der 10-Sekunden-Heartbeat belegt, dass die Maschine lebt, auch wenn sich nichts ändert.
  • Fehlerbehandlung. Beobachten Sie während der Inbetriebnahme fbMqttClient.hrErrorCode und fbMqttClient.eConnectionState in der Online-Ansicht. Die meisten Fehler zeigen sich dort zuerst.

Für größere Strukturen bietet Tc3_JsonXml auch eine Hilfsfunktion, die einen ganzen Datentyp einschließlich Attributen wie Einheiten in einem Aufruf serialisiert. Handgeschriebene SAX-Ausgabe wie oben gibt Ihnen exakte Kontrolle über die Schlüsselnamen, was wichtig ist, wenn andere Teams die Daten nutzen.

Schritt 3: Auf dem öffentlichen MQTT-Broker prüfen

Aktivieren Sie die Konfiguration, starten Sie die SPS und abonnieren Sie von einem PC aus:

mosquitto_sub -h broker.connectmq.com -p 1883 -i twincat-watch-t3w9p1 \
  -t 'connectmq/demo/t3w9p1/#' -v

Erwartete Ausgabe:

connectmq/demo/t3w9p1/plant1/stamping/cell4/press1/telemetry {"force_kN":412.5,"temperature_C":38.2,"cycle_count":10233,"running":true,"state":"AUTO"}

Forcen Sie einen Wert in der Online-Ansicht, und die Änderung erscheint sofort. Der anonyme öffentliche MQTT-Broker unter broker.connectmq.com ist perfekt für diese Art der Inbetriebnahme, aber er ist öffentlich und nicht für Produktionsdaten gedacht. Verwenden Sie also ein zufälliges Topic-Präfix und nichts Vertrauliches.

Schritt 4: Die Beckhoff-TwinCAT-MQTT-Verbindung absichern

Produktive Maschinen sollten niemals über unverschlüsseltes TCP ins Internet veröffentlichen. Erstellen Sie einen privaten Broker im Portal von ConnectMQ, notieren Sie den generierten Benutzernamen, das Passwort und die Client-ID und gehen Sie dann so vor:

  1. Laden Sie das Zertifikat ISRG Root X1 herunter (die Wurzel von Let's Encrypt, das der ConnectMQ-Broker verwendet) und kopieren Sie es auf das Zielsystem, zum Beispiel in einen Ordner Certificates unter dem TwinCAT-Boot- oder Config-Verzeichnis.
  2. Erweitern Sie die einmalige Konfiguration:
fbMqttClient.sHostName     := 'YOUR_BROKER_HOST';
fbMqttClient.nHostPort     := 8883;
fbMqttClient.sClientId     := 'YOUR_CLIENT_ID';
fbMqttClient.sUserName     := 'YOUR_USERNAME';
fbMqttClient.sUserPassword := 'YOUR_PASSWORD';
fbMqttClient.stTLS.sCA     := 'C:\TwinCAT\3.1\Config\Certificates\isrgrootx1.pem';
  1. Konfigurieren Sie einen Last Will über die Will-Struktur des Clients, zum Beispiel eine Retained-Nachricht offline auf plant1/stamping/cell4/press1/status, und veröffentlichen Sie nach dem Verbinden ein Retained-online auf demselben Topic. Konsumenten können dann eine gestoppte Maschine von einer verlorenen Verbindung unterscheiden.
  2. Entfernen Sie das Demo-Präfix und verwenden Sie die ISA-95-Topic-Hierarchie Ihres Werks, also die Struktur Ihres Unified Namespace (UNS). Aus plant1/stamping/cell4/press1 wird dann etwa acme/werk-stuttgart/presswerk/linie-1/zelle-4/presse-1, entsprechend den ISA-95-Ebenen Enterprise → Site → Area → Line → Cell.

Halten Sie Zugangsdaten aus der Versionsverwaltung heraus: Laden Sie sie aus einer Datei auf dem Zielsystem oder aus einer bei der Inbetriebnahme gesetzten persistenten Variablen, statt sie in einem Projekt fest zu codieren, das weitergegeben wird.

Topics für eine Maschinenflotte entwerfen

Maschinenbauer liefern oft dasselbe TwinCAT-Projekt an Dutzende Kunden aus, sodass fest codierte Topics schnell zum Wartungsproblem werden. Einige Gewohnheiten helfen:

  • Das Topic-Präfix parametrierbar machen. Speichern Sie Namen für Unternehmen, Standort, Bereich, Linie und Maschine in persistenten Variablen, die bei der Inbetriebnahme gesetzt werden, und bauen Sie den Topic-String beim Start zusammen.
  • Daten, Status und Ereignisse trennen. Verwenden Sie .../telemetry für periodische Werte, .../status für Retained-Online- und Zustandsinformationen und .../events für Alarme oder Chargenabschlüsse. Konsumenten abonnieren nur, was sie brauchen.
  • Die Payload versionieren. Ein Schlüssel "schema": 1 kostet ein paar Bytes und erlaubt nachgelagertem Code, mit einem Firmware-Update umzugehen, das Felder hinzufügt oder umbenennt.
  • Payloads klein halten. Veröffentlichen Sie die Werte, die tatsächlich genutzt werden. Diagnose-Dumps können auf ein separates Topic auf Abruf.

Diese Konventionen machen die Daten auch leicht durchsuchbar: Ein Broker, der Pfade im ISA-95-Stil erkennt, kann jede Maschine eines Standorts ohne zusätzliche Konfiguration in einem Baum nach Standort und Linie darstellen. Liefern alle Maschinen eines Werks so in den UNS, finden MES, OEE-Auswertung und Energiemonitoring die Daten am selben Ort, unabhängig davon, ob sie von einer Beckhoff-, Siemens- oder CODESYS-Steuerung stammen. Hintergründe liefert der Beitrag zu Sparkplug B und Unified Namespace.

Checkliste für die Inbetriebnahme

Prüfpunkt Warum es wichtig ist
Uhr des Zielsystems per NTP synchronisiert TLS lehnt Zertifikate ab, wenn die Uhr stark abweicht
DNS auf dem IPC konfiguriert Der Hostname des Brokers muss auflösbar sein
Eindeutige Client-ID pro Maschine Duplikate trennen sich gegenseitig immer wieder
Payload-Puffer für das größte JSON dimensioniert Verhindert stillschweigendes Abschneiden
Heartbeat plus Report by Exception Wenig Verkehr mit Lebenszeichen
Retained-Status-Topic mit Last Will Zuverlässige Online- und Offline-Erkennung
Lizenz für TF6701 aktiviert Die Testlizenz läuft nach 7 Tagen ab

Fehlerbehebung

  • hrErrorCode zeigt eine abgelehnte Verbindung. Falsche Zugangsdaten oder Client-ID; bei Brokern, die Client-IDs an Zugangsdaten binden, müssen beide mit den ausgegebenen Werten übereinstimmen.
  • TLS-Fehler nach einem Neustart. Der Zertifikatspfad auf dem Zielsystem ist falsch, oder die CA-Datei wurde nicht mit dem Boot-Projekt kopiert.
  • Trotz bConnected wird nichts veröffentlicht. bPublish wird nie wahr, oder Publish wird aufgerufen, bevor die Payload aufgebaut ist.
  • Nachrichten kommen stoßweise an. bQueue := TRUE bei langsamer Aufrufrate von Execute; rufen Sie Execute in jedem Zyklus aus einer schnellen Task auf.

Wo das hineinpasst

Das Veröffentlichen vom IPC ist eine von mehreren Architekturen, um Maschinendaten herauszuholen; vergleichen Sie sie mit gateway- und SCADA-basierten Designs unter SPS-Anbindung an die Cloud. Wenn Sie mit gemischten Steuerungsmarken arbeiten, nutzt das CODESYS-MQTT-Tutorial ein sehr ähnliches Execute-und-Publish-Muster. Und wenn viele Maschinen in eine Hierarchie veröffentlichen, erklärt der Leitfaden zu Industrial IoT mit MQTT, wie Sie sie als UNS modellieren, den jede Anwendung über den MQTT-Broker nutzen kann.

Verbinden Sie Ihre Beckhoff-Maschinen mit ConnectMQ

Einen eigenen Broker neben jeder Maschine zu betreiben, bedeutet Zertifikate, Updates und Monitoring für jeden Standort. Ein verwalteter MQTT-Broker nimmt Ihnen diese Arbeit ab. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte, und sehen Sie Ihre TwinCAT-Daten innerhalb weniger Minuten im Live-Topic-Explorer eintreffen.

Häufig gestellte Fragen

Welche TwinCAT-Lizenz benötige ich für MQTT?

Der Ansatz über die SPS-Bibliothek erfordert TF6701 TwinCAT 3 IoT Communication. Die konfigurationsbasierte Alternative ist TF6720 IoT Data Agent. Für beide gibt es eine 7-Tage-Testlizenz.

Unterstützt TwinCAT MQTT auch TLS?

Ja. Setzen Sie den Pfad zum CA-Zertifikat in der TLS-Struktur des Clients, verbinden Sie sich mit Port 8883 und ergänzen Sie die Zugangsdaten. Client-Zertifikate werden ebenfalls unterstützt, falls Ihr Broker sie verlangt.

Kann TwinCAT MQTT-Topics abonnieren?

Ja. FB_IotMqttClient unterstützt Abonnements mit einer Nachrichtenwarteschlange, die Sie in der SPS auslesen. Validieren Sie jeden empfangenen Wert, bevor er die Steuerungslogik berührt.

Warum wird meine JSON-Payload nach 255 Zeichen abgeschnitten?

GetDocument liefert einen String mit Standardlänge. Verwenden Sie CopyDocument in einen größeren Puffer, wie oben gezeigt.

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.