examples/Modbus PLC Simulator/README.md
This project exercises Serial Studio's Modbus TCP/RTU support with a physics-based hydraulic test stand simulator. The simulator acts as a Modbus TCP server and produces realistic industrial telemetry, with automatic failure modes and recovery sequences.
It's a good demo of Serial Studio's Pro Modbus protocol support: real-time data acquisition, custom frame parsing, and an industrial dashboard.
Modbus support needs a Serial Studio Pro license. See serial-studio.com for details.
The simulator models a 50HP hydraulic power unit.
The simulator cycles through realistic test sequences:
The simulator exposes 9 holding registers (function code 0x03) starting at address 0.
| Address | Name | Range | Units | Description |
|---|---|---|---|---|
| HR[0] | E-Stop | 0-1 | Emergency stop status (0 = normal, 1 = e-stop) | |
| HR[1] | Start LED | 0-1 | Motor running indicator (0 = off, 1 = running) | |
| HR[2] | Temperature | 72-180 | °F | Hydraulic oil temperature |
| HR[3] | Pressure | 0-3000 | PSI | System pressure (alarm at 2800 PSI) |
| HR[4] | Motor RPM | 0-3600 | RPM | Motor speed |
| HR[5] | Valve Position | 0-100 | % | Control valve opening percentage |
| HR[6] | Flow Rate | 0-500 | GPM × 10 | Pump flow rate (divide by 10) |
| HR[7] | Motor Load | 0-100 | % | Motor load percentage |
| HR[8] | Vibration | 0-150 | mm/s × 10 | Vibration velocity RMS (divide by 10) |
pip install pymodbus
The simulator supports pymodbus 3.x and 4.x automatically.
Run the Python script to start the Modbus TCP server:
python3 plc_simulator.py
Expected output:
========================================================================
HYDRAULIC TEST STAND SIMULATOR
========================================================================
Server: 0.0.0.0:5020 | Update: 50ms (20Hz)
Registers (FC03 Holding):
0:E-Stop 1:Start 2:Temp(°F) 3:PSI 4:RPM 5:Valve(%)
6:GPM(÷10) 7:Load(%) 8:Vibration(÷10 mm/s)
Phases: STARTUP -> RUNNING -> PRESSURE_TEST -> (FAILURE -> SHUTDOWN)
Flags: E=E-Stop A=Alarm(>2800PSI) F=Failure
========================================================================
10:30:00 [STARTUP ] - R: 0 P: 14 F: 0.0 L: 0 V:0.1 T: 72
10:30:01 [STARTUP ] - R: 180 P: 110 F: 4.8 L:17 V:1.8 T: 72
...
Modbus PLC Simulator.ssproj.Modbus.Modbus TCP.127.0.0.1 (or the IP address of the machine running the simulator).5020.1.Holding Registers (0x03).0.9.100 ms (recommended).The included project file (Modbus PLC Simulator.ssproj) provides:
The included modbus_plc_simulator.csv file defines the register map in a format that Serial Studio's Modbus Map Importer can read directly. That means you can auto-generate a project file from a register map definition instead of configuring registers manually.
CSV columns: address, name, type, dataType, units, min, max, scale, offset, description.
To import:
modbus_plc_simulator.csv.Serial Studio's Modbus Map Importer auto-generates a Lua frame parser based on the register map. The parser embedded in this project:
[slaveAddr, funcCode, byteCount, ...data]).The simulator includes realistic failure sequences that happen randomly (~0.02% probability per update):
To force a failure for testing, change the FAILURE_PROBABILITY constant in plc_simulator.py (set to 0.1 for ~10% chance).
SERVER_PORT).Serial Studio supports multi-group mode for polling non-contiguous register ranges. To poll specific registers:
This simulator can double as a template for connecting to real industrial PLCs:
Problem: Serial Studio shows "Connection Failed".
python3 plc_simulator.py).Problem: No data updates in Serial Studio.
Problem: Erratic readings or NaN values.
This example is dual-licensed under GPL-3.0 and the Serial Studio Commercial License.
For more about Serial Studio and Modbus integration, see the Serial Studio documentation.