ESP32のMicroPythonで温湿度センサ(DHT11)の読み取り
2020/07/15 categories:ESP32| tags:ESP32|MicroPython|DHT11|
MicroPythonのファームウェアを入れたESP32でDHT11からのデータを読み取ってみました。
DHT11または22用のライブラリがあるのでそれを使うだけでセンサの値を読み取れます。
ピンアサイン
データシートを見てピンアサインを確認します。信号線は2番だけでESP32の34ピンと接続しました。
ソースコード
dhtをimportしてピンを指定してインスタンス化するとセンサが使えるようになります。measure()で測定を行い、temperature()で温度、humidity()が得られます。
from machine import Pin
from time import sleep
import dht
sensor = dht.DHT11(Pin(27))
while True:
try:
sleep(2)
sensor.measure()
temp = sensor.temperature()
hum = sensor.humidity()
temp_f = temp * (9/5) + 32.0
print('Temperature: %3.1f C' %temp)
print('Temperature: %3.1f F' %temp_f)
print('Humidity: %3.1f %%' %hum)
except OSError as e:
print('Failed to read sensor.')
ライブラリをMicroPythonで自作しようとした
上記のライブラリがあるのを知らずにライブラリを自作しようとした軌跡が下記です。タイマーで信号の時間を計測しようとしたところMicroPythonファームを入れたESP32のタイマーは1ms周期だということを知り、信号の長さ計測は諦めました。その後、ESP32でDHT11を使っている人はいないかと調べたらライブラリを見つけてしまったので完全に車輪の再発明ということに気づいてしまいました。結局うまく動作させられませんでしたがDHT11からの受信データと通信手順についてだけ書いておきます。
DHT11からの受信データ
データシートの英単語がいまいちわかりませんでしたが、データのフォーマットは以下の通りで、40データ(8ビットが5つ)が送られてくるようです。
湿度整数データ(8ビット) + 湿度少数データ(8ビット) + 温度整数データ(8ビット) + 温度少数データ(8ビット) + チェックビット(8ビット)
例えば以下のようなデータになるようです
受信データ | 0011 0101 | 0000 0000 | 0001 1000 | 0000 0000 | 0100 1101 |
---|---|---|---|---|---|
内容 | 湿度整数部 | 湿度少数部 | 温度整数部 | 湿度少数部 | パリティビット |
パリティビットは最初の4バイトをすべて足したものと一致しているか確認してデータにビット落ちがないか確認するためのものだそうです。上の例だと下記のように計算結果が一致しているので受信データに抜けはないという判断ができます。
0011 0101 + 0000 0000 + 0001 1000 + 0000 0000 = 0100 1101
整数部と小数部は単純に10進数とすればよいみたいなので、湿度を例に計算すると以下のようになります。
整数:0011 0101=53、少数:0000 0000 → 53.0%RH
DHT11の通信の手順
データシートに記載されている英語を自分なりに解釈したところ、以下のような手順で通信するようです。いまいちわからない表現が多くて合ってるのか微妙です。
- DHT11の電源ONして安定するまで1秒待つ
- マイコンのI/O出力をLOWにセットする(LOWの時間は18<t<30ms)。その後、マイコンのI/Oはプルアップして、DHT11のデータラインもHIGHになり、DHT11の信号を応答するのを待つ
- DHT11は83μsのLOWを出力してから87μsのHIGHを出力する
- その後、DHT11から40ビットのデータが送られてくる。0はLOW:54μs+HIGH:23~27μs、1はLOW:54μs+HIGH:68~74μsとして送信する。
- DHT11が40ビットのデータを出力した後、LOWを54μs出力してから入力状態になり、次のスタートシグナルを待つ
以上のような手順で通信するようで、スタートシグナルを送った後にタイマーを使って送られてくる信号の時間を測定してデータを受信すればいいのかなと思います。1回の通信でどのくらいの時間が掛かるか計算してみたら、データがすべて0の場合3msec、すべて1の場合5msecくらいかかるみたいです。