5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (26) ディジタル湿度センサ4 I2C AM2322
DHT11などと類似の製品です。AM2322は、I2Cインターフェースと独自の1-Wireの2種類のディジタル・インターフェースをもっています。ここではI2Cで利用します。DHT11に比べて一回り小さく、本体からリード線が直接出ているので、基板に実装して使う用途のようです。
AM2322のデータシートは中文しかないようなので、AM2321の英文のデータシートを併用して、データを読み取るプログラムを作ります。
●AM2322のスペック
- 電源電圧 3.1~5.5V
- 湿度 測定範囲 0~99.9%、分解能0.1%、確度±2%(25℃時)
- 温度 測定範囲 -40~+80℃、分解能0.1℃、確度±0.3℃
- インターフェース I2C(100kb/s)または独自1-Wire 40ビット構成
- スレーブ・アドレス 0xb8(8ビット)
- サンプリング間隔 2秒以上
●AM2322のレジスタ
- リード 0x03
- ライト 0x10
- データ・レジスタ 湿度上位;0x00、下位;0x01、温度上位;0x02、下位;0x03
●読み出し手順
マニュアルによれば、最初はスリープしているので、アドレスを送って最大3ms待てば、反応があると書かれています。
◆読み出し時にスレーブ・デバイスAM2322へ送るデータ
Function | スタート・レジスタ | レジスタの個数 |
---|---|---|
0x03 | 0x00 | 0x04 |
◆送ってくるデータ
Function | レジスタの個数 | 湿度 | 温度 | CRC | ||
---|---|---|---|---|---|---|
上位 | 下位 | 上位 | 下位 | |||
0x03 | 0x04 | 1バイト | 1バイト | 1バイト | 1バイト | 2バイト |
◆読み出したデータの変換
湿度、温度とも10倍の整数値データなので、湿度は10で割って%、温度は10で割って℃が得られます。
●接続
4ピンの並びは同社のDHT11などと同じですが、この製品は1.27mmと狭いピッチです。そのままではピンヘッダが使えないので、変換基板を利用して、2.54mmピッチのピンヘッダを付けました。
AM2322 | ラズパイ |
---|---|
SCL | 5番ピン |
GND | 9番ピン |
SDA | 3番ピン |
Vdd | 1番ピン 3.3V |
●プログラム
2017年11月15日現在のOSのバージョンは4.9.61です。
4本のケーブルをラズパイのGPIOと接続し、電源を入れて、ターミナルからi2cdetect -y 1 としても何も検出できません。
湿度の上位バイトが入っている0x00を読み出します。デバイスのスレーブ・アドレスは0xb8とデータシートに書かれています。最後のLSBはI2CではR/Wフラグなので、右に1ビット・シフトした0x5cを使います。
i2cget -y 1 0x5c 0x00
Error: Read Failed
すばやく、もう一度同じ命令を入れます。
そうすると0x80と0x00レジスタをリードしてきます。1回目はスリープから目覚めるために使われ、目覚めた後にリード命令を実行したという流れです。これをプログラムにします。
1回目の命令はエラーになるので、try文を記述しました。そのあとにダミーのリード命令を送ります。しかし、すぐにスリープするらしく、10分ほど動かすと、IOErrorが出ます。そこで、try文を二重にしました。もっとすっきりした記述方法があるかもしれません。
このプログラムは、1時間ほど動かしても温度と湿度を継続して表示しました。パリティ・ビットのCRCは読んでいません。
#!/usr/bin/env python4
import time
import smbus
i2c = smbus.SMBus(1)
addr = 0xb8 >> 1 #5c
while 1:
try:
i2c.read_byte(addr)
except IOError:
try:
# print("wakeup")
i2c.write_i2c_block_data(addr,0x03,[0x00,0x04])
time.sleep(0.003)
data = i2c.read_i2c_block_data(addr,0x03,6)
except IOError:
print("wakeup2")
humidity = (data[2] << 8 | data[3])/10.0
temp = (data[4] << 8 | data[5])/10.0
print temp,"C ",humidity,"%"
time.sleep(1)
f = open('index.html','w')
f.write('<META HTTP-EQUIV="Refresh" CONTENT="1">')
f.write('<span style="font-size:60px;">'+str(temp)+"C "+str(humidity)+"%"+'</span>')
f.close()
新しくターミナルを立ち上げ、次の1行を入力してWebサーバを起動します。
python -m SimpleHTTPServer |
プログラムを仮にam2322.pyと/home/piに保存すると、sudo chmod 755 am2322.py で実行権を付け、ターミナルから、python am2322.pyで実行します。I2CやSPIのグループにpiユーザが属しているので、sudoは不要です。
別のPCを用意し、WebブラウザのURLに、
http://ラズパイのIPアドレス:8000 |
でアクセスすると、次のように温度と湿度が表示できます。1秒ごとにリフレッシュしているので、眺めているだけで、データが更新されます。
※プログラム・リストは、表示の関係でTabキーが無視されるので、スペースに代えてあります。また、リスト中を2回クリックすると全選択になるので、CTRL-Cでコピーし、テキスト・エディタにCTRL-Vで貼り付けて利用してください。ラズパイに持っていくと、リターン・コードなどが化けていることがあるので、一度消して、ラズパイのテキスト・エディタで改行してください。
※I2Cの有効化は、1-Wireの説明を参照ください。1-Wireと同じく、I2CもEnableにチェックを入れています。
※参考 湿度センサを比較しているサイト;http://www.kandrsmith.org/RJS/Misc/Hygrometers/calib_many.html