2016年7月1日金曜日

ESP単体で30分のデータをまとめて送信


■RTCメモリ/Ambient■

ESP8266 / ESP-WROOM-02のRTCメモリは、電源つないでおけばdeep sleepの後でも消えない約500バイトのメモリです。フラッシュと違って電池外すと消えちゃいますが、どうせdeep sleepでは電池つなぎっぱなしですし、使っても使わなくても電流消費変わらないので、使わにゃソンです。

で、Ambientは個人の方が開発・運営しておられるデータ可視化サービス。ThingSpeak.comのようなサービスですが、ThingSpeakにはないデータをまとめて送信できるAPIが追加されたとのことで、使ってみました。

■Ambientに登録■

メールアドレスとパスワードをすると、確認メールが届きます。確認メールのリンクをクリックすれば登録完了。

Myチャネル画面で「チャネルを作る」をクリックし、一覧表示されたチャネルのリンクをクリックします。

チャート登録画面でチャネル設定でデータの種類を登録し、グラフの軸となるデータ種別を登録します。チャネル設定のデータの種類は、チャート設定での「データn」と対応しています。

1つのチャートには複数のデータを表示できます。関連のありそうなデータを左右軸に振り分けて登録しましょう。チャート1には温度と湿度と気圧、チャート2には気温と空気質を登録します。左右ごとにスケーリングされるようなので、温度と湿度は左、気圧は右にするといい感じでグラフが3本並びます。

登録の際に「日付指定」をチェックしてください。これがThingSpeakと違うところで、Thing Speakはpostした日時がグラフ横軸になるためある程度貯めておいたデータを一気に送る、ということができません。でも、Ambientはデータに日付フィールドを添付して送ることができるので、ESP-WROOM-02のように送信時に消費電力が著しく増大するマイコンにはとてもありがたい機能です。

1つ注意しなくてはいけないのは、Arduino/ESP SDKの日付シリアルtime_tは、秒単位、Ambientはミリ秒単位だということです。Arduinoはdoubleもlong longを扱えないのでこういう仕様になっているのかもしれませんが、それに気づかずにグラフがおかしい…と悩んでAmbientの運営さんのお手を煩わせてしまったのはこの私ですorz

ということで、シリアル値を送る形式で一度完成していたのですが、W3C似のAmbient文字列に変換してから送るように書き換えました。まぁ送り出しのところ一箇所なので、ちょちょいのちょいw

いずれにしても、サイトのドキュメント見てください。

■Ambientへの送信■

ThingSpeakは、POST一発でデータを送ることができるという簡便さが素晴らしいです。でも、Ambientは、SDKがあります。なので、

ambient.begin(channelId, writeKey, &client);ambient.set(1, "12.34");
ambient.set(2, "45.56");
ambient.send();  //  Ambientにデーターを送信

…これだけです。わはははは。

上記は即時送信の場合ですが、一括送信はJSON形式にする必要があります。時刻はunix time(1970年1月1日 00:00:00からのミリ秒)か文字列日付(YYYY-MM-DD HH:mm:ss.sss)で指定します。データのJSON化ついてはこちらの記事をご覧くださいませ。ほんとにこのライブラリ、使いやすくて素晴らしい。

■ESP-WROOM-02にデータを貯める■

ESPには電源でバックアップされた512byteのRAMが搭載されています。4 byte単位での読み書きが可能なのですが、先頭の4バイトはダメっぽいので508バイトを使います。このメモリについてはこちらのブログで知りました。リファレンスちゃんと隅まで読まないとダメよね…つくづく…。

読み書きの際には、まず初期化が必要なのですが…最初に初期化プログラムを走らせて、それから実際のデータを書き込む、なんてのは面倒だしスマートでないので、初期化されたかどうかをCRCで判断します。RTCメモリに書き込まれたCRCと新たに計算したCRCが一致すれば初期化済です。あとは、データを書き換えるごとにCRCを書き換えてやる必要があります(でないと毎回初期化されちゃいますからね)。CRCの計算ルーチンはこちらのコードを使ってます。

読み書きはこんな感じです。

//
// Storageを読み込む。もしCRCが不一致なら初期化
//
bool readStorageAndInitIfNeeded() {
bool ok = system_rtc_mem_read(kOffset_CRC, &storage, sizeof(storage));
if (!ok) {
Serial.println("readStorageAndInitIfNeeded : mem_read fail");
return ok;
}
int crc = calcCRC();
Serial.print("crc = ");
Serial.print(crc, HEX);
Serial.print(", stored crc = ");
Serial.println(storage.crc, HEX);
if (crc != storage.crc) {
Serial.println("crc mismatch");
memset(storage.uni.buffer, 0, sizeof(storage.uni.buffer));
storage.uni.datas.counter = 0;
storage.uni.datas.nextAdjust = 0;
crc = calcCRC();
Serial.print("new crc = ");
Serial.println(crc, HEX);
storage.crc = crc;
ok = system_rtc_mem_write(kOffset_CRC, &storage, sizeof(storage));
if (!ok) {
Serial.println("readStorageAndInitIfNeeded : write fail");
}
}
Serial.print("read counter = ");
Serial.println(storage.uni.datas.counter);
return ok;
}
bool writeStorage() {
storage.crc = calcCRC();
bool ok = system_rtc_mem_write(kOffset_CRC, &storage, sizeof(storage));
if (!ok) {
Serial.println("Error : writeStorage : system_rtc_mem_write fail");
}
return ok;
}

■ソース全体■

ソースはgithubに上げました(あとで掃除します)。

■Ambient感想■

個人で開発・運営しておられるそうですが、サクサク使える良いものに仕上がっていると思います。日付指定ができると良いな、って言ったの俺だもん俺俺w

でも、贅沢なのがユーザです。下記、ご検討よろしくお願いします:-)
  • チャネル設定した名前がチャート追加画面にも反映される
  • データに色と線種を指定できる
  • Arduino time_t形式でのcreatedタイムスタンプが使える←NEW!

■CM■

スイッチサイエンスさんで発売中の「Board1 ver.1.0」ESP-WROOM-02搭載モジュール、値下げしました。1680->1290円です。どうぞよろしくお願いします。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。