Skip to content

Modbus Rtu Crc

DodaTech 1 min read

In this tutorial, you'll learn about Modbus RTU CRC Mismatch Causes Frame Rejection. We cover key concepts, practical examples, and best practices.

The Problem

Modbus RTU frames are rejected due to CRC mismatch, preventing communication.

Quick Fix

Wrong

// Manual frame construction without CRC
uint8_t frame[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01};
Serial.write(frame, 6);  // No CRC appended```

Slave receives frame but rejects it — CRC mismatch. No response.


### Right

```cpp
#include <ModbusRtu.h>

// Modbus CRC16 calculation (CRC-16/MODBUS)
uint16_t modbusCRC(uint8_t *data, uint16_t len) {
  uint16_t crc = 0xFFFF;
  for (uint16_t i = 0; i < len; i++) {
    crc ^= data[i];
    for (uint8_t j = 0; j < 8; j++) {
      if (crc & 0x0001) {
        crc = (crc >> 1) ^ 0xA001;
      } else {
        crc = crc >> 1;
      }
    }
  }
  return crc;
}

void sendModbusFrame(uint8_t *data, uint16_t len) {
  // Calculate CRC
  uint16_t crc = modbusCRC(data, len);

  // Append CRC (little-endian)
  uint8_t frame[256];
  memcpy(frame, data, len);
  frame[len] = crc & 0xFF;        // Low byte first
  frame[len + 1] = (crc >> 8) & 0xFF;  // High byte

  Serial.write(frame, len + 2);
}

void setup() {
  Serial.begin(9600, SERIAL_8N1);
}

void loop() {
  uint8_t request[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01};
  sendModbusFrame(request, 6);
  delay(1000);
}```

Frame sent with correct CRC. Slave responds with valid data frame.


## Prevention

Modbus RTU uses CRC-16/MODBUS (polynomial 0x8005, initial 0xFFFF, final XOR 0x0000). CRC is appended little-endian (low byte first, high byte second). The slave calculates CRC on received data and compares. Mismatch = frame silently discarded. Most Modbus libraries handle CRC automatically. For manual implementations, verify the CRC algorithm matches the slave's expectation.

DodaTech engineers apply these same patterns across Doda Browser, DodaZIP, and Durga Antivirus Pro for production IoT reliability.

## FAQ

<details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">### What polynomial does Modbus CRC use?</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>CRC-16/MODBUS: polynomial 0x8005, initial value 0xFFFF. Standard CRC-16-IBM is different! Use the Modbus-specific variant.</p>
<h3 id="does-the-master-check-crc">Does the master check CRC?</h3><p>Yes, both master and slave verify CRC on received frames. Invalid CRC = frame discarded, no response.</p>
<h3 id="can-i-compute-crc-in-hardware">Can I compute CRC in hardware?</h3><p>Some MCUs have built-in CRC hardware. Ensure it matches CRC-16/MODBUS (not CRC-16-CCITT or CRC-16-IBM).</p>
</div></details>

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro