
前回、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で返すだけ。
温湿度に加えて伝送結果の検証もできたと。一件落着か。今日は「涼しくて」良かったけれども(センサとは関係ない。)
