5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (24) ディジタル湿度センサ2 独自形式 DHT11

入手性の良い湿度センサ

 ディジタル・データの読み取り方法が独自ですが、安価で入手性の良い温湿度センサDHT11は、DHT22などとプロトコルがよく似ています。センサは有機ポリマが使われています。

DHT11のスペック

  • 動作電圧 3.5~5.5V
  • 湿度 測定範囲 不明、確度 ±5%(25℃時)
  • 温度 測定範囲 不明、確度 ±2℃

 センサの原理もしくは外形が大きいのが理由かもしれませんが、SHT31より反応速度はゆっくりです。

接続

 2番出力は、4.7kΩで3.3Vへプルアップしています。3.3Vは規格外ですが、約±5%は動作上許容範囲と考えます。1-4ピン間に入れた0.1uFの積層セラミック・コンデンサはノイズ取り用ですが、役に立っていないかもしれません。

 写真ではGNDは6番ピンにつないでいます。

データは独自方式

 DHT11は、独自の1-wireの通信方式です。40ビットで構成され、最初の2バイトが湿度、後半の2バイトが温度、最後に8ビットのパリティです。現在のラズパイにはDHT11のデバイス・ドライバが入っています。ターミナルから確認します。

sudo modprobe dht11
lsmod

 このドライバは、Industrial I/O(ioo)と呼ばれるLinuxにセンサなどを利用できるようにするサブシステムで、SPIまたはI2Cを含み、非同期、高速なI/Oもサポートしています。

 組み込めることが確認できたので、/boot/overlaysの中にあるREADMEを開きます。DHT11の組み込み方を参照し、具体的に、/boot/config.txtの最後の行にdtoverlay=dht11を追加します。作業は、

sudo nano /boot/config.txt

 カーソルを動かして最後の行に行き、dtoverlay=dht11と入力し、CTRL-O、リターン、CTRL-Xでnanoエディタを終了し、rebootします。

 DHT11から読み出したデータは、/sys/bus/iio/devices/iio:device0/フォルダに入っています。湿度が書かれたのテキストはin_humidityrelative_input、温度はin_temp_inputです。たんに読み出すだけです。

cat /sys/bus/iio/devices/iio:device0/in_humidityrelative_input

 どのタイミングかはわからないのですが、LOW信号を20ms送るとデータを返してきます。データ波形の例です。

 しかし、頻度高く2種類のエラーが返ってきます。エラーの起こる理由に、20msではなく約30msのLOWを送るため、データを取り込む余裕度がなくなり失敗するというのがあるようです(https://www.spinics.net/lists/linux-iio/msg29901.html)。

 実測すると現在は20msになっています。エラーの原因は別にありそうです。

プログラム

 25℃は25000という整数値で記録されています。とにかく、正常な数値でなければ(エラー出ないとき千倍された値が得られるので、'000'が含まれているという判断)、少し待ってもう一度トライするというスクリプトを作りました。

#!/usr/bin/env python
import commands
import time
while 1:
while 1:
moji = commands.getoutput("cat /sys/bus/iio/devices/iio:device0/in_humidityrelative_input")
if '000' in moji:
print str(int(moji)/1000)+"%"
time.sleep(0.1)
break
else:
continue
while 1:
moji = commands.getoutput("/sys/bus/iio/devices/iio:device0/in_temp_input")
if '000' in moji:
print str(int(moji)/1000)+"C"
time.sleep(0.1)
break
else:
 continue
print "---"
time.sleep(1)

 実行例です。

Webから読み取れるように

#!/usr/bin/env python
import commands
import time
while 1:
while 1:
mojiR = commands.getoutput("cat /sys/bus/iio/devices/iio:device0/in_humidityrelative_input")
if '000' in mojiR :
print str(int(mojiR)/1000)+"%"
time.sleep(0.1)
break
else:
  continue
while 1:
mojiT = commands.getoutput("cat /sys/bus/iio/devices/iio:device0/in_temp_input")
if '000' in mojiT:
print str(int(mojiT)/1000)+"C"
time.sleep(0.1)
break
else:
  continue
print "---"
time.sleep(1)
f = open('index.html','w')
f.write('<span style="font-size:100px;">'+str(int(mojiT)/1000)+"C "+str(int(mojiR)/1000)+"%"+'</span>')
f.close()

 新しくターミナルを立ち上げ、次の1行を入力します。

  python -m SimpleHTTPServer 

 別のPCを用意し、WebブラウザのURLに、

  http://ラズパイのIPアドレス:8000 

でアクセスすると、次のように温湿度が表示できます。新しいデータは手動でリロードします。

※プログラム・リストは、表示の関係でTabキーが無視されるので、スペースに代えてあります。また、リスト中を2回クリックすると全選択になるので、CTRL-Cでコピーし、テキスト・エディタにCTRL-Vで貼り付けて利用してください。ラズパイに持っていくと、リターン・コードなどが化けていることがあるので、一度消して、ラズパイのテキスト・エディタで改行してください。

 プログラムを仮にDHT11.pyとすると、sudo chmod 755 DHT11.py で実行権を付け、ターミナルから、python DHT11.pyで実行します。I2CやSPIのグループにpiユーザが属しているので、sudoは不要です。

※I2Cの有効化は、1-Wireの説明を参照ください。1-Wireと同じく、I2CもEnableにチェックを入れています。

※参考URL http://wiki.52pi.com/images/f/f6/13.How_to_use_DHT11_temperature_sensor_to_detect_the_temperature_in_the_room.pdf