先日「M5Stamp Pico」について、ESP32の動作周波数を変更したときの消費電流値を調査しました(記事は こちら)。
ディープスリープが使えないような用途において、小型ソーラーパネルで発電した電力で常時稼働させたいというのが調査の目的です。
出力0.5Wの小型ソーラーパネルを使った場合、平均消費電流値が10mA@5V程度までのIoTデバイスなら何とか常時稼働できそうなのに対し、通常はM5Stamp Picoを動作周波数10MHzで動かし、必要なときだけ周波数を上げて「Wi-Fi通信」などの処理を行う、というような使い方をすることで、平均消費電流値を10mA@5V以下に抑えることができる可能性があることがわかりました。
さて、例えば「常に振動を観測し、大きな揺れが生じた時にメール通知する」というような用途なら「M5Stamp Pico」が使えますが、「常に動物の侵入を観測し、動物が侵入した時に写真を撮影する」というような用途であれば、写真を撮影できるカメラデバイスが必要になります。
できるだけ低電力なカメラデバイスが良いのですが、M5Stack社製のカメラデバイスで最もシンプルなものといえば「Unit Cam Wi-Fiカメラ」になります。
ESP32、イメージセンサ以外に搭載されている部品は電源レギュレータとLED程度であり、回路構成が単純で余計な電力消費がなさそうです。
「M5Stamp Pico」にイメージセンサが付いただけという感じです。
ここでは「Unit Cam Wi-Fiカメラ」について、ESP32の動作周波数を変更したときの消費電流値を調査してみたいと思います。
目標は「M5Stamp Pico」のときと同じく「平均消費電流値が10mA@5V以下であること」です。
ディープスリープを使わずに、平均消費電流値を10mA@5V以下に抑えることができれば、出力0.5Wの小型ソーラーパネルで「Unit Cam Wi-Fiカメラ」を常時稼働させることができるかもしれません。
今回使うことを想定しているのは、こちらのソーラーパネルです。
出力0.5Wで、サイズは 55mm × 70mm です。
想定している回路構成は以下のとおりです。ソーラーパネルで発電した電力で単四型Ni-MH電池4本を充電し、そこから「Unit Cam Wi-Fiカメラ」に電源供給しようと考えています。
そのため、単四型Ni-MH電池4本を「Unit Cam Wi-Fiカメラ」の「5V」「GND」端子につなぎ、途中にテスターを入れて消費電流値を測ることにします。
スケッチは「M5Stamp Pico」のときと同じく以下のとおりです。動作周波数を順番に変更して5秒待つだけのもので、他には何も処理を行っていません。
void setup() {
Serial.begin(115200);
setCpuFrequencyMhz(240);
Serial.println("240MHz");
delay(5*1000);
setCpuFrequencyMhz(160);
Serial.println("160MHz");
delay(5*1000);
setCpuFrequencyMhz(80);
Serial.println("80MHz");
delay(5*1000);
setCpuFrequencyMhz(40);
Serial.println("40MHz");
delay(5*1000);
setCpuFrequencyMhz(20);
Serial.println("20MHz");
delay(5*1000);
setCpuFrequencyMhz(10);
Serial.println("10MHz");
delay(5*1000);
Serial.println("Sleep");
esp_sleep_enable_timer_wakeup(5*1000*1000);
esp_deep_sleep_start();
}
void loop() {
}
それぞれの動作周波数のときの消費電流値をテスターで読み取り、グラフ化してみました。
「M5Stamp Pico」の調査をしたときの波形と重ね合わせています。
動作周波数が低い領域では「M5Stamp Pico」より若干大きな値になっていますが、動作周波数が20MHz以下のとき、消費電流値は目標の10mAを下回っています。
ただしこの状態では「Unit Cam Wi-Fiカメラ」のイメージセンサを使うことはできません。
イメージセンサを使用可能にするためには「イメージセンサの初期化」を行う必要があります。また「イメージセンサの初期化」を行ってしまうと、その後はずっと(ディープスリープしても)消費電流値の大きい状態がつづいてしまうことが分かっています。
スケッチに「イメージセンサの初期化」処理を追加しました。
void setup() {
Serial.begin(115200);
init_camera();
Serial.println("Camera init");
delay(5*1000);
setCpuFrequencyMhz(240);
Serial.println("240MHz");
delay(5*1000);
setCpuFrequencyMhz(160);
Serial.println("160MHz");
delay(5*1000);
setCpuFrequencyMhz(80);
Serial.println("80MHz");
delay(5*1000);
setCpuFrequencyMhz(40);
Serial.println("40MHz");
delay(5*1000);
setCpuFrequencyMhz(20);
Serial.println("20MHz");
delay(5*1000);
setCpuFrequencyMhz(10);
Serial.println("10MHz");
delay(5*1000);
Serial.println("Sleep");
esp_sleep_enable_timer_wakeup(5*1000*1000);
esp_deep_sleep_start();
}
void loop() {
}
boolean init_camera() {
: 省略
}
消費電流値の調査結果は以下のとおりです。
ディープスリープ中でも消費電流値は20mA以上となってしまい、前述のソーラーパネルでは全くダメそうです。
これに対し「SCCBインタフェース」というものを使うと、イメージセンサをソフト的にスタンバイモードに移行させることができます(記事は こちら)。
この機能を使って、イメージセンサをスタンバイモードに移行させた状態で同様の調査を行いました。
void setup() {
Serial.begin(115200);
init_camera();
Serial.println("Camera init");
delay(5*1000);
pwdnCamera();
Serial.println("Camera power down");
delay(5*1000);
setCpuFrequencyMhz(240);
Serial.println("240MHz");
delay(5*1000);
setCpuFrequencyMhz(160);
Serial.println("160MHz");
delay(5*1000);
setCpuFrequencyMhz(80);
Serial.println("80MHz");
delay(5*1000);
setCpuFrequencyMhz(40);
Serial.println("40MHz");
delay(5*1000);
setCpuFrequencyMhz(20);
Serial.println("20MHz");
delay(5*1000);
setCpuFrequencyMhz(10);
Serial.println("10MHz");
delay(5*1000);
Serial.println("Sleep");
esp_sleep_enable_timer_wakeup(5*1000*1000);
esp_deep_sleep_start();
}
void loop() {
}
boolean init_camera() {
: 省略
}
void pwdnCamera() {
: 省略
}
結果は以下のとおりです。
消費電流値は小さくなりました。
特に動作周波数が低い領域では、イメージセンサを初期化しなかったときよりも若干小さくなりました。
基本的には「Unit Cam Wi-Fiカメラ」を動作周波数10MHzで動かしておき、必要なときだけ周波数を上げて「イメージセンサの初期化」「写真撮影」「Wi-Fi通信」などの処理を行い、処理が終わったら「イメージセンサをスタンバイモードに移行」してから周波数を10MHzに戻す、というような使い方であれば、平均消費電流値を何とか10mA以下に収めることができるかもしれません。
今後、具体的に検討を進めてみようと思います。
なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。
ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。