書きたいこと
M5Paperで時計を作ろうとして電圧の取得でハマったので、覚書。
症状
USB通電時に起動時のみ電圧が取得できて、DeepSleep復帰時は電圧が取得できない
結論
USB通電時とバッテリーモードでは、DeepSleepを行うときの準備が違う。
バッテリーモードでDeepSleepを実行するために必要なコードを、USB通電時に記述すると、
M5.getBatteryVoltage() を M5.RTC.begin() より前で実行するしないと、電圧が取得できない症状が出る。
対策
USB給電時の為のみに、DeepSleepを用いるなら、バッテリーモード時に必要なESP32への電力供給の為の以下のコードは不要(というか書いてはだめ!)
gpio_hold_en((gpio_num_t) M5EPD_MAIN_PWR_PIN);
gpio_deep_sleep_hold_en();
経緯
-
バッテリーモードでUSB給電の時期を知るために M5.getBatteryVoltage() で電圧を取得していた。
-
取得位置は、画面表示の直前、温度や湿度などと同じタイミング。
-
バッテリーモード(シャットダウン動作)時には、普通に取得できた。
-
USB通電時では、起動直後は正しく取得できるが、DeepSleep復帰後には全く取得できなかった。
-
何かが安定していないのかと思い delay(1000) を入れてみたが結果は変わらなかった。
通電時のことなので、取得できなくとも問題がなく、放置していたのだが、どうにも気になり、調べてみた。
#include <M5EPD.h>
void setup() {
uint32_t vol1, vol2;
M5.begin(
false, // bool touchEnable
false, // bool SDEnable
true, // bool SerialEnable
true, // bool BatteryADCEnable
false// bool I2CEnable
);
vol1 = M5.getBatteryVoltage();
M5.RTC.begin(); // <-- これの前後で結果が変わる!!!
vol2 = M5.getBatteryVoltage();
Serial.printf("vol1=%4dmV, vol2=%4dmV\n", vol1, vol2);
int32_t dt = 10;
// 周辺への電力供給を停止
M5.disableEXTPower();
M5.disableEPDPower();
// USB切断時には、ESP32への電力供給を停止して待機
M5.shutdown(dt);
// USB通電時には、こちらを実行
// ESP32への通電を維持
// USB通電時に使用するなら、以下の2行は書いちゃだめ!!!
gpio_hold_en((gpio_num_t) M5EPD_MAIN_PWR_PIN);
gpio_deep_sleep_hold_en();
// 休眠時間を指定
esp_sleep_enable_timer_wakeup(dt * 1000 * 1000); // wakeup every 5secs
// DeepSleep開始
esp_deep_sleep_start();
}
void loop() {
}
プログラムについて
- M5.begin()で引数を明記しているのは、引数なしだと、M5.begin()内部で余分な出力がされているのを抑止するためです。
- M5.begin()直後の、vo1, vol2 M5.RTC.begin()が本体。
- コメント、
// 周辺への電力供給を停止
以降は、一定時間停止するコード。 - USB通電時には、
M5.shutdown()
が素通りすることを利用して、DeepSleepの処理を記述
実行すると
M5EPD initializing...OK
vol1=4298mV, vol2=4298mV
M5EPD initializing...OK
vol1=4298mV, vol2= 0mV
M5EPD initializing...OK
vol1=4300mV, vol2= 0mV
.......
みたいな感じで、リセット直後のみ取得できて、DeepSleep後はM5.RTC.begin()
の前でないと電圧は取得できていないことがわかる。
次に、バッテリーモードでESPに電力供給を行うためのコードをコメントアウトして実行
M5EPD initializing...OK
vol1=4294mV, vol2=4294mV
M5EPD initializing...OK
vol1=4294mV, vol2=4294mV
M5EPD initializing...OK
vol1=4294mV, vol2=4294mV
正しく取得できている
まとめ
バッテリーモードでDeepSleepを実行するための対策がUSB通電時に悪影響を及ぼしているとは思いませんでした。
今回は、
- USB通電時には、DeepSleep
- バッテリーモードでは、シャットダウン
と切り分けましたが、
もし、バッテリー給電時にも、DeepSleepしたい場合には、注意が必要です。
M5Paperでは、USB通電とバッテリー供給を正確に切り分ける事ができないので、
電圧を見て判別するなどして、
ESP32への電力供給のためのコードの実行の是非を判断する必要があります。もしくは、正しいかどうかわかりませんが、M5.RTC.begin()より前で電圧を取得するとか。