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.
| Code | Name | Table | Max per request |
|---|---|---|---|
| 01 | Read Coils | Coils (0xxxx) | 2000 |
| 02 | Read Discrete Inputs | Discrete inputs (1xxxx) | 2000 |
| 03 | Read Holding Registers | Holding registers (4xxxx) | 125 |
| 04 | Read Input Registers | Input registers (3xxxx) | 125 |
| 05 | Write Single Coil | Coils | 1 |
| 06 | Write Single Register | Holding registers | 1 |
| 0F (15) | Write Multiple Coils | Coils | 1968 |
| 10 (16) | Write Multiple Registers | Holding registers | 123 |
| 17 (23) | Read/Write Multiple Registers | Holding registers | read 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
- Function 05 accepts only FF 00 (ON) and 00 00 (OFF). Anything else, such as 00 01, is an illegal value in the specification.
- A successful 05 or 06 is answered with an echo of the request. 0F and 10 return only the start address and quantity — the 10 request above is answered with «01 10 00 00 00 02 41 C8».
- When two registers form one value (U32, F32), write them together with 10. Two separate 06 writes let the device use a half-updated value in between.
- Devices differ in the write functions they accept. The Rootech Accura 3300E supports only 03, 06 and 16. If a device lacks 06, write a quantity of 1 with 10.
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
- «Modbus Frame Decoder» web tool: paste RTU or TCP hex to decode requests and replies of all nine functions field by field; it flags quantities over the specification limits and invalid 05 values.
- «Modbus RTU Request Builder» web tool: builds 01–06, 0F and 10 requests from slave ID, address and quantity, CRC included.
- Modbus Master writes one register with 06 (coils 05) and several registers or 32/64-bit values with 10 (0F). If the device rejects 06/05, an option under «Communication details» sends single values with the multiple-write functions (FC15/16).
Published 2026-10-22