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:
CopyDocumentstattGetDocument.GetDocumentliefert 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.hrErrorCodeundfbMqttClient.eConnectionStatein 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:
- 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
Certificatesunter dem TwinCAT-Boot- oder Config-Verzeichnis. - 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';
- Konfigurieren Sie einen Last Will über die Will-Struktur des Clients, zum Beispiel eine Retained-Nachricht
offlineaufplant1/stamping/cell4/press1/status, und veröffentlichen Sie nach dem Verbinden ein Retained-onlineauf demselben Topic. Konsumenten können dann eine gestoppte Maschine von einer verlorenen Verbindung unterscheiden. - 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/press1wird dann etwaacme/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
.../telemetryfür periodische Werte,.../statusfür Retained-Online- und Zustandsinformationen und.../eventsfür Alarme oder Chargenabschlüsse. Konsumenten abonnieren nur, was sie brauchen. - Die Payload versionieren. Ein Schlüssel
"schema": 1kostet 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
hrErrorCodezeigt 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
bConnectedwird nichts veröffentlicht.bPublishwird nie wahr, oderPublishwird aufgerufen, bevor die Payload aufgebaut ist. - Nachrichten kommen stoßweise an.
bQueue := TRUEbei langsamer Aufrufrate vonExecute; rufen SieExecutein 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.



