ESP32 低功耗蓝牙广播间隔调优:量化连接延迟与功耗的平衡艺术

在物联网设备中,ESP32 凭借其强大的 BLE 功能和低功耗特性成为首选。然而,广播间隔(Advertising Interval)的设置往往被忽视,却直接决定了设备的功耗水平和连接建立速度。本文将带你从原理到实践,量化调优广播间隔,实现性能与功耗的完美平衡。

1. 广播间隔的工作原理

BLE 广播是设备向周围发送数据包的过程,广播间隔(adv_interval)定义了两次广播事件之间的时间。ESP32 的广播间隔范围从 20ms 到 10.24s,可配置为 0.625ms 的整数倍。

  • 广播事件:每个广播事件包含一个或多个广播包,发送在 3 个广播信道(37/38/39)上。
  • 连接延迟:当扫描设备发起连接请求后,连接建立时间取决于广播间隔。间隔越短,连接请求被接收的几率越高,延迟越低。
  • 功耗:广播期间射频模块必须开启,间隔越短,单位时间内开启次数越多,平均电流越大。

量化关系

  • 平均功耗 ≈ (广播事件能量 / 广播间隔) + 基础功耗
  • 连接延迟 ≈ 广播间隔 / 2(平均等待时间)

2. 量化调优方法

2.1 测量工具准备

使用电流探头(如 Nordic Power Profiler Kit)或万用表测量 ESP32 开发板在广播模式下的平均电流。同时,用手机或另一块 ESP32 作为扫描器,记录从开始扫描到连接成功的时间。

2.2 实验设计

设置不同的广播间隔:20ms、100ms、500ms、1s、2s,分别测量平均电流和连接延迟。

示例数据(基于 ESP32-WROOM-32,TX 功率 0dBm)

| 广播间隔 | 平均电流 (mA) | 连接延迟 (ms) | |----------|---------------|---------------| | 20ms | 1.8 | 10 | | 100ms | 0.45 | 50 | | 500ms | 0.12 | 250 | | 1s | 0.07 | 500 | | 2s | 0.04 | 1000 |

可见,功耗与间隔近似成反比,而延迟与间隔成正比。

2.3 调优策略

  • 低功耗场景(如电池供电的传感器):选择 1s 以上间隔,牺牲连接速度。
  • 快速连接场景(如可穿戴设备):选择 20-50ms 间隔,但需接受较高功耗。
  • 动态调整:在待机时使用长间隔,当检测到事件(如按键)时切换为短间隔,连接后恢复长间隔。

3. 代码实现

使用 ESP-IDF 配置广播间隔。

#include "esp_bt.h"
#include "esp_gap_ble_api.h"

// 设置广播间隔为 100ms(160 * 0.625ms)
static void set_adv_interval(uint16_t interval_ms) {
    uint16_t interval = interval_ms * 1000 / 625; // 转换为 0.625ms 单位
    esp_ble_adv_params_t adv_params = {
        .adv_int_min = interval,
        .adv_int_max = interval,
        .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);
}

void app_main() {
    // 初始化 BLE
    esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
    esp_bt_controller_init();
    esp_bt_controller_enable(ESP_BT_MODE_BTDM);
    esp_bluedroid_init();
    esp_bluedroid_enable();

    // 启动广播,间隔 100ms
    set_adv_interval(100);
    esp_ble_gap_start_advertising();
}

动态调优示例

// 按键中断中切换为 20ms 间隔
void on_button_press() {
    set_adv_interval(20);
    esp_ble_gap_start_advertising(); // 重新启动广播
}

// 连接建立后,回调中切换为 1s 间隔
void on_connect(esp_ble_gap_cb_param_t *param) {
    if (param->connect.conn_state == ESP_BLE_GAP_CONN_STATE_CONNECTED) {
        set_adv_interval(1000);
        esp_ble_gap_start_advertising(); // 注意:连接后广播自动停止,需重新启动用于多连接
    }
}

4. 注意事项

  • 广播间隔单位:ESP-IDF 中 adv_int_minadv_int_max 的单位是 0.625ms,且最小值不能小于 20ms(实际为 32 个单位)。
  • 连接参数协商:广播间隔影响连接请求的接收,但连接建立后的连接间隔(connection interval)由连接参数决定,需单独配置。
  • 功耗测量:测量时需关闭 WiFi 和其他外设,否则电流数据不准确。
  • 广播类型:可连接广播(ADV_IND)比不可连接广播(ADV_NONCONN_IND)功耗略高,因为需要监听连接请求。
  • 环境干扰:在拥挤的 2.4GHz 频段,广播包可能丢失,导致连接延迟增加,建议适当缩短间隔或增加重传。

5. 总结

广播间隔是 ESP32 BLE 设计中功耗与延迟的杠杆。通过量化测量,开发者可以明确不同间隔下的性能指标,并根据应用场景选择最优值。动态调整策略能进一步平衡两者,实现智能功耗管理。记住,没有万能的最佳间隔,只有最适合你需求的设置。