ESP32 低功耗模式

  • ESP32 低功耗模式
    • 1 概要
    • 2 Modem-sleep 模式
      • 2.1 API 说明
      • 2.2 应用
    • 3 Light-sleep 模式
      • 3.1 强制 Light-sleep
        • 3.1.1 API 说明
        • 3.1.2 应用
      • 3.2 自动 Light-sleep
        • 3.2.1 API 说明
        • 3.2.2 应用
    • 3.3 Deep-sleep 模式
      • 3.3.1 API 说明
      • 3.3.2 应用
    • 4 唤醒方式
      • 4.1 GPIO
      • 4.2 ULP 协处理器唤醒
      • 4.3 Timer
      • 4.4 UART wakeup (light sleep only)
    • 5 GPIO Hold 功能
    • 6 常见问题
    • 7 不同功耗模式下的功耗

ESP32 低功耗模式

1 概要

ESP32 系列芯片提供三种可配置的睡眠模式,针对这些睡眠模式,我们提供了了多种低功耗解决方案,用户可以结合具体需求选择睡眠模式并进行配置。三种睡眠模式如下:

  • Modem-sleep 模式:CPU 可运行,时钟可被配置。Wi-Fi/蓝牙基带和射频关闭。
  • Light-sleep 模式:CPU 暂停运行,Wi-Fi/蓝牙基带和射频关闭。RTC 存储器和外设以及 ULP 协处理器运行。任何唤醒事件(MAC、主机、RTC 定时器或外部中断)都会唤醒芯片。
  • Deep-sleep 模式:CPU 和大部分外设都会掉电,Wi-Fi/蓝牙基带和射频关闭,只有 RTC 存储器和 RTC 外设以及 ULP 协处理器可以工作。Wi-Fi 和蓝牙连接数据存储在 RTC 中。

三种模式的区别如下:


2 Modem-sleep 模式

目前 ESP32 的 Modem-sleep 仅工作在 Station 模式下,连接路由器后生效。Station 会周期性在工作状态和睡眠状态两者之间切换。
ESP32 通过 Wi-Fi 的 DTIM Beacon 机制与路由器保持连接。在 Modem-sleep 模式下,系统可以自动被唤醒,无需配置唤醒源。

一般路由器的 DTIM Beacon 间隔为 100 ms ~ 1,000 ms。

DTIM (Delivery Traffic Indication Message): 使用无线路由器时无线发送数据包的频率。

在 Modem-sleep 模式下,ESP32 会在两次 DTIM Beacon 间隔时间内,关闭 Wi-Fi 模块电路,达到省电效果,在下次 Beacon 到来前自动唤醒。睡眠时间由路由器的 DTIM Beacon 时间决定。Modem-sleep 模式可以保持与路由器的 Wi-Fi 连接,并通过路由器接收来自手机或者服务器的交互信息。

2.1 API 说明

通过以下接口配置 Modem-sleep 模式,type 可选参数:

  • WIFI_PS_NONE: 不使用 Modem-sleep 模式
  • WIFI_PS_MIN_MODEM: ESP32 接收 Beacon 的间隔与路由器的 DTIM 间隔相同,即 1 个路由器间隔
  • WIFI_PS_MAX_MODEM: ESP32 接收 Beacon 的间隔可由程序进行配置,间隔周期 wifi_sta_config_t 结构体中 listen_interval 值决定,单位为 路由器的 Beacon 间隔,默认值为 3(即 3 个路由器 Beacon 间隔)
typedef enum {WIFI_PS_NONE,        /**< No power save */WIFI_PS_MIN_MODEM,   /**< Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period */WIFI_PS_MAX_MODEM,   /**< Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval parameter in wifi_sta_config_t */
} wifi_ps_type_t;
esp_err_t esp_wifi_set_ps(wifi_ps_type_t type);
  1. type 参数为 WIFI_PS_MAX_MODEM ,ESP32 接收 Beacon 的间隔 listen_interval 配置方法:
#define LISTEN_INTERVAL 3
wifi_config_t wifi_config = {.sta = {.ssid = "SSID",.password = "Password",.listen_interval = LISTEN_INTERVAL,},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());

2.2 应用

Modem-sleep 一般用于 CPU 持续处于工作状态并需要保持 Wi-Fi 连接的应用场景,例如,使用 ESP32 本地语音唤醒功能,CPU 需要持续采集和处理音频数据。


3 Light-sleep 模式

Light-sleep 的工作模式与 Modem-sleep 相似,不同的是,除了关闭 Wi-Fi 模块电路以外,在 Light-sleep 模式下,还会关闭时钟并暂停内部 CPU,比 Modem-sleep 功耗更低。有两种方式使 CPU 进入 Light-sleep 模式:

  • 强制 Light-sleep: 通过调用 API 强制 CPU 进入 Light-sleep 模式,强制进入 Light-sleep 模式后,不能通过路由器接收来自手机或者服务器的交互信息
  • 自动 Light-sleep: 配置为自动休眠方式后,会在 CPU 处于空闲的状态下自动进入 Light-sleep 模式,能通过路由器接收来自手机或者服务器的交互信息

3.1 强制 Light-sleep

参考示例: light_sleep

开发者可以使系统强制进入 Light-sleep 模式,即调用强制 Light-sleep 接口,强制关闭 Wi-Fi 模块电路并暂停内部 CPU。强制休眠后,能通过定时器、 GPIO(RTC IO 和 Digital IO)和 UART 唤醒。从 Light-sleep 唤醒后,会从进入休眠的位置继续执行程序。强制进入 Light-sleep 模式后,可以保持与路由器的 Wi-Fi 连接,但不能通过路由器接收来自手机或者服务器的交互信息。

注意:

  1. 强制 Light-sleep 接口调用后,并不会立即休眠,而是等到系统空闲后才进入休眠,
  1. 强制进入 Light-sleep 模式后,不能接收 IP 网络发送的网络数据。

3.1.1 API 说明

  1. 配置唤醒源后,可使用 esp_light_sleep_start() 函数进入 Light-sleep 模式。在没有配置唤醒源的情况下也可以进入轻度睡眠状态,在这种情况下,芯片将无限期地处于 Light-sleep 模式,直到外部复位。
/* Enter sleep mode */
esp_light_sleep_start();
/* Execution continues here after wakeup */

3.1.2 应用

强制 Light-sleep 模式可用于需要保持与路由器的连接,不需要实时响应路由器发来的数据的场景。

3.2 自动 Light-sleep

参考示例: power_save

开发者可配置系统在空闲时自动进入 Light-sleep 模式,并能在需要 CPU 工作时自动唤醒,无需配置唤醒源。在配置为自动 Light-sleep 后,可以保持与路由器的 Wi-Fi 连接,并通过路由器接收来自手机或者服务器的交互信息,对用户体验没有影响。
通常自动 Light-sleep 会与 Modem-sleep 模式 以及电源管理功能共同使用,电源管理功能允许系统根据 CPU 负载动态调节 CPU 频率以降低功耗。

若系统应用中有小于 DTIM Beacon 间隔时间的循环定时,系统将不能进入 Light-sleep 模式。

3.2.1 API 说明

  1. 通过 esp_err_t esp_pm_configure(const void* vconfig) 接口配置电源管理功能,参数 light_sleep_enable 为 true 时使能自动休眠功能。

使能 自动 Light-sleep 功能,需要使能 CONFIG_FREERTOS_USE_TICKLESS_IDLE 和 CONFIG_PM_ENABLE

#if CONFIG_PM_ENABLE// Configure dynamic frequency scaling:// maximum and minimum frequencies are set in sdkconfig,// automatic light sleep is enabled if tickless idle support is enabled.esp_pm_config_esp32_t pm_config = {.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE.light_sleep_enable = true
#endif};ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
#endif // CONFIG_PM_ENABLE

3.2.2 应用

自动 Light-sleep 模式可用于需要保持与路由器的连接,可以实时响应路由器发来的数据的场景。并且在未接收到命令时,CPU 可以处于空闲状态。比如 Wi-Fi 开关的应用,大部分时间 CPU 都是空闲的,直到收到控制命令,CPU 才需要进行 GPIO 的操作。


3.3 Deep-sleep 模式

参考示例: deep_sleep

相对于其他两种模式,系统无法自动进入 Deep-sleep,需要由用户调用接口函数 esp_deep_sleep_start() 进入 Deep-sleep 模式。在该模式下,芯片会断开所有 Wi-Fi 连接与数据连接,进入 Deep-sleep 模式,只有 RTC 存储器和 RTC 外设以及 ULP 协处理器可以工作。从 Deep-sleep 唤醒后,CPU 将软件复位重启。

3.3.1 API 说明

  1. 配置唤醒源后,可使用 esp_deep_sleep_start() 函数进入 Deep-sleep 模式。在没有配置唤醒源的情况下也可以进入 Deep-sleep 状态,在这种情况下,芯片将无限期地处于 Deep-sleep 模式,直到外部复位。
/* Enter deep sleep */
esp_deep_sleep_start();

3.3.2 应用

Deep-sleep 可以用于低功耗的传感器应用,或者大部分时间都不需要进行数据传输的情况。设备可以每隔一段时间从 Deep-sleep 状态醒来测量数据并上传,之后继续进入 Deep-sleep。也可以将多个数据存储于 RTC memory(RTC memory 在 Deep-sleep 模式下仍然可以保存数据),然后一次发送出去。


4 唤醒方式

针对 强制 Lighe-sleepDeep-sleep 需要配置唤醒源的情况,有以下唤醒方式可以选择:

部分唤醒方式仅支持 Light-sleep

4.1 GPIO

  1. External wakeup (ext0)

    RTC IO 模块包含当其中 一个 RTC IO 的电平为唤醒电平(可配置为逻辑高或低)触发唤醒的逻辑。

    RTC IO 是 RTC 外设电源域的一部分,因此如果使能该唤醒源,RTC 外设将在睡眠期间保持上电状态。在 ESP32 的修订版 0 和 1 中,此唤醒源与 ULP 和触摸唤醒源不兼容。

    由于在此模式下启用了 RTC IO 模块,因此也可以使用内部上拉或下拉电阻。

    esp_sleep_enable_ext0_wakeup() 函数可用于启用此唤醒源。

  2. External wakeup (ext1)

    RTC 控制器包含使用 多个 RTC IO 触发唤醒的逻辑。两个逻辑功能之一可用于触发唤醒:

    • 如果任何一个所选 IO 为高电平,则唤醒(ESP_EXT1_WAKEUP_ANY_HIGH
    • 如果所有选定的 IO 都为低电平,则唤醒(ESP_EXT1_WAKEUP_ALL_LOW

    该唤醒源由 RTC 控制器实现。因此,RTC 外设和 RTC 存储器可以在此模式下断电。

    但是,如果 RTC 外设断电,内部上拉和下拉电阻将被禁用。要使用内部上拉或下拉电阻,请在睡眠期间请求 RTC 外设电源域保持上电。

    esp_sleep_enable_ext1_wakeup() 函数可用于启用此唤醒源。

  3. Touch pad wakeup

    RTC IO 模块包含触摸传感器中断时触发唤醒的逻辑。您需要在芯片开始睡眠之前配置触摸传感器中断。

    当 RTC 外设未被强制上电时,ESP32 的修订版 0 和 1 仅支持此唤醒模式。

    esp_sleep_enable_touchpad_wakeup() 函数可用于启用此唤醒源。

  4. GPIO wakeup (light sleep only)

    除了上面描述的 EXT0 和 EXT1 唤醒源之外,在 Light-sleep 模式下还有一种从外部输入唤醒的方法。通过该唤醒源,每个引脚可以使用 gpio_wakeup_enable() 函数单独配置为高电平或低电平唤醒。与 EXT0 和 EXT1 唤醒源(只能与 RTC IO 一起使用)不同,此唤醒源可用于任何 IO(RTC 或数字)。

    esp_sleep_enable_gpio_wakeup() 函数可用于启用此唤醒源。

4.2 ULP 协处理器唤醒

参考示例: system/ulp

ULP 协处理器可以在芯片处于睡眠模式时运行,并且可以用于轮询传感器,监视 ADC 或触摸传感器值,并在检测到特定事件时唤醒芯片。ULP 协处理器是 RTC 外设电源域的一部分,它运行存储在 RTC 慢速存储器中的程序。如果请求此唤醒模式,RTC 慢速存储器将在睡眠期间启动。在 ULP 协处理器开始运行程序之前,RTC 外设将自动上电; 程序停止运行后,RTC 外设将再次自动关闭。

当 RTC 外设未被强制上电时,ESP32 的修订版 0 和 1 仅支持此唤醒模式。

esp_sleep_enable_ulp_wakeup() 函数可用于启用此唤醒源。

4.3 Timer

RTC 控制器具有内置定时器,可用于在预定义的时间后唤醒芯片。时间以微秒精度指定,但实际分辨率取决于为 RTC SLOW_CLK 选择的时钟源。

此唤醒模式不需要在睡眠期间打开 RTC 外设或 RTC 存储器。

esp_sleep_enable_timer_wakeup() 函数可用于启用此唤醒源。

4.4 UART wakeup (light sleep only)

仅支持 Light-sleep 模式。当 ESP32 从外部设备接收 UART 输入时,通常需要在输入数据可用时唤醒芯片。UART 外设包含一项功能,当看到 RX 引脚上的一定数量的上升沿时,可以将芯片从 Light-sleep 状态唤醒。可以使用 uart_set_wakeup_threshold() 函数设置此上升沿数。请注意,唤醒后 UART 不会接收触发唤醒的字符(及其前面的任何字符)。这意味着外部设备通常需要在发送数据之前向 ESP32 发送额外字符以触发唤醒。

esp_sleep_enable_uart_wakeup() 函数可用于启用此唤醒源。

5 GPIO Hold 功能

每个 IO pad(包括 RTC pad)都有单独的 hold 功能,由 RTC 寄存器控制。pad 的 hold 功能被置上后,pad 在置上 hold 那一刻的状态被强制保持,无论内部信号如何变化,修改 IO_MUX 配置或者 GPIO 配置,都不会改变 pad 的状态。应用如果希望在看门狗超时触发内核复位和系统复位时或者 Deep-sleep 时 pad 的状态不被改变,就需要提前把 hold 置上。

在 Deep-sleep 模式下使用 Hold 功能,可能会增加功耗。并且如果使用内部上拉或下拉电阻,需要在睡眠期间使 RTC 外设电源域保持上电。

在睡眠模式下,部分引脚的电源域可能关掉了,所以无法 Hold 功能无法生效,这时需要确认能否打开电源域。例如:GPIO16、17 会在 light sleep 下关闭电源域 VDD_SDIO,所以无法 Hold,这时需要在 esp_light_sleep_start() 中修改代码打开电源域。

针对 RTC IO,可对单个 RTC Pad 使能 Hold 功能:

rtc_gpio_init(27);
rtc_gpio_set_direction(27, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(27, 1);
rtc_gpio_pullup_en(27);
rtc_gpio_hold_en(27);

针对 数字 IO,会对所有 数字 IO 使能 Hold 功能:

gpio_pad_select_gpio(26);
gpio_set_direction(26, GPIO_MODE_OUTPUT);
gpio_set_level(26, 1);gpio_hold_en(26);
/*When the chip is in Deep-sleep mode, all digital gpio will hold the state before sleep, and when the chip is woken up, the status of digital gpio will not be held.*/
gpio_deep_sleep_hold_en();

6 常见问题

  1. 进入 Deep-sleep 后,功耗较高

    有这些原因可能会导致功耗较高:

  • esp_sleep_enable_ext0_wakeup() 需要打开 RTC 外设,产生额外的 100mA 左右的电流消耗,调用 esp_sleep_enable_ext1_wakeup() 则不需要打开 RTC 外设,即不会产生额外的电流。
  • 在 IDF 3.1.1 前的版本可能存在使用 wifi 并关闭后进入睡眠模式,功耗比未使用 wifi 后进入睡眠模式高 1mA 左右。这种情况下,需要在进入睡眠模式前调用 adc_power_off() 关闭 ADC 以解决这个问题。
  • 使用 Hold 功能保持一个固定电平,可能会增加功耗 1mA 左右,这种情况也是由于打开 RTC 外设导致。
  • 某些 GPIO 漏电,一些 ESP32 IO 具有内部上拉或下拉,默认情况下启用。如果外部电路在 Deep-sleep 模式下驱动此引脚,则由于流过这些上拉和下拉的电流,电流消耗可能会增加。要隔离引脚,防止额外的电流消耗,请调用 rtc_gpio_isolate() 函数。例如:ESP32-WROVER 模组上,外部上拉 GPIO12。GPIO12 在 ESP32 芯片中也有内部下拉。这意味着在 Deep-sleep 中,一些电流将流过这些外部和内部电阻,从而增加电流消耗。
  • 某些 IO 芯片内外电压不匹配,可能会增加电流消耗。如果存在电压不匹配的情况,需要在进入睡眠模式前配置 IO 为 Disable 模式,并使能 Hold 功能。
  1. 使能 自动 Light-sleep 后,功耗较高

    • 存在任务持续运行占用 CPU 资源,导致 CPU 负载过大无法休眠。若是这种情况,请检测是否存在 任务 持续运行,并优化当前应用程序流程使 CPU 能周期性空闲进入 Light-sleep 模式。
    • 若系统应用中有小于 DTIM Beacon 间隔时间的循环定时,系统将不能进入 Light-sleep 模式。
    • 若未使用最新 IDF 3.2 版本,可能会因为某些外设使用(例如:I2C、I2S),导致无法自动进入 Light-sleep 模式。若是这个问题,请更新到最新的 IDF 3.2 版本。
    • 若系统不需要 FreeRTOS 时钟配置为 1000 Hz,可将 FreeRTOS 时钟降低为 100 Hz,可显著降低功耗。
  2. 自动 Light-sleep 调试方法

    • 在 menuconfig 中使能 CONFIG_PM_PROFILING ,如果使能,esp_pm_* 函数将跟踪每个电源管理锁的保留时间,esp_pm_dump_locks 函数将打印此信息。 此功能可用于分析哪些锁阻止芯片进入低功耗状态,并查看芯片在每种省电模式下花费的时间,并应在应用程序中保持禁用状态。
    • 在 menuconfig 中使能 CONFIG_PM_TRACE,如果使能,某些 GPIO 将用于发出 RTOS 滴答,频率切换,进入/退出空闲状态等事件的信号。有关 GPIO 列表,请参阅 pm_trace.c 文件。 此功能旨在用于分析/调试电源管理实现的行为时使用,并应在应用程序中保持禁用状态。

7 不同功耗模式下的功耗

ESP32 学习笔记(二十九) ESP32 低功耗模式相关推荐

  1. ESPIDF开发ESP32学习笔记【电源管理与低功耗模式】

    电源管理 ESP-IDF中集成的电源管理算法可以根据应用程序组件的需求,调整外围总线 (APB) 频率.CPU 频率,并使芯片进入 Light-sleep 模式,尽可能减少运行应用程序的功耗 应用程序 ...

  2. C++语法学习笔记二十九: 详解decltype含义,decltype主要用途

    实例代码 // 详解decltype含义,decltype主要用途#include <iostream> #include <functional> #include < ...

  3. opencv学习笔记二十九:SIFT特征点检测与匹配

    SIFT(Scale-invariant feature transform)是一种检测局部特征的算法,该算法通过求一幅图中的特征点(interest points,or corner points) ...

  4. Mr.J-- jQuery学习笔记(二十九)--属性操作方法(获取属性判断)

    获取 attr() <span class="span1" name="it666"></span> <span class=&q ...

  5. Linux学习笔记二十九——http服务

    基础概念: HTTP:Hyper Text Transfer Protocol 超文本传输协议 versions: HTTP/0.9:只接收GET一种请求方法,只支持纯文本 HTTP/1.0:支持PU ...

  6. python数据挖掘学习笔记】十九.鸢尾花数据集可视化、线性回归、决策树花样分析

    #2018-04-05 16:57:26 April Thursday the 14 week, the 095 day SZ SSMR python数据挖掘学习笔记]十九.鸢尾花数据集可视化.线性回 ...

  7. Python学习笔记(十九)面向对象 - 继承

    Python学习笔记(十九)面向对象 - 继承 一.继承的概念 # 继承:子类继承父类的所有方法和属性# 1. 子类 class A(object):def __init__(self):self.n ...

  8. Mr.J-- jQuery学习笔记(二十八)--DOM操作方法(添加方法总结)

    Table of Contents appendTo appendTo(source, target) 源代码 append prependTo ​ ​ ​ ​ prependTo源码 prepend ...

  9. JavaScript学习(二十九)—JS常用的事件

    JavaScript学习(二十九)-JS常用的事件 一.页面相关事件 onload事件:当页面中所有的标签都加载完成后厨房该事件,格式:window.onload <body><sc ...

  10. 嵌入式系统设计师学习笔记二十八:嵌入式程序设计③——高级程序设计语言

    嵌入式系统设计师学习笔记二十八:嵌入式程序设计③--高级程序设计语言 解释程序和编译程序 编译器的工作阶段示意图 语法错误:非法字符,关键字或标识符拼写错误 语法错误:语法结构出错,if--endif ...

最新文章

  1. 电子商务之表示层分析(九)
  2. Linux ln指令
  3. 窗口分析函数_15_找出第一个元素
  4. 找回丢失的端星网络客户端
  5. .net2.0 orm_Java 8:深入研究速度3.0.1“森林”流ORM
  6. mongodb报错一例
  7. LeetCode MySQL 1581. 进店却未进行过交易的顾客
  8. LaneAF | 利用Affinity Field聚类进行车道线实例分割
  9. 房费制 它 结账BUG
  10. 让我们的linux的shell命令待颜色
  11. mysql处理emoji表情_mysql支持emoji表情存取的解决方案
  12. [RK3288][Android6.0] 如何配置MIPI DSI Clock和PCLK
  13. ARRIS路由器梅林系统救砖
  14. 京东18年管培生—技术方向笔试有感
  15. 小米笔记本pro版bios经常找不到硬盘
  16. 任天堂残酷马里奥游戏
  17. 【哈希链表】 146 LRU、LFU缓存机制
  18. 【十年签证】办理美国签证流程详解
  19. windows日志捕获工具-DebugView使用教程
  20. iphone 微信网页自动播放音频解决办法

热门文章

  1. python绘制隐含波动率曲面_隐含波动率曲面
  2. windows系统VS code coderunner 运行shell脚本
  3. ts重点学习71-implement语句
  4. 干眼能从事计算机工作吗,上班族长时间面对电脑须谨慎干眼症
  5. linux端口映射到内网机器,linux如何将公网IP映射到局域网IP?
  6. R语言入门——rep函数
  7. 关闭OneNote从浏览器复制粘贴时包含链接的方法
  8. 【Spring源码三千问】BeanDefinition详解——什么是 RootBeanDefinition?merged bean definition 又是什么鬼?
  9. 一年代码功能点的创新性怎么写_技术部分创新点-新产品
  10. 大学生论文发表的费用需要多少