PortDock

Modbus function codes — 01–06, 0F, 10 and 17, and when to use each

The nine Modbus functions that read and write coils and registers in one table: quantity limits, reply layouts, 06 vs 10, 05 vs 0F, and what exception 01 means.

The function code is the byte right after the slave ID (RTU) or the MBAP header (TCP). It selects which table to read or write; the address is a 0-based index inside that table. Of the public function codes, these nine handle registers and coils. Limits are from the Modbus Application Protocol Specification V1.1b3.

CodeNameTableMax per request
01Read CoilsCoils (0xxxx)2000
02Read Discrete InputsDiscrete inputs (1xxxx)2000
03Read Holding RegistersHolding registers (4xxxx)125
04Read Input RegistersInput registers (3xxxx)125
05Write Single CoilCoils1
06Write Single RegisterHolding registers1
0F (15)Write Multiple CoilsCoils1968
10 (16)Write Multiple RegistersHolding registers123
17 (23)Read/Write Multiple RegistersHolding registersread 125 · write 121

Manuals write function codes in hex (0F, 10, 17) or decimal (15, 16, 23); «FC16» and «FC10» are the same function. The limits are the specification maximums and a device may accept fewer — exceeding them returns exception 03 (illegal data value).

Reads: 01/02 return bits, 03/04 return 16-bit values

Replies to 01 and 02 pack eight bits per byte, and the lowest bit of the first byte is the first requested address. Reading 10 coils (addresses 0–9) returns two data bytes.

Request   01 01 00 00 00 0A BC 0D
Response  01 01 02 05 01 7B 6C

The first data byte 05 is binary 0000 0101, so coils 0 and 2 are on; the second byte 01 means coil 8 is on. Unused bits in the last byte are padded with zeros.

03 and 04 share the same request and reply layout and differ only in the table. The device decides which value lives where — the Rootech Accura 3300E keeps everything in holding registers (03), while the LS ELECTRIC GIMAC1000 keeps measurements in input registers (04). Follow the function code column in the manual; if 03 returns exception 02, try 04.

Writes: single (05, 06) and multiple (0F, 10)

05 coil 0 ON                01 05 00 00 FF 00 8C 3A
06 register 1 = 100         01 06 00 01 00 64 D9 E1
10 registers 0–1 = 10, 258  01 10 00 00 00 02 04 00 0A 01 02 53 FC

17: write, then read, in one request

Function 17 (23) writes and reads holding registers in one request; the specification performs the write before the read. It saves a round trip, but support varies, so check the manual's function list first. This example writes 255 to address 16 and reads two registers from address 0.

Request   01 17 00 00 00 02 00 10 00 01 02 00 FF 56 6B
Response  01 17 04 00 64 00 C8 B9 6E

If you get exception 01

Exception replies add 0x80 to the function code (03 → 83, 06 → 86, 10 → 90). Exception 01 (illegal function) means the device lacks the function or cannot accept it in its current state; pick another function from the supported list. 02 points to the address, 03 to the quantity or value.

01 86 02 C3 A1   ← exception 02 (illegal data address) to a 06 request

Other functions

0x07, 0x08, 0x0B, 0x0C and 0x11 are serial-line-only diagnostics, 0x14/0x15 handle file records, 0x16 is mask write, 0x18 reads a FIFO queue and 0x2B carries device identification and more. For exchanging register and coil values, the nine above are all you need.

In PortDock

Published 2026-10-22