Modbus CRC-16 Calculator
Paste the bytes of a Modbus RTU frame and get the CRC in the order it goes on the wire. If the frame already ends with a CRC, the calculator checks it.
Bytes
ExampleWith or without the CRC at the end. 11 03 00 6B 00 03, 1103006B0003 and 0x11,0x03 all work.
Result
| CRC-16/MODBUS | |
|---|---|
| CRC bytes as sent (low byte first) | |
| Frame with CRC | |
| LRC (Modbus ASCII) | |
| Modbus ASCII frame |
Runs entirely in your browser. Nothing you enter is sent to a server.
CRC-16/MODBUS in code
Start value 0xFFFF, polynomial 0xA001 (0x8005 reflected), no final XOR. The low byte is sent first.
uint16_t modbus_crc16(const uint8_t *buf, size_t len)
{
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < len; i++) {
crc ^= buf[i];
for (int bit = 0; bit < 8; bit++)
crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
}
return crc; /* send crc & 0xFF first, then crc >> 8 */
}
def modbus_crc16(data: bytes) -> bytes:
crc = 0xFFFF
for b in data:
crc ^= b
for _ in range(8):
crc = (crc >> 1) ^ 0xA001 if crc & 1 else crc >> 1
return crc.to_bytes(2, "little") # low byte first, ready to append
How the Modbus CRC works
Every Modbus RTU frame ends with a 16-bit CRC calculated over all bytes before it: device address, function code and data. The receiver calculates the same value and drops the frame without an answer if it does not match. The CRC is sent low byte first, the opposite of register values. That is why the CRC 0x8776 of the frame 11 03 00 6B 00 03 appears on the line as 76 87.
Modbus TCP has no CRC; the TCP connection already checks the data. Modbus ASCII uses a simpler 8-bit LRC instead, which is shown here as well.
Common mistakes
- CRC bytes swapped. Sending the high byte first is the most common bug in self-written drivers. The device stays silent. The calculator tells you when a frame has the right CRC in the wrong order.
- CRC over the wrong bytes. The CRC covers everything from the device address to the last data byte, nothing more and nothing less. In Modbus TCP gateways, the MBAP header is not part of it.
- Text instead of bytes. The CRC is calculated over the binary bytes, not over the characters "0", "1", "0", "3". Hex text from a log must be converted first, which the calculator does for you.
- A correct CRC is not enough. If the device still does not answer, check baud rate, parity, stop bits, device address and the bus termination.
Questions from practice
Why is the Modbus CRC sent low byte first?
The CRC is calculated with a reflected algorithm that shifts bits to the right, and the specification transmits the result low byte first. Register data is sent high byte first, so the CRC is the one exception in the frame. A frame that ends with the two CRC bytes swapped is ignored by the device.
What is the CRC of 01 03 00 00 00 01?
84 0A, so the full request to read one holding register at address 0 from device 1 is 01 03 00 00 00 01 84 0A. For ten registers (01 03 00 00 00 0A) it is C5 CD.
Does Modbus TCP use a CRC?
No. Modbus TCP frames start with a 7-byte MBAP header and carry no CRC, because TCP already protects the data. A CRC appears only in Modbus RTU, including RTU over TCP, where the serial frame is tunnelled unchanged.
Which CRC-16 variant does Modbus use?
CRC-16/MODBUS: polynomial 0x8005 in reflected form (0xA001), start value 0xFFFF, input and output reflected, no final XOR. Other CRC-16 variants such as CCITT or XMODEM give different results and do not work.
What is the difference between CRC and LRC?
Modbus RTU uses the 16-bit CRC over the binary frame. Modbus ASCII sends the frame as hex text between a colon and CR LF and protects it with an 8-bit LRC: the two's complement of the sum of all bytes. The LRC is much weaker but easy to calculate.
Related tools
- Register DecoderFloat32, Int32, UInt16 and bits in every byte order, plus Find my value.
- Address Converter40001 ↔ offset 0, 4x/3x/0x/1x notation, 5- and 6-digit addresses.
- Value EncoderTurn a value like 230.5 into registers for every byte order.