スイッチサイエンスさんのESP-WROOM-02開発ボード「ESPr Developer」とAmbientで温度、湿度などを周期的に測定する環境モニターを作ります。

実現方法

マイコンボードはESP-WROOM-02開発ボード「ESPr Developer」を使います。コードレスにしたいので、電池駆動とし、データーをWi-Fiで飛ばします。

測定する環境データーは、まずは手頃なところとして気温、湿度、気圧、照度を測ることにしました。気温、湿度、気圧はBosch製のBME280というセンサー一つで測定できます。照度はNJL7502Lというフォトトランジスターを使います。将来は風速、風向、雨量なども測定してみたいですが、それは後の課題とします。
スイッチサイエンスさんの「ESPr」シリーズにはBME280の載った「環境センサシールド」という、まさに環境モニターのためのセンサーボードがありますが、以下の理由で使いませんでした。

  1. あまりに手軽で自作感がない
  2. 電池の減り具合も測定したい

理由2の補足ですが、「ESPr Developer」で使われているESP8266というマイコンにはADコンバーターが一つ内蔵されていて、それで電池の電圧を測ろうとしました。ところが「環境センサシールド」には明るさを測るフォトトランジスターが付いていて、それがADコンバーターにつながっているため、電池の電圧が測れないというものです。

省電力設計

モニターを電池駆動でなるべく長期間動かすために、次のような動作をさせるようにしました。

  • 測定と測定の間はDeep sleepモードで待機し、消費電力を抑える
  • 5分間Deep sleepしたら立ち上がり、センサー値を測定する
  • データー送信は毎回はおこなわず、6回に1回(30分に1回)まとめて送信する
    • Wi-Fiにつなぐのは6回に1回だけで、あとの5回はWi-Fiオフで立ち上げる
  • 何回目の立ち上がりかを判定するために、ESP8266のRTCメモリーを使う
    • RTCメモリーはDeep sleepの間も値を保持してくれるメモリーで、ユーザーエリアが512バイトある
    • 6回分のセンサー値もRTCメモリーに書き込んでおく
  • 6回分のデーターはAmbientのbulk_send()でまとめて送信する
    • bulk_send()は複数件のデーターにそれぞれタイムスタンプが必要
    • bulk_send()には次の形式のデーターを渡します。「時刻(秒)」という部分がタイムスタンプで、協定世界時(UTC)の1970年1月1日00:00:00からの経過秒数です。
{
    “writeKey” : “ライトキー”,
    “data” : [
        {“created” : 時刻(秒), “time” : 1, “d1” : “値”, “d2” : “値”, ...},
        {“created” : 時刻(秒), “time” : 1, “d1” : “値”, “d2” : “値”, ...},
        ...
        {“created” : 時刻(秒), “time” : 1, “d1” : “値”, “d2” : “値”, ...}
    ]
}
  • Wi-Fiに接続したらインターネットのSNTPプロトコルを使って現在時刻を取得し、タイムスタンプにすると共に、RTCメモリーに書き込む
  • Wi-Fiに接続しないで立ち上がった時は、RTCメモリーから前回のタイムスタンプを読み、Deep sleepした時間を足して現在時刻を計算して今回のタイムスタンプとする

ArduinoのSNTPライブラリーでは sntp_get_current_timestamp() という関数で現在時刻を取得します。戻り値は、bulk_send()で必要とするのと同じ協定世界時(UTC)の1970年1月1日00:00:00からの経過秒数です。ESP8266で300秒指定してDeep sleepすると実際には294秒程で起きてきます。実際に300秒で起きてくるよう、補正した時間をDeep sleepに指定しました。このあたりのことは「ESP8266で300秒deepSleepしたら実際に何秒眠るのか調べた」に書きました。

以前、ESP8266とBME280を単3乾電池3本で動かし、5分ごとにデーターを測定して毎回Ambientに送信した時は、56日動きました。今回は送信を6回に1回にまとめているので、6倍とは言わないまでも、倍の100日、3か月以上は動くことを期待しています。

Wi−FiのSSIDやAmbientのチャネルIDなどのパラメーター設定

以前のバージョンではWi-FiのSSID、パスワード、AmbientのチャネルID、ライトキーをプログラム中に記述していました。これだと端末ごとにプログラム中のパラメーターを書き直す必要があり、不便です。そこでWiFiManagerというモジュールを使い、立ち上がった後に外部からこれらのパラメーターを設定するようにしました。

Wi-Fiに接続する際、WiFi.begin(ssid, password);を呼び出す代わりに、WiFiManagerを呼びます。WiFiManagerは、次のような動きでSSIDとパスワードを外部から受け取ります。

  1. 保存されているSSIDとパスワードがあれば、ESP8266をステーションモードにして、そのアクセスポイント(AP)に接続を試みます。
  2. SSIDが保存されていないか、接続に失敗した場合、ESP8266をアクセスポイントモードにして設定ポータルを立ち上げ、SSIDとパスワードが入力されるのを待ちます。
  3. PCやスマホのブラウザーからSSIDとパスワードを入力するとWiFiManagerはESP8266をステーションモードに戻し、設定されたAPに接続します。

WiFiManagerはSSID、パスワードの他に追加情報も設定することができるので、AmbientのチャネルIDとライトキーを設定するようにしました。

パラメーターの設定方法

ESP8266が立ち上がり、Wi−Fiに接続できなかった場合、ESP8266がアクセスポイントモードになります。例えばiPhoneで【設定】→【Wi-Fi】を見ていると、接続可能なAPリストの中に「Ambient setup」が現れます。

「Ambient setup」を選択すると、iPhoneがESP8266に接続し、次のような設定ポータルの画面が表示されます。

ここで一番上の「Configure WiFi」をタップすると、接続可能なAPリストが表示されます。

ESP8266を接続したいAPを選んでタップすると次のような設定画面が表示されます。

選択したAPのパスワードと、AmbientのチャネルID、ライトキーを入力し、「save」をタップします。するとESP8266はステーションモードに戻り、指定された情報を保存し、指定されたAPに接続して、処理を続けます。

回路

ESPr Developerを使うと非常にシンプルな回路になります。SPI接続で温度・湿度・気圧センサーBME280とADコンバーターMCP3002とをつないでいます。また電池の電圧を抵抗で分圧してTout(ADコンバーター)に接続しています。

 

実際に作ったボードの写真です。ブレッドボードを使っています。

プログラム

プログラムは倉橋さんの書かれたものを参考にさせていただきました。倉橋さん、ありがとうございます。

プログラムの大まかな流れは「省電力設計」で説明したものと同じです。開発したプログラムはGithubに公開しました

「SimpleWeatherStation」が今回の環境モニターのプログラムです。この他に「Ambientライブラリー」と「timeライブラリー」が必要です。「Ambientライブラリー」のインストール方法は「Arduino ESP8266で温度・湿度を測定し、Ambientに送ってグラフ化する」をご覧ください。「timeライブラリー」もGithubのページにいき、「Clone or download」ボタンでZIPファイルをダウンロードし、Arduino IDEの「スケッチメニュー」→「ライブラリをインクルード」→「.ZIP形式のライブラリをインストールする」でインストールします。

気象センサーの設置

出来上がったセンサーをベランダに設置します。温湿度センサーを屋外に設置するときは、雨にあたらず、風通しがよく、直射日光にもあたらないカバーが必要になります。「ナチュラル研究所」さんのサイトを参考に、百均で買った植木鉢の受け皿を加工して、パゴダと呼ばれるカバーを作りました。

pagoda

センサー端末と電池をケースに入れ、パゴダの天井に取り付けます。これをベランダの軒下に設置しました。

Ambientでグラフ化

センサーを動かすと、5分間隔で測定したデーターが30分ごとにAmbientに送信されます。Ambientでは気温、湿度、気圧、照度、電池電圧をそれぞれグラフ化しました。
各グラフのヘッダーにある「2016」という数字はグラフに表示するデーター件数です。データーは5分に1件なので
12(件/1時間) x 24(時間) x 7(日) = 2016
で、1週間分のデーターを表示しています。2016年ではありません。
センサーの設置場所も設定しました。

チャネル公開機能を使ってライブデーターを表示しています。

ベランダ気象台@世田谷桜丘