温湿度センサー HTU21D / 測定分解能を変更してみる / micro:bit / MicroPython

ループするたびにランダムに測定分解能を変更してみる。変更するたびにユーザーレジスタを読み出して確認する。0x02、0x03、0x82、0x83 のいずれかになるはずである。

from random import randint
from microbit import *

class HTU21D:
    def __init__(self):
        self.HTDU21D_ADDRESS           = 0x40
        self.TRIGGER_TEMP_MEASURE_HOLD = 0xE3
        self.TRIGGER_HUMD_MEASURE_HOLD = 0xE5
        self.SHIFTED_DIVISOR           = (2**8 + 2**5 + 2**4 + 1)<<15 # 0x988000
        self.READ_USER_REG             = 0xE7
        self.WRITE_USER_REG            = 0xE6
        
        self.RH12_TEMP14 = 0b00000000
        self.RH08_TEMP12 = 0b00000001
        self.RH10_TEMP13 = 0b10000000
        self.RH11_TEMP11 = 0b10000001
        
    def readTemp(self):
        buf = bytes([self.TRIGGER_TEMP_MEASURE_HOLD])
        i2c.write(self.HTDU21D_ADDRESS, buf) 
                  
        msb, lsb, crc = i2c.read(self.HTDU21D_ADDRESS, 3)
        crcResult     = self.__check_crc(msb, lsb, crc)
        raw           = (msb<<8 | lsb) & 0xfffc
        temp          = -46.85 + 175.72 * raw / 65536.0
        
        return temp if crcResult == 0 else crcResult
        
    def readHumid(self):
        buf = bytes([self.TRIGGER_HUMD_MEASURE_HOLD])
        i2c.write(self.HTDU21D_ADDRESS, buf) 
                  
        msb, lsb, crc = i2c.read(self.HTDU21D_ADDRESS, 3)
        crcResult     = self.__check_crc(msb, lsb, crc)
        raw           = (msb<<8 | lsb) & 0xfffc
        humid         = -6.0 + 125.0 * raw / 65536.0
        
        return humid if crcResult == 0 else crcResult
        
    def __check_crc(self, msb, lsb, crc):
        divisor   = self.SHIFTED_DIVISOR
        remainder = msb<<16 | lsb<<8 | crc
        
        for i in range(23, 7, -1):
            if remainder & 1<<i:
                remainder ^= divisor
             
            divisor >>= 1
            
        return 0 if remainder == 0 else 999
    
    def readUserRegister(self):
        buf = bytes([self.READ_USER_REG])
        i2c.write(self.HTDU21D_ADDRESS, buf)
        
        return i2c.read(self.HTDU21D_ADDRESS, 1) # bytes データを返す。
        
    def setResolution(self, resolution):
        # 現在のユーザーレジスタを読み出してビット 7、0 だけを書き換える。
        userRegister = self.readUserRegister()[0]
        userRegister &= 0b01111110
        resolution   &= 0b10000001
        userRegister |= resolution
        
        buf = bytes([self.WRITE_USER_REG, userRegister])
        i2c.write(self.HTDU21D_ADDRESS, buf)
        
if __name__ == "__main__":
    HTU = HTU21D()
    
    resolutions = (HTU.RH12_TEMP14,
                   HTU.RH08_TEMP12,
                   HTU.RH10_TEMP13,
                   HTU.RH11_TEMP11,)

    while True:
        HTU.setResolution(resolutions[randint(0, 3)]) # 4 種類の測定分解能をランダムに設定して、
        print(HTU.readUserRegister())                 # 本当に設定されたのか、ユーザーレジスタの内容を読み出して確認する。
                
        temp  = HTU.readTemp()
        humid = HTU.readHumid()
        print("%.1f C, %.1f %%" % (temp, humid))
        sleep(1000)

実行結果:
f:id:ti-nspire:20180614170838p:plain