Arduino/ESP32 通信协议的一些校验方法(校验和 和 异或校验)

凌顺实验室(lingshunlab.com)介绍一些做串口通信或者通信协议的时候,会使用一些数据校验方法,确保接收到的数据是完整正确的 。例如比较常用的是 检验和(checksum)异或校验(Block Check Character/BCC)

检验和(checksum)

检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为数制表示的形式。如果校验和的数值超过十六进制的FF,也就是255. 就要求其补码作为校验和。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。

以下是凌顺实验室遇到的某个产品用到的校验和方式,在这里累加超出255的数据并没有使用补码,所以具体校验和的方法需要参考产品说明书,或者由你来定义。

某产品的检验和方法,把需要校验的数据都相加,但是8位的数据最大只能是256,所以超出的部分我们不需要,只要低8位的数据,使用 &0x00ff 获取。

例如要检验的16进制数据组:11 22 33 44 55 66
计算:11 + 22 + 33 + 44 + 55 + 66 = 0x165 = 357(10进制) = 0000 0001 0110 0101
0000 0001 0110 0101 & 0x00ff = 0110 0101 = 101(10进制)= 0x65
校验码是:65

测试代码

// welcome to lingshunlab.com
// 详细说明请查看:https://lingshunlab.com/book/arduino/arduino-esp32-communication-verify-checksum-and-bcc

void setup() {
  Serial.begin(115200);
  char check_sum = 0;
  // 例如需要校验的数据 0x11 0x22 0x33 0x44 0x55 0x66
  // 把数据相加,因为是8位的数据,所以最后我们只要低8位的数据即可
  check_sum = (0x11 + 0x22  + 0x33 + 0x44 + 0x55 + 0x66) & 0x00ff;

  Serial.println(check_sum, HEX); // 以16进制显示
}

void loop() {
}

上传代码,可以查看到串口监视器输出结果为65

异或校验(Block Check Character/BCC)

实际上是一种奇偶校验,也是一种最常用的、最高效的校验方法。所谓的BCC验证方法,是将每一个字节的数据(一般是两个16进制的字符)进行异或后即得到校验码。

例如要检验的16进制数据组:11 22 33 44 55
计算:0x11 xor 0x22 xor 0x33 xor 0x44 xor 0x55 = 0x11
校验码是:0x11

测试代码

// welcome to lingshunlab.com
// 详细说明请查看:https://lingshunlab.com/book/arduino/arduino-esp32-communication-verify-checksum-and-bcc

void setup() {
  Serial.begin(115200);
  char check_sum = 0;

  // 例如需要校验的数据 0x11 0x22 0x33 0x44 0x55
  check_sum = 0x11 ^ 0x22 ^ 0x33 ^ 0x44 ^ 0x55;
  Serial.println(check_sum, HEX); // 以16进制显示
}

void loop() {
}

上传代码,可以查看到串口监视器输出结果为11