MicroPythonでDHT20から温度・湿度を取得

ATOM Lite(ESP32)と温度湿度センサーDHT20を使って温度・湿度をMicroPythonで取得しました。

 

前置き(余談)

先日、PICを秋月電子さんに買いに行きましたが、なんとなくそれだけ買うと交通費がもったいない気がして、色々買ってしまったセンサーの一つです。

温湿度センサ モジュール DHT20 ¥380
https://akizukidenshi.com/catalog/g/gM-16732/

 

ちなみにDHT11、AM2302(旧名DHT22)という同種のセンサーもあって、通信方式が違うのですが、こちらの方が、MicroPythonにドライバーが組み込まれているので取り扱いは簡単だと思います(試していませんが)。DHT20を買ったのは、その前知識がなかったことと、安かったからですね。DHT20の通信方式はI2Cです。

ESP32 用クイックリファレンス
https://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.html#dht-driver

温湿度センサ モジュール DHT11 ¥480
https://akizukidenshi.com/catalog/g/gM-07003/

温湿度センサ モジュール AM2302 ¥950
https://akizukidenshi.com/catalog/g/gM-07002/

 

回路

DHT20はI2C通信で値を取得します。今回はMicroPythonのソフトウェアI2Cを使うので、GPIOは任意のピンが使えますが、G21をSCL、G25をSDAに使いました。

ATOM Lite    DHT20
5V ---------- 1pin
G21(SCL) ---- 4pin
G25(SDA) ---- 2pin
GND --------- 3pin

l
それぞれを直結で、SCLとSDAのプルアップ抵抗もなくて大丈夫みたいです。

 

プログラム

以下を参考にしました。今回使うのはMicroPythonで、参考サイトはPythonですが、そのまま使えるところが多くて良いですね。

温湿度センサーDHT20とAHT25の使い方 Raspberry Pi
https://s-design-tokyo.com/use-dht20-raspberrypi/

 

詳細は参考サイトまたはデータシート(7.4 Sensor Reading Process)を見るのが良いと思いますが、要点を書きますと、下記になります。

【プログラムの流れ】
・電源を入れて準備完了まで100ms待機
・状態確認(0x71を送って0x18が返ってくるか)
・状態(返り値が0x18じゃない)によっては初期化
・10ms待って測定開始コマンド送信
・測定完了まで80ms待機
・測定データ読み込み(7バイト読み込み)
・測定データを温度・湿度の物理量に変換
・連続で取得する場合は、測定開始コマンドから繰り返す

 

参考サイトにない点として、初期化の処理を加えました。何回かプログラムを回していると、状態確認で、0x18を返してこなくなり、データシートに「initialize the 0x1B, 0x1C, 0x1E registers」っとあったので、試しに空白にしてみたら上手くいきました。

ソース(MicroPython)


from machine import Pin, SoftI2C
import utime

def test():
    i2c = SoftI2C(scl=Pin(21), sda=Pin(25), freq=100000)

    ls = i2c.scan()
    print(ls)
    if len(ls) == 0:
        print('no slave device')
        return
    addr = ls[0] #56 = 0x38
    
    i2c.writeto(addr,b'\x71')
    ret = i2c.readfrom(addr, 1)
    if ret != b'\x18':
        print('init')
        i2c.writeto_mem(addr, 0x1B, b'')
        i2c.writeto_mem(addr, 0x1C, b'')
        i2c.writeto_mem(addr, 0x1E, b'')
        utime.sleep(0.01)
        i2c.writeto(addr,b'\x71')
        ret = i2c.readfrom(addr, 1)
        if ret != b'\x18':
            print('init error')
            return
    
    utime.sleep(0.01)
    i2c.writeto(addr,b'\xAC\x33\x00')
    utime.sleep(0.08)
    dat = i2c.readfrom(addr, 7)
    
    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))

test()

データの変換は、参考サイトのコピペですが、なかったら苦労、っというかできなかっただろうなぁ。感謝!

Updated: 2022年12月6日 — 01:43

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です