# 引言 在嵌入式开发中,低功耗蓝牙(BLE)设备的续航能力往往决定产品成败。ESP32 虽然性能强劲,但其射频活动(广播、扫描、连接事件)是功耗的主要来源。广播间隔(Advertising Interval)和连接参数(Connection Interval、Slave Latency、Supervision Timeout)是开发者最常调整的软件参数。然而,参数如何影响实际电流?如何科学测量?本文基于 ESP32 实测数据,给出对比方法和优化建议。 # 原理:BLE 功耗模型 BLE 的功耗由射频活动时间(Radio On Time)和平均电流决定。 - **广播状态**:设备周期性发送广播包,每次发送持续约 1-2 ms(取决于 PHY 和包长),电流峰值约 30-50 mA(ESP32 在 3.3V 下)。平均电流 = 峰值电流 × 占空比。广播间隔越大,占空比越低,功耗越小。 - **连接状态**:连接事件中,主从设备在指定信道交换数据。连接间隔(Connection Interval)决定事件频率;从机延迟(Slave Latency)允许从机跳过若干事件,进一步降低功耗。但延迟过大会影响数据实时性。 - **其他因素**:CPU 唤醒时间、外设功耗、电源管理(如 ESP32 的 Modem Sleep)也会影响总电流。 # 实测方法 ## 硬件准备 - ESP32-DevKitC 或自定义板(注意:板载 LDO 会增加静态电流,建议使用低功耗 LDO 或直接测量电池端)。 - 高精度万用表(如 Keysight 34461A)或电流探头(如 INA219 模块)。 - 示波器(可选,用于观察电流波形)。 - 稳定的 3.3V 电源(避免 USB 供电噪声)。 ## 软件配置 使用 ESP-IDF v5.x,创建两个示例工程: 1. **广播测试**:仅开启广播,不连接。 2. **连接测试**:作为从机,连接主机(可用手机或另一块 ESP32)。 关键 API: ```c // 设置广播参数 esp_ble_adv_params_t adv_params = { .adv_int_min = 0x20, // 20ms (0x20 * 0.625ms) .adv_int_max = 0x20, .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; esp_ble_gap_config_adv_params(&adv_params); // 设置连接参数(从机侧) esp_ble_gap_set_perf_dev_params(conn_params); // 其中 conn_params 包含 min_conn_int, max_conn_int, slave_latency, timeout ``` ## 测量步骤 1. **基线测量**:设备进入深度睡眠(仅 RTC 运行),记录静态电流。 2. **广播测试**:设置广播间隔为 20ms、100ms、500ms、1000ms,分别测量 10 秒内的平均电流(使用万用表积分模式或记录电流曲线)。 3. **连接测试**:建立连接后,设置连接间隔为 7.5ms、30ms、100ms,从机延迟为 0、4、8,测量平均电流。 4. **数据记录**:每组参数重复 3 次,取平均值,并记录 RSSI 和丢包率(确保连接质量)。 # 实测数据与对比 以下为典型数据(环境:ESP32-WROOM-32,3.3V,TX 功率 0dBm,无外设): | 广播间隔 (ms) | 平均电流 (mA) | 相对功耗 | |---------------|---------------|----------| | 20 | 1.85 | 100% | | 100 | 0.62 | 33% | | 500 | 0.28 | 15% | | 1000 | 0.21 | 11% | | 连接间隔 (ms) | 从机延迟 | 平均电流 (mA) | 备注 | |---------------|----------|---------------|--------------------| | 7.5 | 0 | 2.10 | 高实时性 | | 30 | 0 | 0.85 | 平衡 | | 30 | 4 | 0.45 | 延迟 120ms | | 100 | 8 | 0.22 | 延迟 800ms,低功耗 | **分析**: - 广播间隔从 20ms 增至 1000ms,功耗降低约 89%,但可发现性下降(扫描设备需更长时间)。 - 连接间隔增大 10 倍,功耗降低约 60%;从机延迟进一步降低约 50%。 - 注意:连接间隔 >100ms 时,若数据量较大,吞吐量会显著下降,需权衡。 # 优化建议 - **动态调整**:根据应用场景切换广播间隔。例如,设备待机时用 1000ms 广播,唤醒后临时改为 20ms 以快速被发现。 - **连接参数协商**:从机可请求更优参数,但需主机同意。使用 `esp_ble_gap_update_conn_params()` 在连接后调整。 - **使用 Modem Sleep**:在连接事件之间,ESP32 可进入 Modem Sleep,关闭 RF 和时钟,进一步降低功耗(实测可再降 20-30%)。 - **测量注意事项**:避免使用开发板上的 USB 转串口芯片(如 CP2102),其静态电流可达 2-3mA,会淹没 BLE 功耗。 # 完整代码示例 以下为广播测试的简化代码(ESP-IDF): ```c #include #include "esp_bt.h" #include "esp_bt_main.h" #include "esp_gap_ble_api.h" static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { // 处理事件(略) } void app_main(void) { // 初始化蓝牙 esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); esp_bt_controller_init(); esp_bt_controller_enable(ESP_BT_MODE_BLE); esp_bluedroid_init(); esp_bluedroid_enable(); esp_ble_gap_register_callback(gap_event_handler); // 设置广播数据 esp_ble_adv_data_t adv_data = {0}; adv_data.set_scan_rsp = false; adv_data.include_name = true; adv_data.include_txpower = true; esp_ble_gap_config_adv_data(&adv_data); // 启动广播,间隔 100ms esp_ble_adv_params_t adv_params = { .adv_int_min = 0x100, // 100ms .adv_int_max = 0x100, .adv_type = ADV_TYPE_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; esp_ble_gap_start_advertising(&adv_params); // 主循环保持运行 while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); } } ``` # 注意事项 - **测量时间**:至少测量 10 秒以上,以覆盖广播周期和连接事件的随机性。 - **电源稳定性**:使用低噪声电源,避免电压波动影响电流读数。 - **环境干扰**:在屏蔽箱中测试,避免其他 BLE 设备干扰导致重传,增加功耗。 - **固件优化**:关闭不必要的日志输出(`printf` 会唤醒 CPU),使用 `esp_log_level_set` 降低日志级别。 # 结语 通过实测对比,开发者可以直观地看到广播间隔和连接参数对 ESP32 功耗的影响。合理配置参数,结合动态调整策略,可显著延长电池寿命。建议在项目初期就建立功耗测试流程,避免后期优化困难。希望本文的方法能帮助你在嵌入式开发中做出更优的功耗决策。