稼働中

Raspberry Pi Pico(d_21)HTU21D 温湿度センサー

HTU21D HW-220 (I2C)

HTU21Dは温湿度センサーです。I2C通信で制御します。Raspberry Pi PicoでHTU21D搭載のHW-220モジュールを使ってみました。
※micro:bitの記事e_52からRaspberry Pi Picoで使えるように追記、修正等をしました。

外観

HTU21DモジュールHW-220の外観写真です。(以後はHTU21Dと記載します)
HTU21DHTU21D

接続例

HTU21Dの電源電圧は1.5V~3.8VなのでRaspberry Pi Picoの3.3V電源が使えます。
I2C通信にはI2C1のSDA(GP10)SCL(GP11)を使いました。
HTU21D接続図
接続が出来たらI2Cデバイスのスレーブアドレスを調べてみます。
ThonnyのShellで確認しました。
HTU21Dのスレーブアドレスは以下のように64(0x40)でした。


>>> from machine import I2C,Pin
>>> i2c = I2C(1, scl=Pin(11), sda=Pin(10), freq=400_000)
>>> i2c.scan()
[64]            # hex(64)'0x40'
>>> 

HTU21Dの説明

データシートから抜粋してHTU21Dの説明します。
HTU21DのI2Cで使うコマンドは下表です。下方にあるスクリプト内では測定モードのNo Hold masterの2つは使っていません。
HTU21D コマンド
※HTU21Dのデータシートから抜粋

下表は測定モードがHold masterの場合のI2C通信です。温湿度データ、Checksumの3バイトデータ得ます。
i2c.writeto(addr,buf)でコマンドコードを送信した後に、i2c.readfrom(addr,3)で3バイトを読みます。(addr:HTU21Dのスレーブアドレス、buf:コマンドコード)
2バイト目は温湿度Data(LSB)とStatusが含まれています。
Statusは測定タイプを返しています。(43)が測定タイプ、(44)は未割り当てです。
(43)が‘0’: temperature, ‘1’: humidityです。

2バイトデータを温度、湿度値にするにはStatusの値を’00’した値で下の計算式で算出します。
HTU21D 計算式
※計算式はHTU21Dのデータシートから抜粋

3バイト目は送信したデータが正しいかを判別する8-bit CRCのデータのようです。
HTU21D I2C
※HTU21Dのデータシートから抜粋

測定の分解能を下記のuser registerのBit7,0の設定で変更できます。デフォルトはBit7,0=’0,0’でRH=12bits、Temp14=bitsです。
HTU21D user register
※HTU21Dのデータシートから抜粋

スクリプト

HTU21Dのスクリプトは以下のようにしました。
温度、湿度を測定しました。user registerを読み書きして分解能を確認しました。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。
※Raspberry Pi Pico単独で動作させるには’main.py’としてRaspberry Pi Picoにuploadして使います。


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

## soft reset              cmd 0xfe
def HTU_reset():
    buf=bytearray(1)
    buf[0]=0xfe
    i2c.writeto(addr,buf)
# write user register       cmd 0xe6
def write_user_regi(dat):
    buf=bytearray(2)
    buf[0]=0xe6
    buf[1]=dat
    i2c.writeto(addr,buf)
# read user register       cmd 0xe7
def read__user_regi():
    buf=bytearray(1)
    buf[0]=0xe7
    i2c.writeto(addr,buf)
    r_dat=i2c.readfrom(addr,1)     #user reg data
    return r_dat

# read register
def HTU_temp():
    buf=bytearray(1)
    buf[0]=0xe3       # cmd 0xe3 trigger temp mesurement-hold master
    i2c.writeto(addr,buf)
    r_dat=i2c.readfrom(addr,3)  #msb,lsb,crc 
    raw=(r_dat[0]<<8 | r_dat[1]) & 0xfffc       # statusを'00'に 0xfc='0b_1111_1100'
    sta=r_dat[1] & 0x02                         # tempなら'00'
    temp= -46.85 + 175.72 * raw / 2**16
    return temp,sta

def HTU_humi():
    buf=bytearray(1)
    buf[0]=0xe5       # cmd 0xe5 trigger humidity mesurement-hold master
    i2c.writeto(addr,buf)    
    r_dat=i2c.readfrom(addr,3) #msb,lsb,crc
    
    raw=(r_dat[0]<<8 | r_dat[1]) & 0xfffc       # statusを'00'に
    sta=r_dat[1] & 0x02                         # 湿度なら'10'
    humi= -6.0 + 125.0 * raw / 2**16
    return humi,sta

# set resolution user_register  
def HTU_res(s_dat='00'): 
    # user_regi読み出し、'0x7e' 0b01111110でBit7,1をクリア後に引数(s_dat)に変える
    dat= (read__user_regi()[0] & 0x7e) | int('0b'+s_dat[0]+'0'*6+s_dat[1])
    write_user_regi(dat)

## example -----------------------
# soft reset
HTU_reset()

# Temperature Measure
temp,t_status = HTU_temp()
print('temp=',temp,t_status)
#print('temp',HTU_temp()[0],HTU_temp()[1]) #これでもいい

# Humidity Measure
humi,h_status = HTU_humi()
print('RH% =',humi,h_status)

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

# write__user_register
HTU_res('11')
r_dat=read__user_regi()
print('reso 11={:#010b}'.format(r_dat[0]))

関数 部分説明

■HTU_reset()
HTU21Dをリセットをします。
■write_user_regi(dat)
ユーザーレジスタにデータを書き込みます。
■read__user_regi()
ユーザーレジスタの値を返します。
■HTU_temp()
温度を測定します。温度、ステータスを返します。ステータスは正常なら’00’です。
■HTU_humi()
湿度を測定します。湿度、ステータスを返します。ステータスは正常なら’10’です。
■HTU_res(s_dat=’00’)
温度、湿度測定の分解能を変更します。user registerのBit7,0の設定をします。設定値は前述の表を参照ください。

実行結果

温度、湿度測定とデフォルトのuser register値の確認と分解能を変更後のuser register値の確認をしました。
結果は以下のようになりました。※Thonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
temp= 19.0021 0
RH% = 54.92835 2
default=0b00000010          #default Bit7,0='0,0'
reso 11=0b10000011          #Bit7,0='1,1'変更を確認
>>> 

まとめ

Raspberry Pi PicoでHTU21Dを使ってD/A変換ができました。