Modbus TCP ohne PLC testen: drei Wege
· Von Vladimir Chemeris, Entwickler von Modbus TCP FieldKit
Kurzantwort: Auf dem Laptop starten Sie einen pymodbus-Server mit dem Skript unten. Für einen Test quer durch den Raum oder ohne Laptop starten Sie den FieldKit-Server auf einem iPhone oder iPad und verbinden Ihren Client. Testen Sie danach am echten Gerät, bevor Sie abnehmen, denn ein Simulator bildet dessen Eigenheiten nicht nach.
Weg 1: Ein Python-Server auf Ihrem Laptop
Dieses Skript lief wie gezeigt am 30. Oktober 2026 mit pymodbus 3.16.1 und Python 3.13 unter Linux. Es nutzt die Klassen SimData und SimDevice, die neuere API, die ModbusSequentialDataBlock ersetzt, das pymodbus als veraltet (deprecated) markiert.
python3 -m venv venv
venv/bin/pip install pymodbus
"""A Modbus TCP test server on port 1502."""
import asyncio
from pymodbus.server import ModbusTcpServer
from pymodbus.simulator import DataType, SimData, SimDevice
device = SimDevice(1, simdata=[
SimData(0, values=[100, 250, 1024], datatype=DataType.REGISTERS),
SimData(10, values=[0x42F6, 0xE979, 0xE979, 0x42F6], datatype=DataType.REGISTERS),
])
async def main():
server = ModbusTcpServer(context=[device], address=("0.0.0.0", 1502))
await server.serve_forever()
asyncio.run(main())
Es stellt Unit 1 mit den Holding-Registern 100, 250 und 1024 an Adresse 0 bereit, dazu den Float 123.456 an Adresse 10 in ABCD und an Adresse 12 in CDAB.
Um die Raw-Frames zu sehen, sendet dieser Client eine Anfrage und gibt beide Richtungen aus:
"""Sends one raw Modbus TCP request: read.py HOST UNIT PDU_HEX"""
import socket, struct, sys
host, unit, pdu = sys.argv[1], int(sys.argv[2]), bytes.fromhex(sys.argv[3])
frame = struct.pack(">HHHB", 1, 0, len(pdu) + 1, unit) + pdu
with socket.create_connection((host, 1502), timeout=2) as s:
s.sendall(frame)
print("TX", frame.hex(" ").upper())
print("RX", s.recv(260).hex(" ").upper())
$ python read.py 127.0.0.1 1 0300000003
TX 00 01 00 00 00 06 01 03 00 00 00 03
RX 00 01 00 00 00 09 01 03 06 00 64 00 FA 04 00
Vorsicht, gemeinsamer Speicher. Bei diesem Aufbau lesen alle vier Bereiche dieselben Register. Ein Coil-Read von Adresse 0 lieferte 64, das niedrige Byte von 100, und ein Read von Eingangsregistern lieferte ebenfalls 100. Ein Client, der versehentlich 04 verwendet, bekommt dennoch eine gut aussehende Antwort, daher fängt dieser Aufbau einen falschen Function Code nicht ab. pymodbus kann die vier Bereiche getrennt halten, wenn Sie simdata vier Listen von Blöcken übergeben, eine je Bereich.
Öffnen Sie die Firewall, wenn ein Client auf einem anderen Rechner verbindet: Erlauben Sie TCP 1502 auf dem Laptop.
Weg 2: FieldKit auf einem iPhone oder iPad
Öffnen Sie Server, behalten Sie Port 1502 bei und tippen Sie auf Starten. Richten Sie Ihren Client im selben Wi-Fi-Netzwerk auf die Adresse auf dem Bildschirm. Sie können Coils und Holding-Register auf dem Bildschirm bearbeiten, und Schreibzugriffe Ihres Clients erscheinen etwa zweimal pro Sekunde in der Register-Map.
Das eignet sich für einen Test vor Ort, wenn Sie ohne Laptop eine SCADA-Verbindung oder einen HMI-Bildschirm prüfen oder Schreibzugriffe live eintreffen sehen wollen. Planen Sie zwei Grenzen ein: Der Server läuft im Vordergrund, die App muss also geöffnet bleiben, und er lauscht standardmäßig auf 1502, weil 502 unter iOS nicht garantiert ist. Der eigene Client von FieldKit verbindet sich von einem zweiten Gerät aus mit ihm.
Weg 3: Ein dedizierter Simulator
Windows- und Linux-Anwender greifen oft zu einem eigenständigen Simulator. Modbus Slave von Witte Software ist neben Modbus Poll die kommerzielle Option unter Windows. proconX veröffentlicht ein Kommandozeilentool namens diagslave. Wir haben diese für diesen Artikel nicht getestet, prüfen Sie also die aktuellen Versionen und Lizenzen auf den Seiten der Hersteller.
Die drei im Vergleich
| Python-Server | FieldKit-Server | Dedizierter Simulator | |
|---|---|---|---|
| Braucht einen Laptop | Ja | Nein | Ja |
| Per Skript steuerbar | Ja | Nein | Unterschiedlich |
| Werte live bearbeiten | Im Code | Auf dem Bildschirm | Unterschiedlich |
| Port 502 | Mit erhöhten Rechten | Nicht garantiert | Unterschiedlich |
| Läuft unbeaufsichtigt | Ja | Nein, nur im Vordergrund | Ja |
Was ein Simulator Ihnen nicht zeigt
Wir haben fehlerhafte Anfragen an pymodbus gesendet, und es antwortete in mehreren Fällen anders als die Spezifikation. Die Tabelle finden Sie hier. Ein Client, den Sie nur gegen einen Simulator getestet haben, kann an einem echten Gerät scheitern. Ebenfalls fehlen serielles Timing, Verbindungslimits und die eigenwilligen Register-Maps echter Geräte. Schließen Sie mit dem echten Gerät ab, und beginnen Sie mit Lesezugriffen.
Quellen
- pymodbus-Dokumentation (BSD-3-Clause, getestet mit Version 3.16.1)
- Lokale Tests am 30. Oktober 2026 unter Linux
FAQ
Wie komme ich am schnellsten an einen Modbus-TCP-Server zum Testen?
Installieren Sie auf einem Laptop pymodbus mit pip und starten Sie das 12-Zeilen-Skript aus diesem Artikel. Es lauscht auf Port 1502 und stellt drei Holding-Register und einen Float in zwei Wortreihenfolgen bereit.
Warum Port 1502 statt 502?
Unter Linux und macOS erfordern Ports unter 1024 erhöhte Rechte. Port 1502 läuft ohne sie. Viele Clients lassen den Port einstellen, und für einen Test braucht es nicht mehr.
Verhält sich ein Simulator wie ein echtes Gerät?
Nur zum Teil. Ein Simulator zeigt die Protokollgrundlagen, aber sein Fehlerverhalten und Timing unterscheiden sich von echten Geräten, testen Sie also vor der Abnahme am echten Gerät.