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