Skip to main content

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.

ItemValue
opc_typeMODBUS_RTU
Implementation classplantpulse.driver.protocol.modbus.ModbusRTUDriver
LibraryOwn native implementation (ModbusRtuOverTcp in plantpulse-plc-protocol)
InheritanceAbstractNativeModbusDriver (not PLC4j)
read
write✅ (coil / holding-register)
SecurityNone (inherent to the Modbus standard)
Not direct serial — a serial-to-TCP converter is required

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

FieldMeaningDefault
opc_agent_ipSerial-to-TCP converter IP192.168.0.60
opc_agent_portConverter TCP portConverter setting (e.g. 502 / 4001)
options.unit-id (alias unit-identifier)Modbus slave ID (1..247)1
options.request-timeoutResponse timeout (ms)5000

Serial parameters such as baud-rate / parity / stop-bits are 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):

NotationMeaning
coil:1FC 01 — Read Coils
discrete-input:1FC 02 — Read Discrete Inputs
holding-register:1FC 03 — Read Holding Registers (signed 16)
holding-register:1:UINTunsigned 16
holding-register:1:DINTsigned 32 (2 registers, MSWord-first)
holding-register:1:REAL32-bit float (2 registers)
holding-register:100:STRING[10]10-word ASCII
input-register:1FC 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-register are 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 + the modbus package in plantpulse-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.