ESP8266 系列芯片提供三种可配置的睡眠模式,针对这些睡眠模式,我们提供了多种低功耗解决方案,用户可以结合具体需求选择睡眠模式并进行配置。三种睡眠模式如下:
ESP8266低功耗解决方案之深度睡眠Deep-sleep:
相对于其他两种模式,系统无法自动进入 Deep-sleep,需要由用户调用接口函数system_deep_sleep 来控制。在该模式下,芯⽚片会断开所有 Wi-Fi 连接与数据连接,进入睡眠模式,只有 RTC 模块仍然⼯工作,负责芯片的定时唤醒。在 Deep-sleep 状态下,GPIO 电平状态可以保持,具有 2 μA 的驱动能⼒。
应用场合:
Deep-sleep 可以用于低功耗的传感器应用,或者大部分时间都不需要进行数据传输的情况。设备可以每隔一段时间从 Deep-sleep 状态醒来测量量数据并上传,之后继续进入Deep-sleep。也可以将多个数据存储于 RTC memory(RTC memory 在 Deep-sleep 模式下仍然可以保存数据),然后一次发送出去。
自动唤醒和外部唤醒:
自动唤醒:在 Deep-sleep 状态下,可以将 GPIO16 (XPD_DCDC) 连接至 EXT_RSTB。计时到达睡眠时间后,GPIO16 输出低电平给 EXT_RSTB 管脚,芯片即可被重置并被唤醒。
外部唤醒:在 Deep-sleep 状态下,可以通过外部 IO 在芯片 EXT_RSTB 管脚上产生⼀一个低电平脉冲,芯片即可被重置并被唤醒。
使能深度睡眠接口:
/**
* @brief Set the chip to deep-sleep mode.
*
* The device will automatically wake up after the deep-sleep time set
* by the users. Upon waking up, the device boots up from user_init.
*
* @attention 1. XPD_DCDC should be connected to EXT_RSTB through 0 ohm resistor
* in order to support deep-sleep wakeup.
* @attention 2. system_deep_sleep(0): there is no wake up timer; in order to wake
* up, connect a GPIO to pin RST, the chip will wake up by a falling-edge
* on pin RST
*
* @param time_in_us deep-sleep time, unit: microsecond
*
* @return null
*/
void esp_deep_sleep(uint32_t time_in_us);
配置深度睡眠接口:
/**
* @brief Call this API before esp_deep_sleep and esp_wifi_init to set the activity after the
* next deep-sleep wakeup.
*
* If this API is not called, default to be esp_deep_sleep_set_rf_option(1).
*
* @param option radio option
* 0 : Radio calibration after the deep-sleep wakeup is decided by byte
* 108 of esp_init_data_default.bin (0~127byte).
* 1 : Radio calibration will be done after the deep-sleep wakeup. This
* will lead to stronger current.
* 2 : Radio calibration will not be done after the deep-sleep wakeup.
* This will lead to weaker current.
* 4 : Disable radio calibration after the deep-sleep wakeup (the same
* as modem-sleep). This will lead to the weakest current, but the device
* can't receive or transmit data after waking up.
*
* @return null
*/
void esp_deep_sleep_set_rf_option(uint8_t option);
提供了以下几种种方案来减少 Deep-sleep 模式的功耗:
============================================================================
1. 设置立即进入 Deep-sleep,缩短设备进入 Deep-sleep 的时间:
void system_deep_sleep_instant(uint32 time_in_us)
2.设置 Deep-sleep 唤醒后不进行射频校准,以缩短芯片初始化的时间和降低芯片初始化时的电流:
void esp_deep_sleep_set_rf_option(uint8_t option)
3.适当降低射频功耗,旧版:修改esp_init_data_default.bin文件
4.使⽤用以下指令修改 BIN ⽂文件,缩短 flash 初始化的时间并降低 flash 初始化时的电流:
python add_low-power_deepsleep_cmd.py ./bin file
5.选择 Flash 型号和工作模式,选择特殊型号的 flash,可明显缩短从 flash 加载固件的时间,例如 ISSI-IS25LQ025。
适当的工作模式,也可以缩短从 flash 加载固件的时间,建议 flash 工作模式尽量选择四线工作模式。
6.设置清空 UART FIFO,减少打印时间,FIFO(先入先出队列列)是 UART 的缓存器器,强制将串行通信的每个字节按照接收的顺序进行传送。FIFO 打印消耗时间较多,尽量避免大量打印。所以在设置休眠前应清空UART FIFO,否则,系统会等待 UART FIFO 打印结束才进入睡眠,将消耗较多时间。
7.集中发包,因为发包动作持续时间短(与睡眠醒来的时间相比)、消耗能量少,建议集中发送数据,在 Deep-sleep 醒来之后,一次发送多个数据包。
===========================================================================
注意:实际测试中发现,由于 Light-sleep 硬件唤醒时间短(约为 3 ms),如果应⽤用场景中设备睡眠时间 <2s,宜采⽤用 Light-sleep ⼯工作模式,更更节省功耗;如果睡眠时间 >2s,则宜采⽤用 Deep-sleep ⼯工作模式,更更节省功耗。
实测:芯片级理论值能达到20uA,但是模组级实测值达到100uA左右,后来与原厂确认了测试方法,的确达到了20uA。
附带示例源码:
/******************************************************************************
* @ 10秒后系统进入深度睡眠模式,外部唤醒
* @ EXT_RSTB 管脚拉低,芯片重置并唤醒
*******************************************************************************/
void app_main(void)
{
for (int timer = 0; timer < 10; timer++) {
ESP_LOGI(TAG, "timer: %d\n",timer);
vTaskDelay(1000 / portTICK_RATE_MS);
}
ESP_LOGI(TAG, "start esp_deep_sleep\n");
/* 发现进入深度睡眠后无法再次烧录固件 */
esp_deep_sleep(0);
}