hotloop
GitHub

Integrations Modbus TCP/RTU

Modbus TCP/RTU

Verified live

The 1979 workhorse. PLCs, VFDs, power meters, RTUs, and the fallback of every gateway that has nothing better.

Verified against A real Modbus server, run in-process, over TCP

All four word orders are supported, under the names vendor manuals print: ABCD, CDAB, BADC, and DCBA. Set a device default with byteOrder and override it per tag with the fourth address field.

Addressing is raw and zero-based. If your drawings use the traditional 40001-style numbering, set oneBased to true and write the numbers from the drawings. Getting this wrong by one is the oldest Modbus bug there is.

Reads are merged into blocks, so adjacent and near-adjacent registers become one request. maxGap controls how many unused registers are worth reading to avoid a second round trip (default 8), and maxBlock caps a single request (default 120, protocol ceiling 125).

Writing a single bit of a holding register is a read-modify-write, because Modbus has no atomic bit-set there. The other fifteen bits are preserved.

Addressing

AddressMeans
holding:100:float32:CDABA float across registers 100 and 101, word-swapped.
holding:40:bit3Bit 3 of register 40.
holding:200:string1616 characters from register 200.
input:12:int16A signed input register.
coil:5A single coil.
The trap

Word order is the setting people get wrong, and a float read with the wrong order is not obviously wrong on a screen. It is a plausible number that is not the truth.

Try it: one pair of registers, four readings

A float32 spans two 16-bit registers, and vendors disagree about which comes first. Type the two registers exactly as the device sent them. Only one of the four results below is the truth, and nothing on the wire tells you which.

OrderBytesReads as
ABCDE9 79 42 F6-1.8834e+25
CDAB42 F6 E9 79123.456
BADC79 E9 F6 421.5185e+35
DCBAF6 42 79 E9-9.8611e+32

Configuration

byteOrderoneBasedmaxGapmaxBlock