4. BLE技术基础

在ESP32的Wi-Fi与BLE共存工程中,BLE往往承担配网、设备发现、近场控制与状态同步等职责。要写出稳定的共存代码,必须先理解BLE协议栈的分层结构、GAP与GATT的职责边界,以及广播、扫描、连接参数如何影响射频占用时间。本节从工程视角梳理BLE基础,并落到ESP-IDF的API与角色配置上。

一、BLE协议栈分层:从控制器到应用

BLE协议栈可分为控制器(Controller)与主机(Host)两大部分。控制器负责物理层与链路层,包括射频收发、调制解调、跳频、CRC校验、白名单过滤、广播与连接事件的时序控制;主机负责逻辑链路控制与适配协议(L2CAP)、安全管理(SM)、属性协议(ATT)、通用属性规范(GATT)以及通用访问规范(GAP)。应用层则通过GAP与GATT暴露的接口完成设备发现、连接建立与数据读写。

在ESP32上,控制器由芯片内部硬件与蓝牙协议栈固件实现,主机可运行Bluedroid或NimBLE。Bluedroid功能完整、生态成熟;NimBLE体积更小、内存占用更低,适合与Wi-Fi共存时资源紧张的场景。两者都通过VHCI(虚拟主机控制器接口)与控制器通信,应用层API风格不同,但协议栈分层思想一致。

BLE协议栈分层与ESP32角色配置 应用层 配网服务 / 控制指令 自定义Profile与Service GAP角色 Broadcaster / Observer GATT角色 Server / Client ATT / SM / L2CAP 属性、安全、逻辑通道 Host(Bluedroid / NimBLE) 运行于ESP32应用核 控制器层 HCI / VHCI 主机与控制器命令通道 Link Layer 广播/扫描/连接事件调度 PHY 1M / 2M / Coded 射频与基带 2.4GHz ISM频段 ESP32蓝牙控制器 硬件+固件协同 共存与角色配置 Wi-Fi与BLE时分复用 射频仲裁与优先级 广播间隔 20ms~10.24s 连接参数 Interval / Latency / Timeout MTU与数据长度 影响吞吐与占空比 ESP-IDF API esp_bt / esp_ble_gap / gatt VHCI 配置

二、GAP与GATT:角色与数据模型

GAP定义设备如何被发现、如何建立连接,以及连接后的角色。BLE有四种GAP角色:广播者(Broadcaster)只发送广播;观察者(Observer)只扫描广播;外围设备(Peripheral)作为从设备被连接;中心设备(Central)主动发起连接。ESP32既可配置为Peripheral,也可配置为Central,在配网场景中通常作为Peripheral广播服务,手机作为Central连接并写入Wi-Fi凭据。

GATT定义连接后的数据交互模型。GATT Server持有属性数据库,包含Service、Characteristic、Descriptor等层级;GATT Client通过读写、通知、指示访问这些属性。一个典型配网服务包含一个写特征(接收SSID/密码)和一个通知特征(回传配网结果)。理解UUID、句柄、权限(读/写/通知)与CCCD(客户端特征配置描述符)是调试GATT的关键。

概念 作用 ESP-IDF典型API
GAP广播 让设备可被发现,携带名称与服务UUID esp_ble_gap_config_adv_data()
GAP扫描 发现周围广播设备,用于Central角色 esp_ble_gap_start_scanning()
GATT Server 提供属性数据库,响应读写与订阅 esp_ble_gatts_create_service()
GATT Client 发现服务、读写特征、订阅通知 esp_ble_gattc_open()
连接参数 控制连接事件间隔、从设备延迟与超时 esp_ble_gap_update_conn_params()

三、广播、扫描与连接参数

广播是BLE无连接阶段的通信方式。广播包最大31字节,可包含设备名、服务UUID、厂商自定义数据等。广播间隔越短,被发现越快,但射频占用越高;间隔越长,功耗越低,但发现延迟增加。扫描方可以被动扫描(只监听)或主动扫描(发送扫描请求获取扫描响应)。在Wi-Fi与BLE共存时,广播间隔与Wi-Fi信标、DTIM周期可能产生周期性冲突,需要合理设置。

连接建立后,连接参数决定通信节奏。连接间隔(Connection Interval)是两次连接事件之间的时间,范围7.5ms到4s;从设备延迟(Slave Latency)允许从设备跳过若干连接事件以省电;监督超时(Supervision Timeout)用于判断链路丢失。连接间隔越短,吞吐越高、延迟越低,但功耗与射频占用越大。ESP-IDF中可通过以下方式更新连接参数:

esp_ble_conn_update_params_t params = {
    .min_int = 0x10,   // 最小连接间隔 20ms
    .max_int = 0x20,   // 最大连接间隔 40ms
    .latency = 0,      // 从设备延迟
    .timeout = 400,    // 监督超时 4s
};
esp_ble_gap_update_conn_params(¶ms);
在共存工程中,若Wi-Fi处于高吞吐状态,可适当增大BLE连接间隔,减少射频仲裁冲突;若BLE用于实时控制,则应保持较小连接间隔并提高BLE优先级。

四、ESP-IDF BLE API与角色配置案例

ESP-IDF提供Bluedroid与NimBLE两套主机栈。以Bluedroid为例,初始化流程通常包括:释放经典蓝牙内存、初始化控制器、使能控制器、注册GAP与GATT回调、设置设备名称、配置广播数据、启动广播。若作为Central,则改为注册扫描回调并启动扫描,发现目标后发起连接。

esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&cfg);
esp_bt_controller_enable(ESP_BT_MODE_BLE);
esp_bluedroid_init();
esp_bluedroid_enable();
esp_ble_gap_register_callback(gap_event_handler);
esp_ble_gatts_register_callback(gatts_event_handler);
esp_ble_gap_set_device_name("ESP32_CFG");
esp_ble_gap_config_adv_data(&adv_data);
esp_ble_gap_start_advertising(&adv_params);

角色配置的核心是明确“谁广播、谁扫描、谁提供服务、谁发起连接”。配网场景中,ESP32作为Peripheral与GATT Server,手机作为Central与GATT Client;设备间组网场景中,ESP32也可作为Central扫描并连接传感器Peripheral。两种角色对内存、连接数与射频占用的要求不同,需结合共存策略统一规划。

常见误区:把GAP角色与GATT角色混为一谈。Peripheral通常是GATT Server,但并非绝对;Central也可以作为GATT Server。连接参数也不是越短越好,过短的连接间隔会显著增加Wi-Fi与BLE的射频争用,导致Wi-Fi吞吐下降或BLE丢包。

五、复盘与工程建议

  • 先画清协议栈分层,再定位问题在Host、Controller还是射频共存层。
  • 广播数据控制在31字节内,优先放置设备名与关键服务UUID。
  • 连接参数按业务延迟与功耗需求折中,避免盲目追求低延迟。
  • GATT属性表设计要预留扩展,UUID使用16位或128位需统一规划。
  • 共存场景下记录Wi-Fi吞吐与BLE连接事件日志,用数据验证参数调整效果。

掌握BLE协议栈、GAP/GATT、广播扫描与连接参数,是后续在ESP32上实现Wi-Fi与BLE稳定共存的基础。只有把角色配置、数据模型与射频时序统一考虑,才能在配网、控制与状态同步等场景中获得可预测的工程表现。