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
- Modbus Application Protocol Specification V1.1b3, sections 5 and 6
- Frames captured on 30 October 2026 from pymodbus 3.16.1 on Linux
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.