Modbus function codes: a reference with limits and example frames

· By Vladimir Chemeris, developer of Modbus TCP FieldKit

Short answer: eight function codes cover almost all Modbus work: 01 to 04 read, 05 and 06 write one item, 15 and 16 write several. The table gives the limits, and each frame below is a real exchange with a test server.

The eight you need

Code Hex Name Area Limit
01 0x01 Read Coils Coils 2000 bits
02 0x02 Read Discrete Inputs Discrete inputs 2000 bits
03 0x03 Read Holding Registers Holding registers 125 registers
04 0x04 Read Input Registers Input registers 125 registers
05 0x05 Write Single Coil Coils 1 coil
06 0x06 Write Single Register Holding registers 1 register
15 0x0F Write Multiple Coils Coils 1968 bits
16 0x10 Write Multiple Registers Holding registers 123 registers

Note the decimal and hex: manuals mix them, and 15 in decimal is 0F on the wire. Writing 0x15 by mistake sends Write File Record.

Reads

03, Read Holding Registers, from a pymodbus 3.16.1 server, address 0, quantity 3:

TX 00 01 00 00 00 06 01 03 00 00 00 03
RX 00 01 00 00 00 09 01 03 06 00 64 00 FA 04 00

The response gives a byte count, 06, then two bytes per register.

01, Read Coils, address 0, quantity 8:

TX 00 0C 00 00 00 06 01 01 00 00 00 08
RX 00 0C 00 00 00 04 01 01 01 01

The data byte 01 holds eight coils, lowest address in the lowest bit. Here coil 0 is on and coils 1 to 7 are off.

Single writes

06, Write Single Register, address 2, value 2048. A normal response repeats the request:

TX 00 08 00 00 00 06 01 06 00 02 08 00
RX 00 08 00 00 00 06 01 06 00 02 08 00

05, Write Single Coil takes only FF 00 for on, or 00 00 for off:

TX 00 0A 00 00 00 06 01 05 00 00 FF 00
RX 00 0A 00 00 00 06 01 05 00 00 FF 00

The echo confirms the device received the request. Read the register back when it matters: the device’s own logic can still ignore or clamp the value.

Multiple writes

16, Write Multiple Registers, address 20, two registers. The response carries the address and the quantity, without the data:

TX 00 0D 00 00 00 0B 01 10 00 14 00 02 04 12 34 56 78
RX 00 0D 00 00 00 06 01 10 00 14 00 02

Use this for 32-bit values, so both halves arrive in one request. Two separate 06 writes leave a moment when the value is half old and half new.

Less common codes

Code Hex Name Note
07 0x07 Read Exception Status Serial line only
08 0x08 Diagnostics Serial line only, with sub-functions
20 0x14 Read File Record
21 0x15 Write File Record
22 0x16 Mask Write Register AND and OR mask on one register
23 0x17 Read/Write Multiple Registers One transaction, write first
24 0x18 Read FIFO Queue
43 0x2B Encapsulated Interface Transport Sub-code 14 reads device identification

Support varies a lot. An unsupported function should return exception 01. FieldKit implements the eight main codes and names the exception it receives.

What happens at the limits

A request for 126 registers should get 83 03. pymodbus 3.16.1 answered 80 01 instead. See what a real server did for more cases like this.

Sources

FAQ

What is the difference between function 03 and 04?

03 reads holding registers, which are read and write. 04 reads input registers, which are read-only. They are separate areas on many devices, though some devices map both to the same memory.

How many registers can I read at once?

125 with function 03 or 04. Write Multiple Registers takes up to 123, and Read Coils takes up to 2000 bits.

What value turns a coil on with function 05?

FF 00 turns it on, and 00 00 turns it off. The specification says all other values are illegal.