部品屋根性(77) AHT21B、CRC8でのデータ検査を追加。ラズパイPython

Joseph Halfmoon

前回、I2C接続の温湿度センサ AHT21B をラズパイのI2Cバスに接続し、Python3のスクリプトで温度、湿度を読み取ってみました。まあ動いているみたいではあるのですが、データの伝送に誤りがあるや否やを確かめるためのCRCを検査しておりませなんだ。今回は、CRCの検査を追加しただけ。

※「部品屋根性」投稿順Indexはこちら

バイト・リストを引数に与えるとCRC8を計算する関数 calcCRC8を前回コードに付け加えました。CRC8にもいろいろある、ということでAHT21Bの場合、

    • 特性多項式を表す poly = 0x31
    • 初期値 opt = 0xFF

として、読み取った7バイトのうちステータスと湿度、温度の合計6バイト分のデータに対してCRC8を計算すると、末尾の7バイト目のCRC値と一致する(伝送誤りなければ)と。

改訂版のPython3スクリプトが以下に。

#! /usr/bin/python3
# coding: utf-8
from smbus2 import SMBus, i2c_msg
import sys
import time

def calcCRC8(bytLis, poly=0x31, opt=0):
    """Caluculate CRC8 for byte List
    
    poly=0x31 for the AHT21b.
    """
    crc = opt
    for item in bytLis:
        crc ^= item
        for idx in range(8):
            if crc & 0x80:
                crc = ((crc << 1) & 0xFF) ^ poly
            else:
                crc = ((crc << 1) & 0xFF)
    return crc

addr = 0x38

def triggerAHT21B(bus):
    """Triger measurement
    
    send 0xAC, 0x33, 0x00
    """
    time.sleep(0.01)
    #bus.write_block_data(addr, 0xAC, [0x33, 0x00])
    write = i2c_msg.write(addr, [0xAC, 0x33, 0x00])
    bus.i2c_rdwr(write)

def readMeasurementResult(bus):
    """Read 7 bytes
    
    status 8bit, Humidity 20bit, Temparature 20bit, CRC 8bit 
    """
    time.sleep(0.08)
    msg = i2c_msg.read(addr, 7)
    bus.i2c_rdwr(msg)
    return list(msg)

def initAHT21B(bus):
    time.sleep(0.1)
    write = i2c_msg.write(addr, [0x71])
    read = i2c_msg.read(addr, 1)
    bus.i2c_rdwr(write, read)
    res = list(read)
    if len(res) == 1:
        if res[0] == 0x18:
            return True
    return False

def calcHumidity(buf):
    humInt = (buf[1]<<12) + (buf[2]<<4) + ((buf[3] & 0xF0)>>4)
    return (humInt / 2**20) * 100

def calcTemp(buf):
    tempInt = ((buf[3] & 0x0F)<<16) + (buf[4]<<8) + buf[5]
    return (tempInt / 2**20) * 200 - 50

def main():
    print("AHT21B test")
    cnt = 3
    while (cnt > 0):
        with SMBus(1) as bus:
            triggerAHT21B(bus)
            buf = readMeasurementResult(bus)
        if len(buf)==7:
            print("Status: 0x{0:02x}".format(buf[0]))
            print("Humidity [RH%]: {0:3.1f}".format(calcHumidity(buf)))
            print("Temperature[C]: {0:3.1f}".format(calcTemp(buf)))
            crcVerify = False
            if buf[6] == calcCRC8(buf[0:6], opt=0xFF):
                crcVerify = True
            print("CRC Verify: {0}".format(crcVerify))
        else:
            print("ERROR!")
        cnt -= 1
        time.sleep(3)
    # Normal End
    sys.exit(0)

if __name__ == "__main__":
    main()
実機実行結果のアップデート

実機にて実行した結果が以下に。Verifyが成功したか否かをTrue、Falseで返すだけ。Results_wCRCverify

温湿度に加えて伝送結果の検証もできたと。一件落着か。今日は「涼しくて」良かったけれども(センサとは関係ない。)

部品屋根性(76) AHT21B、I2C温湿度センサをラズパイPythonで動作確認 へ戻る

部品屋根性(78) LM61、アナログ出力温度センサをラズパイPythonで読み取る へ進む