2017年4月1日土曜日

FlashAir+Arduino+Raspberry Piで温湿度計(1):準備〜センサから値を読む

[This report is also available in English]

もくじ
  1. 準備〜センサから値を読む
  2. iSDIOを使いながらSDカードを読む
  3. Arduino から Raspberry Pi に測定値を送る
  4. Raspberry Pi で見える化する〜完成

カミさんが「温湿度計が欲しい」と言うので作ってみました。
Arduino で測定した温湿度計を FlashAir で Raspberry Pi に飛ばして Web 表示します。

【今回のポイント】
  • FlashAir, Arduino, Raspberry Pi を連携させてセンサデータを見える化
  • DHT22 で温度と湿度を計測
  • Arduino で浮動小数を文字列変換
  • FlashAir の iSDIO での WiFi 接続と SD カード読み書きを両立 (次回の記事で解説)
  • Chart.js でバブルチャートを表示 (次回の記事で解説)


完成するとこうなります。


複数の部屋のデータが表示されていますが、温湿度計は1台です。
各部屋の比較をしたいだけなので、1箇所ずつ測定してからデータを重ねました。

温湿度計自体はこんな感じ。
顧客(カミさん)からは「思ってたのと違う」という賛辞をいただきました。



全体設計

Arduino Pro Mini で温湿度センサから温度と湿度を取り出します。
取り出したデータは FlashAir の iSDIO 機能を使って Raspberry Pi に送ります。
最終的に、Raspberry Pi の Web ページでチャートを作って iPad で表示すれば完成です。


iPad から FlashAir に直接接続して Raspberry Pi を省略することも可能ですが、
その場合は Flash Air が WiFi に常時接続することになり電源の消費が激しくなります。

今回の構成にしておくと、FlashAir はデータ送信時だけ WiFi を起動するため、
Arduino をバッテリー駆動にすることができます。
バッテリー駆動なら、戸棚の中などコンセントが無い場所でも測定することができます。

通信シーケンスは次のようになります。


材料

温湿度センサ - DHT22

格安の温湿度センサです。
センサ単体とモジュール化されたものの二種類が市販されています。
値段があまり変わらないのでモジュールがおすすめです。
モジュールの方がプルアップ抵抗が内蔵されていて扱いやすいので。

DHT11 と DHT22 の違いは計測精度です。
DHT22 を使うと、温度・湿度ともに小数値まで測ってくれます。
今回は最終的に整数で丸めてしまうため DHT11 で十分でした。

と言うか、頂き物のセンサセットに入っていたのが DHT11 だったんですけども。


【2017/04/10 追記】
結局、最終的に DHT22 を使いました。
DHT11 と DHT22 を比較すると、有効数字だけでなく
測定精度が全然違いました。

DHT11 と DHT22 でそれぞれ測定した結果のキャプチャを比較するとよく分かります。

左が DHT11 で右が DHT22 です。
測定日が違うので一概には言えませんが、DHT22 の方が場所ごとの差がはっきり分かります。
DHT11 の方はどこを測っても湿度が20%前後になってしまっています。カラッカラ。


Arduino Pro Mini


どこのご家庭にも何個か転がっている Arduino Pro Mini です。
安いです。1個500円以下です。
Arduino UNO 1個で Pro Mini が10個くらい買える勢いです。

また、Pro Mini は RAWピンに 5V 電源を供給すると ACC から 3.3V が出ます。
センサや SD カードは 3.3V が多いですがそのまま繋げられて便利。

FlashAir (W-02以降)

これもどこのご家庭にもある FlashAir です。

今回は iSDIO を使うので W-02 以降必須です。
ストレージとしては設定ファイルを格納する程度なので容量は問いません。

SDカード DIP 化モジュール

今回は秋月電子のモジュールを使いました。
Amazon では同じものを売っていませんが、おそらくこのリンク先のものでも機能は同じかと。

ボタン電池ホルダーとCR2032x2個

このボタン電池ホルダーを使うとCR2032が2個入ります。

CR2032は公称電圧が3Vですが、電流値が大きいと2.5V付近まで電圧が下がります。
参考:CR2032ってどんな電池?主要メーカ7社の比較まとめ

つまり、CR2032を2個直列にして5Vを作り、
Arduino Pro Mini を電池駆動するわけですね。

ただし、今回はあまり真面目に省電力対策をしていませんので、
結構すぐに電池を消耗してしまいます。

長時間動かすのであれば、シリアルモジュール経由で
USBのスマホバッテリーを繋いだ方が経済的。。。

回路図

回路図は非常にシンプル。
単に DHT11 または DHT22 と SD カード を Arduino Pro Mini に繋ぐだけ。
FlashAir ならね!

注意点としては、DHT11 と DHT22 はモジュールのメーカーによって、
VCC と GND のピン配置が反転していることがあります。
誤って接続すると壊れるので、基盤のシルク印刷を要確認。

あと、5V外部電源を Arduino Pro Mini の RAW端子に繋ぎますが、
SDカードとDHT11は3.3V ACCに繋ぐことくらいでしょうか。

電圧を誤ると FlashAir が動きません。
また、電池がヘタって電圧が下がってくると、Arduino は動くのに
FlashAir がランダムにエラーを吐くという気持ち悪いことになります。

Arduino UNO の場合は RAW ではなく Vin 端子、
ACC ではなく 3.3V 端子だと思います。


DHT22で温湿度を測定する

Adafruit のライブラリを使えば簡単に測定できます
最近の Arduino IDE は ZIP アーカイブからライブラリを導入できるようです。
ライブラリのGit hub からダウンロードした ZIP ファイルを Arduino IDE でロードすればOKです。

次のように値を読みます。
DHT11 の場合は read22 を read11 にするだけで、あとは同じです。
#include 

#define DHT_PIN 3
dht DHT;

void setup() { }

void loop() {
  int chk = DHT.read22(DHT_PIN);
  if ( chk != 0 ){
    Serial.println(F("Fail to read humidity."));
    return;
  }
  char humid[8];
  char temp[8];
  char param[32];
  sprintf(param,"H=%s&T=%s",
    ID,dtostrf(DHT.humidity,5,2,humid),dtostrf(DHT.temperature,5,2,temp));
  Serial.print("PARAM:");
  Serial.println(param);
}

ここでは FlashAir で HTTP パラメータを送るために文字列結合しています。
通常のC言語であれば sprintf で繋げば良いだけなのですが、
Arduino の sprintf は浮動小数の出力ができません。

そこで、途中に出てくる「dtostrf」という関数で浮動小数を文字列に変換しています。
dtostrf は次のような仕様です。
 第一引数:変換元の浮動小数
 第二引数:全体の文字数(小数点を含む)
 第三引数:小数点以下の桁数
 第四引数:出力先の文字配列
 返り値:第四引数へのポインタ


次回では FlashAir を SD カードと WiFi 子機の両方として動作させつつ、
Raspberry Pi にデータを収集します。

0 件のコメント:

コメントを投稿