温湿度センサーDHT20とAHT25から温度データと湿度データを読み取る方法を紹介します。
Raspberry PiとRaspberryPi OSに標準でインストールされているプログラム言語のPythonを使用して、I2C通信でデータを読み取ります。
サンプルプログラムでは、データ読み取り以外に測定条件設定も行います。
ちなみに、DHT20とAHT25は、同一のI2Cアドレスで全く同じプログラムで動作しました。
仕様についても精度以外の違いは無いように読み取れます。
DHT20とAHT25の主な仕様
【湿度測定】
DHT20
精度:±3%(typical)
再現性:±0.1%RH
ヒステリシス:±1%RH
分解能:0.024%RH(typical)
AHT25
精度:±2%(typical)
以下DHT20と同じ
【温度測定】
DHT20
精度:±0.5℃(typical)
再現性:±0.1℃
ヒステリシス:±0.1℃
分解能:0.01℃
AHT25
精度:±0.3℃(typical)
以下DHT20と同じ
準備
DHT20/AHT25の購入
DHT20はプラスチックケースに入って脚が4本出ている形状です。
0.1インチピッチ(2.54mm間隔)なので、特に気を遣うことはありません。
AHT25はモジュールの状態で、コネクタ付きのケーブルが付属されていました。
下の写真は秋月電子通商で購入したDHT20とAHT25モジュールで、今回はこれらのモジュールを使います。
【DHT20】

【AHT25】

モジュールとRaspberry Piの接続
接続図

接続写真 DHT20


接続写真 AHT25


Raspberry Piの通信設定とPythonの操作方法
Raspberry PiのI2C通信設定を有効にします。
下の記事でRaspberry PiのI2C通信設定と、Pythonの基本操作を説明しています。
I2C通信プログラミング
プログラムコード
Pythonプログラムです。DHT20とAHT25は同じプログラムで動作します。
※修正(2022.4.11)
18行目をコメントアウト
18行目のifがインデントエラーの原因となる為(while 1:でインデントエラー)。
import smbus
import time
# I2C設定
i2c = smbus.SMBus(1)
address = 0x38
#トリガ設定コマンド
set = [0xAC, 0x33, 0x00]
#データ読み込み用
dat = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
# DHT20/AHT25設定
time.sleep(0.1)
ret = i2c.read_byte_data(address, 0x71)
# if ret != 0x18:
# initialization process
# 繰り返し
while 1:
# トリガ測定コマンド送信
time.sleep(0.01)
i2c.write_i2c_block_data(address, 0x00, set)
# データの読み込み
time.sleep(0.08)
dat = i2c.read_i2c_block_data(address, 0x00, 0x07)
# データ変換
hum = dat[1] << 12 | dat[2] << 4 | ((dat[3] & 0xF0) >> 4)
tmp = ((dat[3] & 0x0F) << 16) | dat[4] << 8 | dat[5]
# 物理量変換
hum = hum / 2**20 * 100
tmp = tmp / 2**20 * 200 - 50
# 表示
print("hum: " + str(hum))
print("tmp: " + str(tmp))
time.sleep(1)
プログラムの説明
プログラムの流れです。
- I2C通信の設定をします
- センサーの設定をします
- センサーにトリガ測定コマンドを送ります
- センサーから温湿度データを取得します
- データを物理量に変換し画面に表示します
- 3.~5.を繰り返します。
1.I2C通信の設定をします
# I2C設定
i2c = smbus.SMBus(1)
address = 0x38
i2c = smbus.SMBus(1)
インスタンス生成です。使用するBus1を指定します。
address = 0x38
アドレス指定です。DHT20とAHT25のアドレスはどちらも0x38(16進数)で、通信時に指定します。
Raspberry Piにセンサーを接続した状態で、LXTerminalから「i2cdetect -y 1」コマンドを入力すると、アドレスが0x38であることを確認出来ます。
2.センサーの設定をします
各種設定のときは、データシートで指定された待機時間のウェイトを入れています。
# DHT20/AHT25設定
time.sleep(0.1)
ret = i2c.read_byte_data(address, 0x71)
if ret != 0x18:
# initialization process
time.sleep(0.1)
電源投入後100msec以上待機します。
ret = i2c.read_byte_data(address, 0x71)
0x71でステータスを取得します。取得したステータスが0x18でない場合は、0x1B、0x1C、0x1Dレジスタを初期化します。
※レジスタの初期化方法は、「公式ウェブサイトを参照」とデータシートに記載されています。
残念ながら見つけることが出来なかったので、コメント(#initialization process)にしています。
データシートの『7.4 Sensor Reading Process』で詳細を確認できます。
『公式ウェブサイト』のサンプルプログラム(aht20-21 51mcu demo.zip)をダウンロードしたところ、レジスタの初期化の記述がありました。
トップページの下段の『下载中心』という所からダウンロードページに行けました。
main.cファイルのmain()関数で、ステータスを読み込んだ結果と0x18のandをとってエラー判断をしています。ここでエラーがあった場合にAHT20_Start_Init()をコールしています。この関数がレジスタの初期化関数と思われます。
いずれ、このAHT20_Start_Init()関数を移植して動作確認してみます。
2022.4.11
3.センサーにトリガ測定コマンドを送ります
# トリガ測定コマンド送信
time.sleep(0.01)
i2c.write_i2c_block_data(address, 0x00, set)
time.sleep(0.01)
10msec待機します。
i2c.write_i2c_block_data(address, 0x00, set)
set(トリガ測定コマンド)をセンサーに送ります。
setの中身は、[0xAC, 0x33, 0x00]の3バイトです。
データシートの『7.4 Sensor Reading Process』で詳細を確認できます。
4.センサーから温湿度データを取得します
# データの読み込み
time.sleep(0.08)
dat = i2c.read_i2c_block_data(address, 0x00, 0x07)
time.sleep(0.08)
80msec待機します。
dat = i2c.read_i2c_block_data(address, 0x00, 0x07)
ステータス 8bit、湿度データ 20bit、温度データ 20bit、CRC 8bitの合計56bit(7バイト)を読み込みます。
ステータス 8bit
dat[0]がステータスです。このステータスのbit[7]が0であれば、測定完了を意味します。1であれば測定中です。
このステータスは、80msecの待機を実行すれば0になり、待機時間を短くすると1になることを確認しました。
湿度データ 20bit
dat[1]、dat[2]、dat[3]の上位4bitの合計20bitが湿度データです。
温度データ 20bit
dat[3]の下位4bit、dat[4]、dat[5]の合計20bitが温度データです。
CRC 8bit
CRCは、データ通信中にノイズなどで値が変化してしまった時に、間違いを発見するために使用します。
CRCの詳しい説明はこちら
「巡回冗長検査」(2021年8月21日 (土) 20:49 UTCの版)『ウィキペディア日本語版』
5.データを物理量に変換し画面に表示します
# データ変換
hum = dat[1] << 12 | dat[2] << 4 | ((dat[3] & 0xF0) >> 4)
tmp = ((dat[3] & 0x0F) << 16) | dat[4] << 8 | dat[5]
読み込んだデータは、8bitの入れ物5つに入っています。
これを20bitの湿度データと、20bitの温度データにします。
湿度データ

温度データ

データシートの『7.4 Sensor Reading Process』の『5.Calculate the temperature and humidity value』で詳細を確認できます。
# 物理量変換
hum = hum / 2**20 * 100
tmp = tmp / 2**20 * 200 - 50
データシートで指定された計算で物理量に変換します。
hum = hum / 2**20 * 100
Relative Humidity Conversion
RH[%] = (SRH / 220) × 100%
tmp = tmp / 2**20 * 200 – 50
Temperature Conversion
T[℃] = (ST / 220) × 200 – 50
データシートの『8 Signal Conver』で詳細を確認できます。
# 表示
print("hum: " + str(hum))
print("tmp: " + str(tmp))
print(“hum: ” + str(hum))
測定した湿度と温度を画面に表示します。
5.3.~4.を繰り返します
# 繰り返し
while 1:
while 1:
Stopボタンが押されるまで繰り返します。
※この『while 1:』は、22行目のwhile文です。
プログラムの実行結果
プログラムを実行します。
①Runボタンを押します。
②温度データと湿度データを1秒間隔で画面に表示します。
③Stopボタンを押すとプログラムは終了します。


以上、DHT20およびAHT25モジュールからI2C通信で湿度データと温度データを読み込んで画面に表示するサンプルでした。
まとめ
うまく動作させることは出来たでしょうか?
DHT20とAHT25は同じメーカーではありますが、まさかI2C通信のアドレスまで一緒だったのは、びっくりしました。センサー自体は同一で、精度で選別しているのかもしれません。
とりあえず両方を同時に使うことは無いと思うので問題にならないと思います。
プログラミングやソフトウェアの記事です。