Documentation

Modbus Compatibility: Standards, Function Codes and Tests

ModLens and ModLens Sim follow the public Modbus specifications. They are tested against an independent Modbus implementation (the open-source pymodbus library), not only against each other.

Standards

  • Modbus Application Protocol Specification V1.1b3: function codes, data model, exception codes, quantity limits.
  • Modbus Messaging on TCP/IP Implementation Guide V1.0b: MBAP header, transaction IDs, unit identifier.
  • Modbus over Serial Line Specification and Implementation Guide V1.02: RTU framing, CRC-16, 3.5-character silent interval, broadcast (unit 0).

Transports

Transport ModLens (client/master) ModLens Sim (server/slave)
Modbus TCP (port 502 or any) ✅ ✅
Modbus RTU on RS-485/RS-232 (USB adapter) ✅ ✅
Modbus RTU over TCP (transparent serial gateways) ✅ ✅
Network serial ports (RFC 2217, raw socket) ✅

Function codes

Code Function ModLens ModLens Sim
01 Read coils ✅ ✅
02 Read discrete inputs ✅ ✅
03 Read holding registers ✅ ✅
04 Read input registers ✅ ✅
05 Write single coil ✅ ✅
06 Write single register ✅ (or FC16, configurable) ✅
15 Write multiple coils ✅
16 Write multiple registers ✅ ✅

Behavior

  • Addressing: 0-based protocol addresses (register 40001 = holding address 0, 30001 = input address 0). The help explains how to convert manual numbering.
  • Limits: standard maximums (125 registers / 2000 bits per read, 123 registers per write). ModLens splits bigger reads automatically, and each device can have a lower limit for equipment that accepts fewer.
  • Exception codes: 1, 2, 3, 4, 5, 6, 10 and 11 are recognized and explained, with a "what to try" checklist.
  • Data types: int16, uint16, int32, uint32, float32, int64, uint64, float64, ASCII strings, bits.
  • Byte/word orders: ABCD (standard big-endian), CDAB (word swap), BADC (byte swap), DCBA (little-endian).
  • Scaling: value = raw × scale + offset.

Options for real-world devices (per device in ModLens)

Option Use it when
Max registers / coils per read The device rejects big reads (error 3 or timeout); common limits are 32, 64 or 100
Always write with function 16 The device rejects FC6 with error 1 (illegal function)
Pause between requests Slow devices, gateways or radio links give random timeouts
Timeout and retries Slow networks; or fast unit-ID scanning (0.2–0.3 s)
RTU over TCP Inexpensive serial-to-Ethernet converters in transparent/raw mode

Automated test results (every build)

Test Against Result
ModLens reads all 4 tables, all data types pymodbus server (independent), Modbus TCP ✅
Same, RTU framing over TCP (CRC) pymodbus server, RTU framer ✅
Exception code 2 on missing addresses pymodbus server ✅
Writes FC5, FC6, FC16, forced FC16 pymodbus server ✅
Device read limit (100 registers read 7 at a time) pymodbus server ✅
Scanner finds the exact address map, finder finds float32/int32 pymodbus server ✅
Live monitoring with scaling pymodbus server ✅
ModLens Sim answers a standard client: FC1-6, 15, 16, exceptions, silence for unknown units pymodbus client, Modbus TCP ✅
Same with RTU framing over TCP pymodbus client, RTU framer ✅
ModLens Sim RTU slave on a serial line (CRC, exception, bad-CRC frames ignored) serial wire ✅
CRC-16 matches the specification's example frame (01 03 00 00 00 0A → C5 CD) Modbus serial line spec ✅
Runs on Raspberry Pi OS (ARM64, Debian Bookworm) container test ✅

Using Modbus Slave / Modbus Poll (Witte Software), the reference tools many integrators use: 1. ModLens vs Modbus Slave: - In Modbus Slave: Connection → Connect → Modbus TCP/IP, port 502 (or 5021 if 502 is busy). Fill a few holding registers and set one to Float AB CD = 21.5 and one to Float CD AB. - In ModLens: add a TCP device 127.0.0.1 with that port, open Explorer and Find a value. The values must match exactly. 2. ModLens Sim vs Modbus Poll: with ModLens Sim running, read unit 1, holding 0–20 on port 5020 in Modbus Poll. Compare with ModLens Sim's Live values. 3. On real equipment: one Modbus TCP device and one RS-485 device (a meter or a VFD) with their manual's register map.

Not yet verified on site: real RS-485 hardware with ModLens (the RTU code path is the same, provided by pymodbus).