Modbus RTU Driver (RTU-over-TCP)
Overview
Modbus RTU — a Modbus variant that runs over RS-485 / RS-232 serial links. Natively rewritten in 2026-07 — the old delegation to Apache PLC4j modbus-rtu has been removed. It now uses the native RTU-over-TCP implementation in plantpulse-plc-protocol (ModbusRtuOverTcp). Serial RTU devices are exposed through a serial-to-TCP converter and registered as host:port — the driver handles TCP sockets only.
| Item | Value |
|---|---|
opc_type | MODBUS_RTU |
| Implementation class | plantpulse.driver.protocol.modbus.ModbusRTUDriver |
| Library | Own native implementation (ModbusRtuOverTcp in plantpulse-plc-protocol) |
| Inheritance | AbstractNativeModbusDriver (not PLC4j) |
| read | ✅ |
| write | ✅ (coil / holding-register) |
| Security | None (inherent to the Modbus standard) |
The native driver handles TCP sockets only. Expose RS-485/232 devices through a serial-to-TCP converter (e.g. USR-TCP232, Moxa NPort) and register that converter's IP:port as opc_agent_ip / opc_agent_port. Serial parameters such as baud rate, parity, and stop bits are configured on the converter side; the driver does not use them.
Class Structure
AbstractNativeModbusDriver (주소 파싱 · 디코드 · read/write 공통)
└── ModbusRTUDriver — createClient() = new ModbusRtuOverTcp(unitId, host, port)
└── ModbusTCPDriver — createClient() = new ModbusTcp(unitId, host, port)
RTU framing (slave address + PDU + CRC-16 LE) is handled by ModbusRtuOverTcp on top of the TCP stream.
OPC Registration Options
| Field | Meaning | Default |
|---|---|---|
opc_agent_ip | Serial-to-TCP converter IP | 192.168.0.60 |
opc_agent_port | Converter TCP port | Converter setting (e.g. 502 / 4001) |
options.unit-id (alias unit-identifier) | Modbus slave ID (1..247) | 1 |
options.request-timeout | Response timeout (ms) | 5000 |
Serial parameters such as
baud-rate/parity/stop-bitsare configured on the converter side — the driver does not accept them.
Tag plc_address Format
Identical to Modbus TCP — <area>:<address>[:<datatype>][[<count>]] (PLC4X modbus4x syntax preserved, 1-based):
| Notation | Meaning |
|---|---|
coil:1 | FC 01 — Read Coils |
discrete-input:1 | FC 02 — Read Discrete Inputs |
holding-register:1 | FC 03 — Read Holding Registers (signed 16) |
holding-register:1:UINT | unsigned 16 |
holding-register:1:DINT | signed 32 (2 registers, MSWord-first) |
holding-register:1:REAL | 32-bit float (2 registers) |
holding-register:100:STRING[10] | 10-word ASCII |
input-register:1 | FC 04 — Read Input Registers |
Detailed notation rules and the data_type · format mapping are the same as on the Modbus TCP driver page.
Write (Native)
coil:N→ single coil write (Boolean).holding-register:N[:TYPE]→ register write per datatype (REAL/DINT= MSWord-first, 2 registers; otherwise a single 16-bit register).discrete-input/input-registerare read-only.
Unsupported Areas
- Direct serial port (
/dev/ttyUSB0) — not supported. A serial-to-TCP converter is required. - Multi-master / token-passing — single master only.
- Modbus ASCII (colon-delimited, LRC checksum) — RTU framing only.
References
- Modbus over Serial Line (V1.02) — Modbus-IDA.
- Code:
plantpulse-edge-driver/src/plantpulse/driver/protocol/modbus/ModbusRTUDriver.java+ themodbuspackage inplantpulse-plc-protocol. - Operations: use a serial-to-TCP converter rather than a USB ↔ RS-485 adapter, and verify the 120 Ω termination resistor. An incorrect unit-id or baud rate results in nothing but timeouts.