以前から気温や湿度を定期的に測定していますが,測定結果を見るにはCGIのWebページにアクセスする必要がありました. それらの情報を常時表示できる環境モニターを電子ペーパーを使って作成しました. 最近自宅の消費電力をスマートメーターから収集しているので,それも表示するようにしました.
自宅のLinuxサーバーでグラフ等を描画した画像を用意して,このシステムはそれを定期的(10分毎)に取得して表示するだけです. 人がいない時に表示しても無駄なので,光センサーを使い明るい時だけ動作するようにします.
全体の回路図と電源部の回路図は上のとおりです. 使用したのは,以前使った6インチの電子ペーパー(ED060XC3)で,758x1024ピクセルの解像度があります. ESP32を使い乾電池(単三電池3本)で駆動します.
電子ペーパーはいくつかの電圧を加える必要があります. 前回は既成のDC-DCコンバータを改造して使いましたが今回は専用ICを使いました. 比較的入手しやすかったTPS65185を使いましたが,電池で動作させるにはかなり使いにくいICでした. このICは内部で入力電圧を監視しており,それが2.9Vを下回ると動作を停止します. スリープ時はほとんど電流を消費しませんが,DC-DC変換動作を開始させると瞬間的に0.6V程度の電圧低下を起こします. そのため電池2本(3V)や3.3Vの昇圧DC-DCで動かそうとしましたが無理でした. つまり,このICは3V程度の低い電圧で使うことは想定されていません. リチウムイオン電池やリチウムポリマー電池を使う手もありますが過放電防止が必要になり,また年に1度しかバッテリーを交換しないような機器に二次電池を使うのは無駄です. 結局,単三アルカリ電池3本で動作させることにしました. 電源部の回路図はTPS65185の評価ボードのデータシートとほぼ同じですが,手元にあったチップダイオードを使ったところ基板サイズが大きくなってしまいました. ESP32に与える電圧は,消費電流の少ないレギュレータICのTCR3UF33Aを使って生成します. シリーズレギュレータを使うため,電源電圧との差分は無駄になってしまいます.
周囲が明るい時だけ動作させるために光センサーとしてCdSを使いました. またバッテリーの電圧を測定するためESP32のADCを使いますが,電源電圧がADCの入力範囲を越えるので,電圧を落とすためにLEDを入れています. スリープ時に電流を消費しないように未使用時はCdSとLEDのGNDはハイインピーダンスとしていますが,LEDはこの際の電流の逆流防止も兼ねています.
配線を行った基板と,電子ペーパーを写真立てに収めた状態を下に示します.
前述のとおり,このシステムはあらかじめ用意された画像を表示するだけのものです. 自宅のWebサーバー上にcronで定期的に画像データを生成しておき,それをHTTPで一定時間ごとに取得して表示します. 画像を表示する際に,バッテリーの残量を表すアイコンを重ね合わせます. 人がいるときだけ表示するために,明るさがしきい値以上の時だけ画面更新を行い,それ以外ではESP32はディープスリープしています. ちなみに画像取得の際にHTTPのGETコマンドで画像URLの後にオプションとして現在のバッテリー電圧と光センサーの値を渡しています. これはサーバー側では無視されますが,Apacheのログでセンサーの値を確認できるようにするためにこのようにしてあります.
ESP32のホールセンサーを使って,磁石を近づけて電源を入れた場合には設定モードで起動します. 設定モードの最中はLEDが点滅し,Keyに"QUIT"を入力するか5分たつと設定モードを終了します. 設定モードではSoftAPでWebサーバー(SSIDは"ESP32",パスワードは"12345678")として動作し,http://192.168.0.1/にアクセスして下記の表の値を設定することができます.
SSID | アクセスポイントのSSID |
PASS | アクセスポイントのパスワード |
CHAN | アクセスポイントのチャンネル |
URL | 取得する画像ファイルのURL |
WAKEUP | 光センサーのしきい値 |
SLEEP | 情報更新間隔(秒) |
今回表示する画像データは白黒2値としました. 画像を効率よく無線LANで転送してRAM上に保持するために圧縮する必要があります. 下の表に,いくつかのフォーマットで今回使う画像を圧縮した結果を示します.
フォーマット | ファイルサイズ(byte) |
PBM (無圧縮) | 97,292 |
GIF | 24,895 |
TIFF (CCITT G4) | 18,466 |
PNG | 14,442 |
ここでは比較的圧縮率が高くて実装が簡単な,FAXで使われるCCITT Group 4圧縮のTIFFフォーマットを使うことにしました.
Linux上で画像データを生成する際は,PythonのPillowライブラリを使い,
image.save('OUTPUT.tif', compression='group4', tiffinfo={262: 0})
として保存します. CCITT G4圧縮は固定のハフマン符号によるランレングス圧縮を使いますが,白色と黒色で異なるFAX画像に最適化された符号表を用いるため,tiffinfoのオプションを付けないと色を反転させて保存するために圧縮率が悪化します.
CCITT G4で圧縮された画像をESP32上で復号するライブラリを書きました. 比較的シンプルなアルゴリズムなので,メインの関数は60行程度です. 静的ハフマン符号はこちらのスクリプトで有限オートマトンに変換して扱いました. 一つ手こずった問題として,ImageMagickやPillow (おそらくlibtiff)で生成したCCITT G4圧縮のTIFFファイルに,G4圧縮では存在しないはずのEOL (000000000001)コードが入ってるというものがありました. どうやらEOFBという2つの連続したEOLコードによりバイト境界を合わせることがあるようなので,入力にそのコードが出現した場合に対処するようにしています.
10分毎に起動して,WiFiの通信に900ms,電子ペーパーの書き換えに1200msほどかかります. スリープ時の消費電流は全体で14μAでした. 電源電圧が3.5Vまでは動作するはずであり,光センサーによる節電効果が高いと思われるので1年以上電池が持てばよいと考えています.
実際に各種センサーの情報を表示させたのが上の例です. 消費電力・温度・湿度・気圧を1日と1週間のグラフで表示していますが,グラフが小さくて少し見にくいです. 数字だけを大きく表示した方が見やすいかもしれません.
(2023-06-08追記) ちょうど1年ほど経過したところで電池が切れたので交換しました. また最近センサーをもう一つ増やしたので,サーバー側の画像表示スクリプトも変更しました.