Raspberry Piの湿温度センサをDHT11からAM2320に交換しました

我が家の洗面所で暖房ボイラーの消費電力と温度・湿度を計っているRaspberry Pi。そこで使用している温度センサをより高精度なものへ交換しました。

今で使っていたDHT11だと3.3V時の精度が低く、出力も1度刻みなのでM2Xでグラフを見てもガクガクしていて今一つだったのです。

20160626-01

 

DHT11からAM2320へ

そのDHT11を製造しているAosong(Guangzhou) Electronics Co.,Ltd.の最新?温湿度センサがAM2320。DHT11の上位製品であるDHT22にi2c通信モードを足した製品のようで、温度測定範囲は-40℃から80℃とマイナスにも対応、0.1℃刻みで誤差±0.3℃と高性能。
足の間隔が2.54mmピッチのAM2320と1.27mmピッチのAM2321があり、後者を買って「あーっ」っとなってる人が結構多そうな印象。ユニバーサル基盤などで作業しやすいのはAM2320です。

20160626-02

通信はDHT11と同じようにタイムチャートに合わせてデータを取得する1-wireモードもありますが、せっかくなので今回は楽そうで事例も多いi2cを使う事に。データシートはメーカーではなくていつもの秋月電子のページにあります。

その秋月は送料が高かったので、スイッチサイエンスの通販 – Yahoo!ショッピングにて580円+送料全国一律164円で購入。

CからRubyへ

結線やサンプルプログラムなどまるっとRaspberry PIで温度湿度センサーをRubyで動かす – Qiitaを参考にさせていただきました。結線は線が1本増えたのでGPIOから引き直し。Vcc5V、GNDのほかAM2320の2pin(SDA)をピンヘッダの4pinへ、4pin(SCL)を6pinへ。

面倒なので以下rootにて作業しています。i2c-toolsを入れてユーザー作成。piは最初からあるので何か言われる想定。

# apt-get install i2c-tools
# adduser pi i2c

modulesに2行追加します。

# vi /etc/modules
i2c-bcm2708
i2c-dev

モジュールのブラックリストファイル(/etc/modprobe.d/raspi-blacklist.conf)から除外しますが自分はすっからかんでした。もし

blacklist i2c-bcm2708

が入っていれば#でコメントアウトします。ここまできたらリブート。

期待しながらi2cdetectを実行してみます。

# i2cdetect 1
Error: Could not open file `/dev/i2c-1' or `/dev/i2c/1': No such file or directory
# i2cdetect 0
Error: Could not open file `/dev/i2c-0' or `/dev/i2c/0': No such file or directory

うーん。モジュールはロードされてるのに/devが無いっぽい。i2c-toolsを入れなおしてもダメ(今思えばMAKEDEVをaboteしたとかなんとか)。ググったりしているうちにこの記事に出会って思いました。

あれ、コメントアウトもなにも結局i2c自体が有効になってないって事じゃね?
という事で

#raspi-config -> 9 Advanced Options -> A7 I2C

で全部Yes押して有効にすれば

# i2cdetect 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x03-0x77.
Continue? [Y/n]
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- 5c -- -- --
60: -- -- -- -- -- -- -- -- -- -

ちゃんと動きました。今元記事見たら

Raspbianの標準ではi2cが有効になっていないので有効にします。

書いてあるし(ノ∀`)

無事にセンサと窓口が開いた所で、Rubyのプログラムにとりかかります。
Gemでi2cのライブラリをインストール。

gem install i2c

ソースもとりあえずまるごとお借りして実行。

# ruby am2321.rb
nil
nil
nil
[42.8, 26.1]
nil
nil
nil
nil
nil
nil
nil
nil
nil

うーん。このnilの山はいったい。一部温度は取れているようなのだけど・・・

結局データシートや色々な所を調べてみると、ほとんど

s = @device.read(@address, 8, “\x03\x00\x04”)

の結果うまく値が入らずnilを返している模様。最初は通信上のエラーでCRCチェックに漏れているのかと思ったんですが、i2c通信自体となると自分のスキルでは打てる手はなし。

とりあえず目的優先という事でプログラムのループ部分を

  • 値が取れるまでループ
  • 取るのに何回かかったかを別ファイルに書き出し

するように変更しました。

sensor = AM2321.new('/dev/i2c-1')

100.times do
  p sensor.read
  sleep(0.5)
end

から

res = nil
rcount = 0
sensor = AM2321.new('/dev/i2c-1')

while res == nil do
  res = sensor.read
  rcount += 1
  sleep(1)
end

print(res[0], ",", res[1], "\n")
    File.open("/dev/shm/am2320retry-counts.txt","a") do |file|
     file.puts "#{Time.now.strftime("%H:%M:%S")},#{rcount}"
    end

 

[湿度,温度]

の形で入ってくるのでDHT11の時と同じく、”,”でcutしてm2xに投げるシェルを変更してcrontabも入れ替えて完了。cronで動かない・・・と思ったら作った.rbのパーミッションが755になってませんでした。

これで我が家の温度グラフがより詳細に!!

20160626-04

 

最後に取得失敗回数をカウントしたテキストを載せておきます。10分に一回実行し、失敗した場合は内部で1秒ごとにリトライ。結果9割は1回ないし2回で取得ができていますが、時折59回や中には99回もかかったなんてのもあってどうしたらいいのやら。

# tail -f /dev/shm/am2320retry-counts.txt
14:10:04,1
14:20:04,1
14:30:05,1
14:40:05,1
14:51:02,59
15:00:05,2
15:10:05,2
15:20:06,2
15:30:05,1
15:40:04,1
15:50:04,1
16:00:04,1
16:10:05,1
16:20:05,2
16:30:06,2
16:40:04,1
16:50:05,2
17:00:05,2
17:10:05,2
17:20:06,2
17:30:05,2
17:41:43,99
17:50:05,2
18:00:25,21
18:10:06,2
18:20:05,2
18:30:06,2
18:40:05,2
18:50:05,2
19:00:05,2
19:10:05,2
19:20:14,10
19:30:05,2
19:40:05,2
19:50:05,2
20:00:05,2
20:10:06,2
20:20:05,2
20:30:46,43
20:40:05,2
20:50:05,2
21:00:06,2
21:11:02,58
21:20:04,1
21:30:06,2
21:40:05,2
21:50:05,2
22:00:05,2

とりあえず、こんな形でうまく動き始めてくれました。

20160626-03

説明怪しいけどAM2320は一応Amazonでも売ってます。

2 Responses

  1. Velmy 2016/07/25 / 16:20

    最近AM2320を買って、ラズパイ3B + Win10 IoT Core で接続してみました。
    このセンサーは自動的に省電力モードに入るらしく、一度ダミーのコマンドを送信した後、世紀のコマンドを投げることでデータを取得できます。
    また、コマンドを投げた後、15ms待たないとデータの読み取りに失敗するそうです。
    pythonはほとんど触ったことが無いので的外れかもしれませんが、コマンドの送信と受信を1命令で行うのではなく、送信後にウエイトを入れてから受信してみてはどうでしょう。

    • ぶっちー 2016/07/26 / 21:33

      ▽VELMY
      ようこそいらっしゃいました。
      スリープモードは認識があっても15msは盲点でした。
      2回で取れる時もあれば未だに何十回もnilが続く事もあるので、
      read前に15ms入れてみようと思います。
      ありがとうございました。

コメントを残す