余ったからとDHT11で温度ログを取っていたけれど、やっぱり精度が気になる。かといってI2C対応のAM2320は高いなーと迷っていたら、同じ1-wire(シリアル)通信専用のAM2302がDHT11とほぼ同じ値段だったので買ってみました。
AM2302はAmazonが安い
AM2302はDHT22とも書かれる(完全に同じかは不明)DHT11の上位製品。
- 湿度精度:±2%(DHT11は±5%)
- 温度精度:±0.5℃(DHT11は±2℃)
- 分解能:0.1℃/%(DHT11は1℃/%)
その分秋月電子で買うと3倍もの値段がします。
しかしAmazonでは一個543円しかも送料無料。例によって中国からなので予備も含めて2個購入しました。
基盤に固定済みでプルアップ抵抗付き。ジャンパーワイヤもついてきます。
Pythonで読み取るライブラリ
またCでシリアル通信するコード見るのか・・・と苦労していたら、Electric DIYには有名なAdafruitがPythonライブラリを公開してくれています。ありがたや。
Pythonは3系列へ
Pythonは現在の2.7x系が開発終了するとの表示がありました。
今の環境(OpenHabianのフルアプデート済み)ではどちらも利用可能だったので、このセンサーに関してはPython3環境でセットアップしています。
$ python --version Python 2.7.9 $ python3 --version Python 3.4.2 $ ls -l `which python` lrwxrwxrwx 1 root root 9 Mar 28 2015 /usr/bin/python -> python2.7
NodeREDサーバも兼ねてるのでベースのPythonは2のまま。
Adafruit Python DHT Sensor Library
$ sudo git clone https://github.com/adafruit/Adafruit_Python_DHT.git $ sudo apt-get install python3-pip $ sudo pip3 install Adafruit_DHT $ sudo python3 setup.py install
サンプルプログラムを実行してみます。
$ cd Adafruit_Python_DHT/exsample $ sudo python3 ./AdafruitDHT.py Usage: sudo ./Adafruit_DHT.py [11|22|2302] <GPIO pin number> Example: sudo ./Adafruit_DHT.py 2302 4 - Read from an AM2302 connected to GPIO pin #4
パラメータとして1個目にセンサータイプ、2個目にGPIO番号を渡します。
ライブラリはAM2302のみならず、コレまで使ってきたDHT11や別扱いのDHT22も対応。
今回センサーはGPIOヘッダの18ピン目=GPIO24に接続しているので”2302 24″をつけて実行。
$ sudo python3 ./AdafruitDHT.py 2302 24 Temp=21.1* Humidity=30.1%
あっさり動きました。Cのときと違ってすごく楽。
そして小数点まで表示してくれるのはやっぱりイイ。
M2Xにてプロットする
DHT11のCプログラムと出力フォーマットをあわせ、同じシェルスクリプトでM2Xに投げます。
Raspberry Piとセンサで家の消費電力を測ってM2Xでグラフ化する(設置編) | 徒労日記
カンマ区切りの以下のフォーマットを出力。
HH.H,TT.T
HH.H = 湿度
TT.T = 温度
サンプルプログラムの値決め打ちにして、フォーマットをあわせた”am2302.py”が以下。
$ cat am2302.py #!/usr/bin/python # Copyright (c) 2014 Adafruit Industries # Author: Tony DiCola import sys import Adafruit_DHT sensor_args = Adafruit_DHT.AM2302 pin = 24 humidity, temperature = Adafruit_DHT.read_retry(sensor_args, pin) if humidity is not None and temperature is not None: print('{0:0.1f},{1:0.1f}'.format(humidity, temperature)) else: print('Failed to get reading. Try again!') sys.exit(1)
上記を実行し、M2Xに投げるシェルスクリプト”am2302_2_m2x.sh”が以下。
#!/bin/sh humtem=$(python3 /usr/local/etc/Adafruit_Python_DHT/sensor/am2302.py) echo $humtem r_temp=$( echo $humtem | cut -f2 -d',') curl -i -X PUT http://api-m2x.att.com/v2/devices/XXXXXXXXXXXXX/streams/2_temp/value -H "X-M2X-KEY: XXXXXXXXXXXXX" -H "Content-Type: application/json" -d "{ \"value\": \"$r_temp\" }" r_humi=$( echo $humtem | cut -f1 -d',') curl -i -X PUT http://api-m2x.att.com/v2/devices/XXXXXXXXXXXXX/streams/2_humi/value -H "X-M2X-KEY: XXXXXXXXXXXXX" -H "Content-Type: application/json" -d "{ \"value\": \"$r_humi\" }"
テスト実行の結果。いい感じです。
$ sudo ./am2302_2_m2x.sh 30.0,22.1 HTTP/1.1 202 Accepted Content-Type: application/json; charset=UTF-8 X-M2X-VERSION: v2.112.2 Vary: Accept-Encoding X-RateLimit-Limit: 10 X-RateLimit-Remaining: 9 X-RateLimit-Reset: 1552707468 Content-Length: 21 {"status":"accepted"}HTTP/1.1 202 Accepted Content-Type: application/json; charset=UTF-8 X-M2X-VERSION: v2.112.2 Vary: Accept-Encoding X-RateLimit-Limit: 10 X-RateLimit-Remaining: 8 X-RateLimit-Reset: 1552707469 Content-Length: 21
あとはこれを10分毎に実行するようCrontabに書いて完成。
$ sudo crontab -e #h dom mon dow command */10 * * * * /usr/local/etc//Adafruit_Python_DHT/sensor/am2302_2_m2x.sh 2>&1 | logger -t am2302_2_m2x -p local0.info
余談
実行パスの謎
最初のうち、しばらく謎の現象に悩まされました。
それは「exsampleディレクトリからサンプルプログラムを移動させるとエラーになる」というもの。
まず実行するカレントディレクトリは結果に影響しないことを確認。
:/Adafruit_Python_DHT/examples$ python3 AdafruitDHT.py 2302 24 Temp=21.9* Humidity=30.0% :/Adafruit_Python_DHT/examples$ cd .. :/Adafruit_Python_DHT$ python3 examples/AdafruitDHT.py 2302 24 Temp=22.0* Humidity=30.0%
その後、サンプルプログラムをAdafruit_Python_DHTにコピーしてから実行してみます。
:/Adafruit_Python_DHT$ sudo cp examples/AdafruitDHT.py . :/Adafruit_Python_DHT$ python3 AdafruitDHT.py 2302 24 Traceback (most recent call last): File "AdafruitDHT.py", line 41, in <module> humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) File "/usr/local/etc/Adafruit_Python_DHT/Adafruit_DHT/common.py", line 94, in read_retry humidity, temperature = read(sensor, pin, platform) File "/usr/local/etc/Adafruit_Python_DHT/Adafruit_DHT/common.py", line 80, in read platform = get_platform() File "/usr/local/etc/Adafruit_Python_DHT/Adafruit_DHT/common.py", line 55, in get_platform from . import Raspberry_Pi_2 File "/usr/local/etc/Adafruit_Python_DHT/Adafruit_DHT/Raspberry_Pi_2.py", line 22, in <module> from . import Raspberry_Pi_2_Driver as driver ImportError: cannot import name 'Raspberry_Pi_2_Driver' :/Adafruit_Python_DHT$
途端に謎のImportErrorが発生します。
特に各.pyを見ても相対パスなどは書かれていません。なぜに??
フォーラムに答えが
いろいろ探すと同じ様なハマりかたしてる人がいて、そこにこんなリプが
For anyone else facing the same issue that @TiagoGouvea mentioned. Try to run your program from outside the Adafruit_DHT directory that was cloned. It happens because when you run – import Adafruit_DHT It imports the Adafruit_DHT folder in your current directory instead of the one installed in your site-packages directory. When run from anywhere else, it is working fine. Hope this helped. |
あなたが神か。
展開したAdafruit_Python_DHT配下で実行すると、インストールしたsite-packagesディレクトリではなく、直下にあるAdafruit_DHT ディレクトリを参照してしまいエラーになるよ、との事です。
確かに/tmpにコピーして使ったら普通に動きました。
構築中ってつい解凍フォルダ配下で作業したくなるから、そこで見事はハマったわけです。
Cartmanishere commented on 14 Sep 2017