Modbus CRC16 calculator
Enter the bytes of a Modbus RTU frame — address, function code and data. You get the CRC16 and the two bytes exactly as they go on the wire. Paste a complete frame and the calculator confirms when its CRC is already correct.
Spaces, commas and 0x prefixes are allowed: 01 03 00 00 00 02 or 0x01,0x03,… or 010300000002.
- CRC16
- –
- On the wire
- –
- Complete frame
- –
Runs entirely in your browser — nothing you enter is sent anywhere.
How the Modbus CRC is calculated
Modbus RTU uses CRC-16/MODBUS: polynomial 0x8005 (0xA001 in reflected form), initial value 0xFFFF, no final XOR. It covers every byte of the frame from the address up to the last data byte.
- Start with the register at 0xFFFF.
- XOR the next frame byte into the low byte of the register.
- Eight times: shift the register right by one bit; if the bit shifted out was 1, XOR the register with 0xA001.
- After the last byte, send the result low byte first: CRC 0x0BC4 goes on the wire as C4 0B.
The same in C
This bitwise version is what most firmware uses. A table-driven variant is faster and gives the same result.
uint16_t modbus_crc16(const uint8_t *data, size_t len) { uint16_t crc = 0xFFFF; for (size_t i = 0; i < len; i++) { crc ^= data[i]; for (int b = 0; b < 8; b++) crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1; } return crc; /* low byte first on the wire */ }
Frequently asked questions
Why does my CRC come out with the bytes swapped?
Because Modbus sends the CRC low byte first, unlike the 16-bit registers in the data, which are big-endian. A CRC of 0x0BC4 appears on the wire as C4 0B. Many hand-written checks fail exactly here.
Does Modbus ASCII or Modbus TCP use this CRC?
No. Modbus ASCII protects its frames with an LRC (the negated byte sum), and Modbus TCP has no checksum of its own — TCP takes care of that. The CRC16 belongs to Modbus RTU only.
Why is the CRC over a complete frame 0x0000?
Appending the CRC low byte first makes the register end at zero. That is a quick way to check a received frame: run the CRC over all bytes including the CRC — if the result is 0x0000, the frame is intact.
Checking every frame by hand?
Trace listens on the RS485 line, splits Modbus RTU telegrams at the silent interval and verifies every CRC live — faulty frames are flagged, not dropped.