## 为什么 Deep Sleep 是物联网节点的核心 物联网节点(如传感器、追踪器)通常需要长时间待机,仅在特定时刻采集数据并发送。若让 ESP32 保持 Active 模式,电流高达 80~240mA,电池很快耗尽。而 Deep Sleep 模式下,CPU 和大多数外设关闭,仅保留 RTC 和部分 ULP 协处理器,电流可降至 10μA 左右,功耗降低数千倍。 ## ESP32 电源模式概览 - **Active**:全速运行,电流 80~240mA(取决于 WiFi/蓝牙活动) - **Modem Sleep**:CPU 运行,WiFi/蓝牙关闭,电流约 3~8mA - **Light Sleep**:CPU 暂停,可被外设唤醒,电流约 0.8mA - **Deep Sleep**:CPU 和大部分 RAM 关闭,仅 RTC 和 ULP 工作,电流约 10μA - **Hibernation**:RTC 也关闭,仅保留唤醒引脚,电流约 2.5μA 对于周期性上报的节点,Deep Sleep 是最佳平衡点:既能保留 RTC 计时,又能通过 GPIO 或定时器唤醒。 ## Deep Sleep 的工作原理 进入 Deep Sleep 时,ESP32 会: 1. 保存 RTC 内存(可保留少量数据,如状态变量) 2. 关闭主系统时钟和大部分电源域 3. 仅保留 RTC 定时器、ULP 协处理器(可选)和唤醒源检测电路 唤醒后,系统从复位向量重新启动,`esp_sleep_get_wakeup_cause()` 可判断唤醒原因。 ## 定时唤醒:RTC Timer 配置 RTC 定时器基于内部 150kHz 振荡器,支持微秒级精度,最长可定时约 4 小时(若需更长,可多次循环或使用外部 RTC)。 ### 配置步骤 1. 初始化 NVS(非易失存储)——部分驱动需要 2. 配置唤醒源:`esp_sleep_enable_timer_wakeup(time_in_us)` 3. 可选:配置 GPIO 唤醒(如按键) 4. 调用 `esp_deep_sleep_start()` 进入睡眠 ### 完整代码示例:每 30 秒唤醒一次并打印唤醒原因 ```c #include #include "esp_sleep.h" #include "esp_log.h" #include "nvs_flash.h" #define WAKEUP_PERIOD_US (30 * 1000000) // 30 秒 static const char *TAG = "deep_sleep_demo"; void app_main(void) { // 初始化 NVS(部分外设需要) esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { nvs_flash_erase(); nvs_flash_init(); } // 获取唤醒原因 esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); switch (cause) { case ESP_SLEEP_WAKEUP_TIMER: ESP_LOGI(TAG, "唤醒原因:定时器"); break; case ESP_SLEEP_WAKEUP_EXT0: ESP_LOGI(TAG, "唤醒原因:GPIO 外部触发"); break; default: ESP_LOGI(TAG, "唤醒原因:上电/复位"); } // 模拟传感器读取和上报(此处仅打印) ESP_LOGI(TAG, "采集数据并上报..."); // 配置定时唤醒 ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(WAKEUP_PERIOD_US)); // 可选:配置 GPIO 唤醒(例如 GPIO0 低电平触发) // esp_sleep_enable_ext0_wakeup(GPIO_NUM_0, 0); // 进入 Deep Sleep ESP_LOGI(TAG, "进入 Deep Sleep,%d 秒后唤醒\n", WAKEUP_PERIOD_US / 1000000); esp_deep_sleep_start(); } ``` ### 代码说明 - `esp_sleep_enable_timer_wakeup()` 参数为微秒,可用 `us` 常量或计算得出 - 唤醒后程序从头执行,因此需在 `app_main` 中判断唤醒源 - 打印日志使用 `ESP_LOGI`,但注意串口输出会增加功耗,实际产品中建议关闭日志 ## 降低功耗的额外技巧 - **关闭未用的外设**:进入 Deep Sleep 前,调用 `esp_wifi_stop()`、`esp_bluedroid_disable()` 等关闭 WiFi/蓝牙 - **设置 GPIO 为低功耗状态**:将未使用的 GPIO 配置为下拉或悬空,避免漏电流 - **使用 ULP 协处理器**:在 Deep Sleep 期间,ULP 可执行简单传感器读取,仅在需要时唤醒主 CPU - **优化唤醒周期**:根据业务需求调整定时周期,避免频繁唤醒 - **测量实际功耗**:使用功耗分析仪(如 Nordic PPK)验证,注意不同开发板(如官方 DevKit 的 USB 转串口芯片会额外耗电) ## 注意事项 - **RTC 内存**:Deep Sleep 期间,普通 RAM 数据丢失,若需保留数据,使用 `RTC_DATA_ATTR` 修饰变量 - **定时器精度**:RTC 振荡器受温度影响,长时间定时可能漂移,若需高精度可外接 32.768kHz 晶振 - **唤醒后初始化**:每次唤醒后,外设(如 ADC、I2C)需重新初始化 - **电源电压**:Deep Sleep 电流与供电电压相关,3.3V 时约 10μA,2.5V 时可降至 5μA 以下 - **开发板差异**:部分开发板(如 NodeMCU)带有电源 LED 和稳压器,会增加静态电流,量产时需设计最小系统 ## 总结 ESP32 的 Deep Sleep 模式为物联网节点提供了极低功耗的解决方案。通过合理配置定时唤醒和外部触发,开发者可以轻松实现电池供电的长期运行。本文的示例代码可直接用于项目原型,但实际产品还需结合 ULP、电源管理和硬件设计进一步优化。掌握这些技术,你就能设计出续航以年计的智能传感器节点。