关于 ESP32 开发板深度睡眠模式电流 11mA 这件事
在官方渠道购买的 ESP32-Pico-Kit V4.1 的板子,然后尝试了 ESPIDF 官方例程以及 GPT 帮忙生成的 Arduino 和 ESPIDF 的最小代码烧录测量,结果发现通过 USB 测量板子进入深度睡眠之后的电流均为 11mA 多点,和官方说的 10uA 以下有这天然之别,但是看过程也确实在重启,看内存也只有 RTC 内存会保留状态,也就是说模块符合预期,但是结果功耗不符合,哪里出了问题呢?查了一圈,看到两篇相关 的答案:CP2102转换芯片和线性稳压器芯片导致的。
【其实 GPT 告诉我答案了,但是我不是硬件工程师,没法办进一步定位,最后还是 Google 给了我认知范围内的答案!!!】
尝试各种姿势的例程
尝试了各种最小 deepsleep 的例程代码后,直接把板子接到 USB 测量器上,发现都是 11mA 最左右如下:
但是各种现象和功能模块确实是符合预期的,有意思的是,这个过程 GPT 其实已经告诉我答案了,就在第一条,但是我还是没有办法在我能力范围内确定,也被我忽略了接着 Google 找来找去【如果是硬件工程师,可能一下子就知道啥原理以及定位到哪个芯片了】。
直到在 Google 中找到很类似 的,也给出了具体芯片,这时候就基本确定了。
有机会把下面那两个拆掉看下吧,,,【估计就搁置了XD】
最简单的 Arduino 例程
#include <Arduino.h>
#include <esp_sleep.h>
void setup() {
Serial.begin(115200);
// 给串口足够的时间来初始化
delay(1000);
Serial.println("Entering deep sleep for 10 seconds");
// 设置ESP32在10秒后自动唤醒
esp_sleep_enable_timer_wakeup(10 * 1000000);
// 进入深度睡眠
esp_deep_sleep_start();
// 注意:ESP32进入深度睡眠后,不会执行下面的代码
}
void loop() {
// 这里的代码在深度睡眠后不会被执行
}
最简单的 ESPIDF 例程
#include "esp_sleep.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
void app_main() {
// 在进入深度睡眠之前打印一条日志
ESP_LOGI("Sleep", "Entering deep sleep for 10 seconds");
// 设置唤醒设备的条件,这里设置为10秒后自动唤醒
esp_sleep_enable_timer_wakeup(10 * 1000000);
// 进入深度睡眠模式
esp_deep_sleep_start();
// 代码不会执行到这里
}
官方例程
/*
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "driver/rtc_io.h"
#include "nvs_flash.h"
#include "nvs.h"
//#include "deep_sleep_example.h"
#if SOC_RTC_FAST_MEM_SUPPORTED
static RTC_DATA_ATTR struct timeval sleep_enter_time;
#else
static struct timeval sleep_enter_time;
#endif
static void deep_sleep_task(void *args)
{
/**
* Prefer to use RTC mem instead of NVS to save the deep sleep enter time, unless the chip
* does not support RTC mem(such as esp32c2). Because the time overhead of NVS will cause
* the recorded deep sleep enter time to be not very accurate.
*/
#if !SOC_RTC_FAST_MEM_SUPPORTED
// Initialize NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
nvs_handle_t nvs_handle;
err = nvs_open("storage", NVS_READWRITE, &nvs_handle);
if (err != ESP_OK) {
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
} else {
printf("Open NVS done\n");
}
// Get deep sleep enter time
nvs_get_i32(nvs_handle, "slp_enter_sec", (int32_t *)&sleep_enter_time.tv_sec);
nvs_get_i32(nvs_handle, "slp_enter_usec", (int32_t *)&sleep_enter_time.tv_usec);
#endif
struct timeval now;
gettimeofday(&now, NULL);
int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000;
switch (esp_sleep_get_wakeup_cause()) {
case ESP_SLEEP_WAKEUP_TIMER: {
printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms);
break;
}
#if CONFIG_EXAMPLE_GPIO_WAKEUP
case ESP_SLEEP_WAKEUP_GPIO: {
uint64_t wakeup_pin_mask = esp_sleep_get_gpio_wakeup_status();
if (wakeup_pin_mask != 0) {
int pin = __builtin_ffsll(wakeup_pin_mask) - 1;
printf("Wake up from GPIO %d\n", pin);
} else {
printf("Wake up from GPIO\n");
}
break;
}
#endif //CONFIG_EXAMPLE_GPIO_WAKEUP
#if CONFIG_EXAMPLE_EXT0_WAKEUP
case ESP_SLEEP_WAKEUP_EXT0: {
printf("Wake up from ext0\n");
break;
}
#endif // CONFIG_EXAMPLE_EXT0_WAKEUP
#ifdef CONFIG_EXAMPLE_EXT1_WAKEUP
case ESP_SLEEP_WAKEUP_EXT1: {
uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status();
if (wakeup_pin_mask != 0) {
int pin = __builtin_ffsll(wakeup_pin_mask) - 1;
printf("Wake up from GPIO %d\n", pin);
} else {
printf("Wake up from GPIO\n");
}
break;
}
#endif // CONFIG_EXAMPLE_EXT1_WAKEUP
#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
printf("Wake up from touch on pad %d\n", esp_sleep_get_touchpad_wakeup_status());
break;
}
#endif // CONFIG_EXAMPLE_TOUCH_WAKEUP
case ESP_SLEEP_WAKEUP_UNDEFINED:
default:
printf("Not a deep sleep reset\n");
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
#if CONFIG_IDF_TARGET_ESP32
// Isolate GPIO12 pin from external circuits. This is needed for modules
// which have an external pull-up resistor on GPIO12 (such as ESP32-WROVER)
// to minimize current consumption.
rtc_gpio_isolate(GPIO_NUM_12);
#endif
printf("Entering deep sleep\n");
// get deep sleep enter time
gettimeofday(&sleep_enter_time, NULL);
#if !SOC_RTC_FAST_MEM_SUPPORTED
// record deep sleep enter time via nvs
ESP_ERROR_CHECK(nvs_set_i32(nvs_handle, "slp_enter_sec", sleep_enter_time.tv_sec));
ESP_ERROR_CHECK(nvs_set_i32(nvs_handle, "slp_enter_usec", sleep_enter_time.tv_usec));
ESP_ERROR_CHECK(nvs_commit(nvs_handle));
nvs_close(nvs_handle);
#endif
// enter deep sleep
esp_deep_sleep_start();
}
static void example_deep_sleep_register_rtc_timer_wakeup(void)
{
const int wakeup_time_sec = 20;
printf("Enabling timer wakeup, %ds\n", wakeup_time_sec);
ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000));
}
void app_main(void)
{
/* Enable wakeup from deep sleep by rtc timer */
example_deep_sleep_register_rtc_timer_wakeup();
#if CONFIG_EXAMPLE_GPIO_WAKEUP
/* Enable wakeup from deep sleep by gpio */
example_deep_sleep_register_gpio_wakeup();
#endif
#if CONFIG_EXAMPLE_EXT0_WAKEUP
/* Enable wakeup from deep sleep by ext0 */
example_deep_sleep_register_ext0_wakeup();
#endif
#if CONFIG_EXAMPLE_EXT1_WAKEUP
/* Enable wakeup from deep sleep by ext1 */
example_deep_sleep_register_ext1_wakeup();
#endif
#if CONFIG_EXAMPLE_TOUCH_WAKEUP
/* Enable wakeup from deep sleep by touch */
example_deep_sleep_register_touch_wakeup();
#endif
xTaskCreate(deep_sleep_task, "deep_sleep_task", 4096, NULL, 6, NULL);
}
参考链接
- ESP32-DevKitC's DeepSleep is consuming quite a bit of current, so I investigated the cause. : 从 11.8mA 理清到 8.15mA 到 10uA【主要是电源转换芯片和USB转换芯片带来的】
- ESP32正常工作模式和深度睡眠模式的功耗对比
- ESP32 reduced current consumption during DeepSleep by putting HX711 into power down mode.
- ESP32深度睡眠电流怎样低于10uA
- Implementing and Measuring Deep Sleep Power Consumption on ESP32 with ESP-IDF
- Deep Sleep Example
- ESP32 Deep Sleep Tutorial
- ESP32 Sleep Modes & Power Consumption in Each Mode
- Power Consumption Verification
- Deep sleep Power consumption Problem.
- FreeRTOS: ESP32 Deep Sleep
- A Practical Guide To ESP32 Deep Sleep Modes
- Insight Into ESP32 Sleep Modes & Their Power Consumption
- Why is it using so much power while deep-sleeping?
- Deep sleep power consumtion ESP32 devkit
- Current Consumption Measurement of Modules