94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
# Usage: AHT20 crc8 checker.
|
|
# A total of 6 * 8 bits data need to check. G(x) = x8 + x5 + x4 + 1 -> 0x131(0x31), Initial value = 0xFF. No XOROUT.
|
|
# Author: XU Zifeng.
|
|
# Email: zifeng.xu@foxmail.com
|
|
N_DATA = 6
|
|
# 1 * 8 bits CRC
|
|
N_CRC = 1
|
|
# Initial value. Equal to bit negation the first data (status of AHT20)
|
|
INIT = 0xFF
|
|
# Useful value to help calculate
|
|
LAST_8_bit = 0xFF
|
|
|
|
|
|
# Devide number retrieve from CRC-8 MAXIM G(x) = x8 + x5 + x4 + 1
|
|
CRC_DEVIDE_NUMBER = 0x131
|
|
|
|
# Data and CRC taken from AHT20, use this for testing?
|
|
TEST_DATA = [[28, 184, 245, 165, 156, 208, 163], [28, 185, 16, 149, 156, 83, 112], [
|
|
28, 184, 249, 85, 156, 114, 213], [28, 185, 9, 53, 156, 54, 45], [28, 185, 70, 117, 156, 189, 33], [28, 185, 64, 165, 156, 61, 209]]
|
|
|
|
|
|
def mod2_division_8bits(a, b, number_of_bytes, init_value):
|
|
"calculate mod2 division in 8 bits. a mod b. init_value is for crc8 init value."
|
|
head_of_a = 0x80
|
|
# Processiong a
|
|
a = a << 8
|
|
# Preprocessing head_of_a
|
|
for i in range(0, number_of_bytes):
|
|
head_of_a = head_of_a << 8
|
|
b = b << 8
|
|
init_value = init_value << 8
|
|
a = a ^ init_value
|
|
while (head_of_a > 0x80):
|
|
# Find a 1
|
|
if (head_of_a & a):
|
|
head_of_a = head_of_a >> 1
|
|
b = b >> 1
|
|
a = a ^ b
|
|
else:
|
|
head_of_a = head_of_a >> 1
|
|
b = b >> 1
|
|
# This will show calculate the remainder
|
|
# print("a:{0}\thead of a:{1}\tb:{2}".format(
|
|
# bin(a), bin(head_of_a), bin(b)))
|
|
return a
|
|
|
|
|
|
def AHT20_crc8_calculate(all_data_int):
|
|
init_value = INIT
|
|
# Preprocess all the data and CRCCode from AHT20
|
|
data_from_AHT20 = 0x00
|
|
# Preprocessing the first data (status)
|
|
# print(bin(data_from_AHT20))
|
|
for i_data in range(0, len(all_data_int)):
|
|
data_from_AHT20 = (data_from_AHT20 << 8) | all_data_int[i_data]
|
|
# print(bin(data_from_AHT20))
|
|
mod_value = mod2_division_8bits(
|
|
data_from_AHT20, CRC_DEVIDE_NUMBER, len(all_data_int), init_value)
|
|
# print(mod_value)
|
|
return mod_value
|
|
|
|
|
|
def AHT20_crc8_check(all_data_int):
|
|
"""
|
|
The input data shoule be:
|
|
Status Humidity0 Humidity1 Humidity2|Temperature0 Temperature1 Temperature2 CRCCode.
|
|
In python's int64.
|
|
"""
|
|
mod_value = AHT20_crc8_calculate(all_data_int[:-1])
|
|
if (mod_value == all_data_int[-1]):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
|
|
def CRC8_check(all_data_int, init_value=0x00):
|
|
divider = 0x107
|
|
DATA_FOR_CHECK = all_data_int[0]
|
|
for data in all_data_int[1:-1]:
|
|
DATA_FOR_CHECK = (DATA_FOR_CHECK << 8) | data
|
|
remainder = mod2_division_8bits(
|
|
DATA_FOR_CHECK, divider, len(all_data_int) - 1, init_value)
|
|
if (remainder == all_data_int[-1]):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(CRC8_check([0x66, 0x44, 0x33, 0x22, 0x24], 0))
|
|
for data in TEST_DATA:
|
|
print(AHT20_crc8_check(data))
|