PLCBytes
Modbus tools

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

Example

With 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

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