Modbus Function Codes & CRC Modbus
The codes a Modbus exchange is built from, plus the checksum that wraps each serial frame. Function codes is what a request asks for — read coils, write registers, and the dec-vs-hex gotcha (FC 15 = 0x0F, FC 16 = 0x10). Exception codes is what a server sends back when it refuses, riding on the function code with its high bit set. CRC-16 builds or checks the two error-check bytes an RTU frame carries.
| Code | Name | What it does |
|---|---|---|
| 1 0x01 | Read Coils | Read 1–2000 coils — the read/write discrete output bits. |
| 2 0x02 | Read Discrete Inputs | Read 1–2000 discrete inputs — read-only bits. |
| 3 0x03 | Read Holding Registers | Read 1–125 holding registers — the read/write 16-bit words. |
| 4 0x04 | Read Input Registers | Read 1–125 input registers — read-only 16-bit words. |
| 5 0x05 | Write Single Coil | Force one coil ON (0xFF00) or OFF (0x0000). |
| 6 0x06 | Write Single Register | Write one holding register. |
| 7 0x07 | Read Exception Status | Serial only — read 8 device exception-status bits. |
| 8 0x08 | Diagnostics | Serial only — line diagnostics and loopback sub-functions. |
| 11 0x0B | Get Comm Event Counter | Serial only — status word and event count. |
| 12 0x0C | Get Comm Event Log | Serial only — status, counts, and recent event bytes. |
| 15 0x0F | Write Multiple Coils | Write a contiguous block of coils in one request. |
| 16 0x10 | Write Multiple Registers | Write a contiguous block of holding registers. |
| 17 0x11 | Report Server ID | Serial only — device ID string and run-status byte. |
| 22 0x16 | Mask Write Register | AND/OR-mask selected bits of one holding register. |
| 23 0x17 | Read/Write Multiple Registers | Read one block and write another in a single transaction. |
| 43 0x2B | Encapsulated Interface Transport | Read Device Identification (MEI type 0x0E) — vendor, model. |
| No function codes match that filter. | ||
Codes split across four data tables: coils and discrete inputs are bits; holding and input registers are 16-bit words. Which table an address lives in — and the 5-digit prefix that names it — is the subject of Modbus Decoding.
| Code | Name | Meaning |
|---|---|---|
| 1 0x01 | Illegal Function | The server doesn't support that function code. |
| 2 0x02 | Illegal Data Address | The address — or the requested range — isn't valid in this device. |
| 3 0x03 | Illegal Data Value | A value or quantity is out of range for that address. |
| 4 0x04 | Server Device Failure | An unrecoverable error occurred while carrying out the request. |
| 5 0x05 | Acknowledge | Request accepted but long-running — poll for completion, don't resend. |
| 6 0x06 | Server Device Busy | Busy with a long program command; resend the request later. |
| 8 0x08 | Memory Parity Error | Parity error in the extended file-record memory (FC 20/21). |
| 10 0x0A | Gateway Path Unavailable | A gateway is misconfigured or overloaded — no path to the target. |
| 11 0x0B | Gateway Target Failed to Respond | No reply from the target device — often the wrong unit ID. |
| No exception codes match that filter. | ||
An exception response echoes the original function code with its high bit set — FC + 0x80. A failed Read Holding Registers (FC 3, 0x03) comes back as 0x83, and the byte after it is the exception code above.
Input
Paste the frame as hex bytes — spaces, commas, and 0x are ignored. Modbus RTU uses CRC-16 (polynomial 0xA001, initial value 0xFFFF); ASCII mode uses an LRC instead, and Modbus TCP drops the checksum entirely for the MBAP header.
Output
How the check works
The CRC is computed over every byte of the frame — unit ID, function code, and data — then appended low byte first. A receiver runs the same calculation over the whole frame including the CRC; a clean frame leaves a remainder of zero. The Append as line above gives the two bytes to add when you're building a frame; the verdict below treats the last two bytes of what you pasted as a CRC and tells you whether a captured frame checks out.