稼働中

Raspberry Pi Pico(s_17)HTU21D 用モジュール

HTU21D HTU21Dc.py

HTU21Dはデジタル温湿度センサーです。※詳細はHTU21Dのデータシートを参照ください。
Raspberry Pi PicoでHTU21DセンサーモジュールHW-220を使う自作の’HTU21Dc.py’を作成しました。
記事d_21を元に作成しています。’HTU21Dc.py’は末尾にあります。
使い方だけを記載します。

使い方

■ ファイル転送
Raspberry Pi Picoへ’HTU21Dc.py’を送った後でimportして使います。
※HTU21Dc.pyの末尾に、使用例(HTU21D_ex.py)の## example以降をコピペ追加しても動作確認できます。
■ メソッド
‘HTU21Dc’をimportすると「HTU_temp、HTU_humi、HTU_reset、HTU_res、HTU_CRC、read__user_regi」のメソッドが使えるようになります。
HTU21D(num=1,sda=10)で初期化します。
num:I2C0、I2C1の番号です。デフォルトは1(I2C1)
sda:SDAのGPIO番号です。デフォルトは10(GP10)
(01)HTU_temp()
温度を測定します。
温度、ステータス、16bit生データ、checksumデータをリストを返します。
(02)HTU_humi()
湿度、ステータス、16bit生データ、checksumデータをリストを返します。
(03)HTU_reset()
ソフトリセットします。
(04)HTU_res(s_dat=’00’)
分解能を変更します。user registerのBit7,0を設定します。
HTU21D 分解能
(05)HTU_CRC(dat)
以下の多項式で巡回冗長検査をします。値を返します。
polynomial
(06)read__user_regi()
user registerの値を返します。

使用例1

HTU21Dで温湿度を測定します。user registerを読み書きして分解能を確認します。


HTU21Dc_ex1.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C,Pin
from HTU21Dc import HTU21D
## example -----------------------
a=HTU21D(1,10)   #(num=1,sda=10)
a.HTU_reset()

# Temperature Measure
t_lst=a.HTU_temp()
print('temp=',t_lst[0],t_lst[1])    # 温度、ステータス
print('CRC,Checksum',a.HTU_CRC(t_lst[2]),t_lst[3])  # CRC結果、Checksum

# Humidity Measure
h_lst=a.HTU_humi()
print('RH% =',h_lst[0],h_lst[1])    # 湿度、ステータス
print('CRC,Checksum',a.HTU_CRC(h_lst[2]),h_lst[3])  # CRC結果、Checksum

# userregister
r_dat=a.read__user_regi()                   # user_regi
print('default={:#010b}'.format(r_dat[0]))

a.HTU_res('11')                             # resolition ‘00’
r_dat=a.read__user_regi()                   # user_regi
print('reso 11={:#010b}'.format(r_dat[0]))

実行結果

実行すると以下のようになりました。※Thonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
temp= 18.7876 0
CRC,Checksum 130 130        # 同値なので送受信は正常
RH% = 50.79321 2
CRC,Checksum 164 164        # 同値なので送受信は正常
default=0b00000010          # Bit7,0='00'
reso 11=0b10000011          # Bit7,0='11'
>>> 

使用例2

HTU21Dで温湿度を測定します。
CRC計算を行い受信データの検査をします。誤伝送なら再測定します。


HTU21Dc_ex2.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C,Pin
from HTU21Dc import HTU21D
import time
## example -----------------------
a=HTU21D(1,10)   #(num=1,sda=10)   
a.HTU_reset()
# CRC-Checksum
while True:
    t_lst=a.HTU_temp()
    if a.HTU_CRC(t_lst[2]) == t_lst[3]:
        print('temp=',t_lst[0])
        break
    #print('err')
    time.sleep_ms(200)
while True:
    h_lst=a.HTU_humi()
    if a.HTU_CRC(h_lst[2]) == h_lst[3]:
        print('RH% =',h_lst[0])
        break
    #print('err')
    time.sleep_ms(200)

実行結果

実行すると以下のようになりました。※Thonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
temp= 18.93775
RH% = 51.13654
>>> 

HTU21Dモジュール用


HTU21Dc.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import I2C,Pin
import time
# HTU21D Device digital humidity sensor with temperature
# slave address hex(64)='0x40'
class HTU21D:
    def __init__(self,num=1,sda=10):      
        self.addr=0x40
        self.i2c=I2C(num, scl=Pin(sda+1), sda=Pin(sda), freq=400_000)

    ## soft reset    
    def HTU_reset(self):
        buf=bytearray(1)
        buf[0]=0xfe      # cmd 0xfe soft reset
        self.i2c.writeto(self.addr,buf)

    # read register State(8)hum(20)temp(20) 6bytes
    def HTU_temp(self):
        buf=bytearray(1)
        buf[0]=0xe3      # cmd 0xe3 trigger temperature mesurement-hold master
        self.i2c.writeto(self.addr,buf)    

        r_dat=self.i2c.readfrom(self.addr,3) #msb,lsb,crc
        raw=(r_dat[0]<<8 | r_dat[1])  # 16bit_raw_data
        sta=r_dat[1] & 0x02           # status humi='10'
        crc=r_dat[2]         
        data=raw & 0xfffc
        temp= -46.85 + 175.72 * raw / 2**16
        return temp,sta,raw,crc

    def HTU_humi(self):
        buf=bytearray(1)
        buf[0]=0xe5      # cmd 0xe5 trigger humidity mesurement-hold master
        self.i2c.writeto(self.addr,buf)    

        r_dat=self.i2c.readfrom(self.addr,3) #msb,lsb,crc
        raw=(r_dat[0]<<8 | r_dat[1])  # 16bit_raw_data
        sta=r_dat[1] & 0x02           # status humi='10'
        crc=r_dat[2]        
        data=raw & 0xfffc
        humi= -6.0 + 125.0 * data / 2**16
        return humi,sta,raw,crc

    # write user register
    def write_user_regi(self,dat):
        buf=bytearray(2)
        buf[0]=0xe6      # cmd 0xe6 write user register
        buf[1]=dat
        self.i2c.writeto(self.addr,buf)

    # read user register
    def read__user_regi(self):
        buf=bytearray(1)
        buf[0]=0xe7      # cmd 0xe7 read user register
        self.i2c.writeto(self.addr,buf)
        r_dat=self.i2c.readfrom(self.addr,1) #user reg data
        return r_dat

    # set resolution user_register  
    def HTU_res(self,s_dat='00'): 
        # '0x7e' 0b01111110
        # user_regi読み出し、Bit7,0を指定s_datに変える ORをとる
        dat= (self.read__user_regi()[0] & 0x7e) | int('0b'+s_dat[0]+'0'*6+s_dat[1])
        self.write_user_regi(dat)

    def HTU_CRC(self,dat):
        div=2**8 + 2**5 + 2**4 +2**0  # bin(305)='0b100110001'
        zisu=8
        #message data
        dat_len=len(bin(dat))-2
        msg = dat << zisu        
        div = div<<(dat_len-1)        
        for i in range((dat_len+zisu-1), (zisu-1), -1):
            if msg & (1<<i) : msg = msg ^ div # XOR div=div>>1
        return msg