10 - 低功耗设计

ESP32 功耗优化与休眠策略

功耗模式

工作模式对比

模式功耗唤醒源适用场景
正常工作80-170mA-数据处理、通信
浅睡眠0.8mA定时/IO短暂停止
深度睡眠10µA定时/IO/ULP传感器采集
休眠2.5µARTC定时超长续航

功耗测量

#include "esp_sleep.h"
 
// 获取唤醒原因
void print_wakeup_reason(void)
{
    esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
 
    switch (wakeup_reason) {
        case ESP_SLEEP_WAKEUP_UNDEFINED: printf("No wakeup source\n"); break;
        case ESP_SLEEP_WAKEUP_ALL:       printf("Light sleep wakeup\n"); break;
        case ESP_SLEEP_WAKEUP_TIMER:     printf("Timer wakeup\n"); break;
        case ESP_SLEEP_WAKEUP_TOUCH:     printf("Touch wakeup\n"); break;
        case ESP_SLEEP_WAKEUP_ULP:       printf("ULP wakeup\n"); break;
        case ESP_SLEEP_WAKEUP_GPIO:      printf("GPIO wakeup\n"); break;
        case ESP_SLEEP_WAKEUP_UART:      printf("UART wakeup\n"); break;
    }
}

浅睡眠 (Light Sleep)

进入浅睡眠

#include "esp_sleep.h"
 
void light_sleep_demo(void)
{
    // 配置唤醒源 (定时器)
    esp_sleep_enable_timer_wakeup(10 * 1000000);  // 10秒
 
    // 可选:启用 GPIO 唤醒
    gpio_wakeup_enable(GPIO_NUM_4, GPIO_INTR_HIGH_LEVEL);
    esp_sleep_enable_gpio_wakeup();
 
    printf("Entering light sleep...\n");
    esp_light_sleep_start();
 
    printf("Woke up!\n");
}

WiFi 睡眠

void wifi_power_save(void)
{
    // 设置为 Modem 睡眠 (WiFi 保持连接,暂停通信)
    esp_wifi_set_ps(WIFI_PS_MODEM);
 
    // 设置为低功耗 (WiFi 断开,节省更多)
    esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
}

深度睡眠 (Deep Sleep)

基础深度睡眠

#include "esp_sleep.h"
 
void deep_sleep_demo(void)
{
    printf("Entering deep sleep for 60 seconds...\n");
 
    // 配置定时唤醒 (60秒)
    esp_sleep_enable_timer_wakeup(60 * 1000000);
 
    // 进入深度睡眠
    esp_deep_sleep_start();
}

GPIO 唤醒

void deep_sleep_gpio_wakeup(void)
{
    // 配置 GPIO 唤醒 (按钮按下唤醒)
    gpio_wakeup_enable(GPIO_NUM_0, GPIO_INTR_LOW_LEVEL);
    esp_sleep_enable_gpio_wakeup();
 
    printf("Deep sleep with GPIO wakeup\n");
    esp_deep_sleep_start();
}

ULP 协处理器

ULP 编程

// ulp/main.S
.set    ADC_CHANNEL, 1      // GPIO36
.set    SLEEP_TIME, 30000   // 30秒
 
// 初始化 ADC
write    r0, ADC_CHANNEL
write    r1, 0x1
move     r3, 0x40004a00     // SENS_SAR_START_FORCE_REG
st       r1, r3, 0
 
// 读取 ADC
wait     2
move     r3, 0x40004d00     // SENS_SAR_READ_REG
ld       r2, r3, 0
 
// 比较阈值
sub      r2, r2, 1000
jumps    r2, 1, wakeup
 
// 继续休眠
wakeup:
    wake
    halt

ULP C 编程

#include "ulp.h"
#include "esp_sleep.h"
 
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
 
void ulp_init(void)
{
    esp_sleep_enable_ulp_wakeup();
 
    ulp_load_binary(0, ulp_main_bin_start,
                    (ulp_main_bin_end - ulp_main_bin_start));
 
    ulp_run(0);
}

功耗优化技巧

关闭外设

void disable_unused_peripherals(void)
{
    // 关闭 WiFi (不使用时)
    esp_wifi_stop();
 
    // 关闭蓝牙
    esp_bluedroid_disable();
    esp_bt_controller_disable();
 
    // 关闭不使用的 ADC
    adc_power_off();
 
    // 关闭不使用的 Timer
    timer_power_off(TIMER_GROUP_0);
}

动态频率调节

#include "esp_pm.h"
 
void set_cpu_freq(uint32_t freq_mhz)
{
    esp_pm_config_esp32_t config = {
        .max_cpu_freq = (esp_pm_cpu_freq_t)freq_mhz,
        .min_cpu_freq = (esp_pm_cpu_freq_t)80
    };
    esp_pm_configure(&config);
}

电池供电方案

锂电池管理

┌────────────┐
│   锂电池    │
│   3.7V     │
└─────┬──────┘
      │
┌─────▼─────┐     ┌────────────┐
│ TP4056    │────►│   ESP32    │
│ 充电管理   │     │   3.3V    │
└───────────┘     └────────────┘

太阳能供电

┌────────────┐
│  太阳能板   │    ┌────────────┐
│   6V/2W    │───►│   锂电池   │
└────────────┘    │   3.7V    │
                  └─────┬──────┘
                        │
              ┌─────────▼─────────┐
              │  AMS1117-3.3      │
              │  LDO 稳压         │
              └─────────┬─────────┘
                        │
                  ┌─────▼─────┐
                  │   ESP32   │
                  └───────────┘

实际案例:定时采集

#include "esp_sleep.h"
#include "driver/rtc_io.h"
 
#define SENSOR_PIN ADC1_CHANNEL_6
#define SLEEP_TIME_SEC 300  // 5分钟
 
void app_main(void)
{
    // 初始化
    print_wakeup_reason();
    adc_init();
 
    // 采集传感器数据
    int sensor_value = adc1_get_raw(SENSOR_PIN);
    printf("Sensor value: %d\n", sensor_value);
 
    // 上传数据 (WiFi 开启)
    wifi_init_sta();
    connect_wifi();
    upload_data(sensor_value);
    wifi_disconnect();
 
    // 进入深度睡眠
    printf("Entering deep sleep...\n");
    esp_sleep_enable_timer_wakeup(SLEEP_TIME_SEC * 1000000);
    esp_deep_sleep_start();
}

参考资料

官方文档

技术参考

ULP 资源

硬件参考

图片参考

ESP32 功耗模式对比


相关链接

反向链接

进阶学习


下一步