概要
田んぼ用リモートカメラのソフトウェアを実装した。
背景と目的
前回に引き続き、ソフトを実装する。
詳細
1. 基本仕様
1.1 動作の流れ
- 指定時刻に起動
- 初期設定
- 電池電圧計測
- 庫内温度計測
- 撮影
- 画像データ送信
- センサデータ送信
- スリープ
1.1.1 指定時刻に起動
このカメラは、リアルタイムクロックを積んでいないので自分で時刻を判断して起動することができない。そこで、
- センサデータ送信時のレスポンスで、現在時刻をクラウドからもらう
- 次の起動時刻までの時間を計算する
- 起動までの残り時間分だけスリープする
という仕組みにする。(クラウド側から、起動までの残り時間を渡せば、起動時刻をクラウド指示できるがこのカメラの使用用途としては毎日同じ時間に起動すればよいので気にしない。過去に作成した家庭菜園の成長記録用カメラでは、起動までの残り時間を送っている。)
1.2 クラウド側
- 画像データ、センサデータとも、SORACOM Beamで、AWS APIGateway上に作成したエンドポイントに転送する
- 画像データは、事前検証により送信はできるもののSORACOMからのレスポンスステータスコードが400になるが気にしない
2. ESP32
2.1 ツール
- arduino-esp32 v1.0.6 (新しいバージョンだとうまく動かない部分があるため)
2.2 電池電圧計測
A/Dを読み取り、回路構成を考慮して変換するのみ。vbatは読み取り値。電圧の変化範囲が狭いので、4Vでの実測値1522LSBやゲイン32LSB/0.1Vを使う。
return (vbat - 1522.0) / 32.0 * 0.1 + 4.0;
2.3 温度計測
A/D入力を読み、S-8100Bの特性を考慮して電圧-温度変換をすればよいのではあるが、ESP32のA/D入力の非線形性やS-8100Bの絶対精度を考慮しながら、いろいろ悩んだ挙句、
- 2点補正する手段が手元にない
- 私の中での実績的に、A/Dゲイン(LSB/V)誤差がオフセット誤差に比べて大きいため、1点しか補正できない場合ゲイン誤差の補正のみを行うのが妥当
と考え、以下のようなオレオレ補正を入れ、ある程度信頼できる手元の温度計との合致性は向上したので良しとする。
adcは、A/D読み取り値だが、S-8100Bはある程度ノイズがあるため約30回の平均化をしている。
S-8100Bの絶対精度は、mTempOffsetで調整。
// 電圧[V] // ESP32のADC特性(ATT=-11dB) // http://radiopench.blog96.fc2.com/blog-entry-1034.html // // 仕様: 3000LSB=2450mV@-11dB // 標準のADCオフセットは実績的に約-140[LSB] // 標準の傾きは仕様とオフセット実績を考慮すると3140LSB / 2.45V = 1281[LSB/V] // Vadc = (adc - (-140)) / 1281 * mGainAdjust Vadc = (double)(adc + 140.0) / 1281.0 * mAdcAttAdjust; // 温度[C] // S-8100Bの特性 // +30degのとき1.508V(typ) // -8mV/K // T = -(V - 1.508) / 0.008 + 30 temperature = -(Vadc - 1.508) / 0.008 + 30.0 + mTempOffset;
2.4 撮影
撮影は、家庭菜園の成長記録カメラとほぼ同様。解像度の設定だけSXGAに変更する。予備撮影など、オートホワイトバランス機能の癖を考慮した撮影手順が重要。
2.5 画像データ送信
BG96で送信するための基本的なコードは、こちらに従うため、ポイントだけ記載する。
画像データは、jpgファイルのバイナリデータをHTTPのボディに入れて送る。最終的に、AWS APIGatewayで受け取らせるため、Content-Typeヘッダをapplication/octet-streamにする。
ctx.printf("Content-Type: application/octet-stream\n");
また、カメラ個体を識別するIDのような文字列も一緒に送りたいのだが、ボディをバイナリデータにしてしまうと他の文字列データなどを入れにくい。そこで、ヘッダに以下のようなものを追加する。SORACOMの仕様では、受け取ったヘッダはそのまま流すので、AWS側で処理すればよい。
ctx.printf("machineId: %s\n", machineId);
2.6 センサデータ送信
センサデータは、JSONのボディで送信するので、こちらと同じ感じになるので省略。
レスポンスで、先述のスリープ時間を決めるための現在時刻を受け取る。JSONなので、こちらを参考に処理。
2.7 スリープ
リモート水位センサの場合と同様、ESP32のディープスリープを使用する。先述の通り、スリープ時間は、センサデータ送信のレスポンスで受け取った現在時刻からの次回起動目標時刻の差を計算して設定する。
3. クラウド
3.1 画像の受け取り
こちらのようにAPIGatewayでデータを受け取る。Lambdaでは、base64エンコードされた文字列として受け取るので、それをjpgバイナリに戻すようにbase64デコードして、処理してS3に保存する。
3.2 センサデータの受け取り
APIGatewayで、JSONを受け取り、Lambdaで処理してS3に保存する。
4. 動作確認
1週間ほど、テストを行い、毎日同じ時間に画像、センサデータがS3に蓄積されることを確認できた。
まとめと今後の課題
田んぼ用リモートカメラのソフト実装ができた。次は、筐体をしたい。