ESP32 の Deep Sleep が 27μA までしか落とせない・・・って 嘆いていた ところ、keynee さんから貴重なコメント を賜りました。
結果として無事に 4μA@3.3V な Hibernation mode に突入させることに成功しましたので、他の方への参考になるよう記事に残します。
#include "esp_deep_sleep.h" #include "soc/rtc_cntl_reg.h" #include "soc/dport_reg.h" #include "soc/i2s_reg.h" #include "soc/sens_reg.h" #include "soc/syscon_reg.h" void setup() { // put your setup code here, to run once: Serial.begin(115200, SERIAL_8N1); Serial.println("Start"); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_MAX, ESP_PD_OPTION_OFF); } void loop() { // put your main code here, to run repeatedly: delay(1000); Serial.println("good night!"); SET_PERI_REG_BITS(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_DTEST_RTC, 0, RTC_CNTL_DTEST_RTC_S); CLEAR_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC); CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); esp_deep_sleep_enable_timer_wakeup(10 * 1000 * 1000); // wakeup(restart) after 10secs esp_deep_sleep_start(); Serial.println("zzz"); // ここは実行されない }
keynee さん直伝の秘技
SET_PERI_REG_BITS(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_DTEST_RTC, 0, RTC_CNTL_DTEST_RTC_S);
CLEAR_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC);
CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU);
の3連投をしたのちに esp_deep_sleep_start() させてやることで、見事に Hibernation mode に移行♪
4.0μA@3.3V | 3.8μA@3.0V |
![]() |
![]() |
ほぼ全停止状態ではありますが RTC は生きてるので「指定時間後に再起動」だけは出来ます。
(上のサンプルだと10秒後に再起動)
ESP8266 のときには、Deep Sleep から抜けて再起動させるときには、IO16 を RST ピンに繋いでおく必要がありましたが、ESP32 ではそーいう作法は必要なく、普通に再起動かかるようです。
ESP8266 の Deep Sleep 10μA でも凄いのに、その半分以下の 4μA とは驚きですねー
(追記)2017/02/23
Arduino-esp32 が更新され、特別な操作なく普通に deep sleep が活用できるようになった模様です。
#include "esp_deep_sleep.h" void setup() { // put your setup code here, to run once: Serial.begin(115200, SERIAL_8N1); Serial.println("Start"); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF); esp_deep_sleep_pd_config(ESP_PD_DOMAIN_MAX, ESP_PD_OPTION_OFF); } void loop() { // put your main code here, to run repeatedly: delay(1000); Serial.println("good night!"); esp_deep_sleep_enable_timer_wakeup(10 * 1000 * 1000); // wakeup(restart) after 10secs esp_deep_sleep_start(); Serial.println("zzz"); // ここは実行されない }
TrueRMS テスターを使って、4.0μA@3.3V、3.8μA@3.0V を確認しました。
(追記)2017/02/26
内蔵 ADC で電源電圧を測定し、低電圧をトリガーにして自発的に Hibernation mode(過放電防止モード)に移行する方法について記事にしました。
詳しくは こちら をどうぞ