概述

[English]

本文档是 ESP32 系列 BLE 应用开发笔记,主要介绍 ESP32 系列 BLE 应用开发的基本概念、开发环境,并基于 NimBLE 重点列举了 BLE 开发过程中普遍适用的一些注意事项,并整理了开发所需的资料文档。

ESP32 系列蓝牙特性介绍

ESP32 有多款芯片支持蓝牙,目前对蓝牙的支持可以分为如下几种:

ESP32 系列芯片蓝牙特性

芯片型号

蓝牙认证版本

功能支持

ESP32

4.2

controller 通过蓝牙 4.2 认证

ESP32-C2

5.3

controller 通过蓝牙 5.3 认证,支持 BLE 5.0 及以下的所有功能

ESP32-S3、ESP32-C3

5.3

controller 通过蓝牙 5.3 认证,支持 BLE 5.0 及以下的所有功能

ESP32-C6、ESP32-H2、ESP32-C61、ESP32-C5

6.0

通过蓝牙 6.0 认证,支持 BLE 5.0 及以下的所有功能,并支持部分 BLE 5.0 以上的功能

关于芯片功能的具体情况可以选择对应芯片并参看 ESP32 系列蓝牙功能支持情况

关于蓝牙协议栈的说明

ESP-IDF 支持两种蓝牙主机协议栈:

  1. Bluedroid:同时支持经典蓝牙与低功耗蓝牙

  2. NimBLE:只支持低功耗蓝牙

两个协议栈的功能一致,但实现上各有优劣,具体如下:

  1. Bluedroid:协议栈架构较为清晰,但内存和固件尺寸占用较大

  2. NimBLE:协议栈实现较为简洁,内存和固件尺寸占用较小。开发者需要对蓝牙协议栈有较深入的了解

两个协议栈均提供了丰富的例程和文档供开发者参考:

本文档主要基于 NimBLE 协议栈,介绍 BLE 开发流程和基本概念。但基本概念和编程思想同样适用于 Bluedroid 协议栈。

BLE 编程的基本概念

基于事件驱动的编程模型:

在 ESP32 的 NimBLE 中,回调机制(callback mechanism)是整个 BLE 应用响应事件的基础。它允许注册一些函数,当特定事件(比如连接建立、断开、接收通知、读写 GATT 特征等)发生时,NimBLE 栈自动调用这些函数进行处理。

BLE 的基本角色(Roles)

在 BLE 中主要有以下几种角色:

  1. 主设备 (Central) - 主动发起连接的设备 - 负责管理连接和数据交换

  2. 从设备 (Peripheral) - 等待被连接的设备 - 提供数据和服务

  3. 广播者 (Broadcaster) - 只发送广播数据 - 不建立连接 - 适用于信标(Beacon)等应用场景

  4. 观察者 (Observer) - 只接收广播数据 - 不建立连接 - 适用于数据采集等场景

在实际应用中,一个设备可以同时支持多个角色。例如,一个智能手表可以作为从设备连接手机,同时又可以作为主设备连接心率带。

GAP(Generic Access Profile)

负责 BLE 设备发现、连接管理、广播等。

GATT(Generic Attribute Profile)

定义 BLE 的数据通信格式。

关于更多 BLE 基本概念的介绍,可以参看 低功耗蓝牙介绍

BLE 编程注意事项:

  1. 确保回调中只处理轻量逻辑。耗时逻辑,复杂逻辑在其它任务中处理。

  2. 避免回调中调用阻塞函数,如 vTaskDelay 等。

协议栈反初始化

NimBLE 协议栈反初始化:

  1. 断开所有连接,关闭广播和扫描

  2. 调用 nimble_port_stop(); 停止 NimBLE 协议栈

  3. 调用 nimble_port_freertos_deinit(); 反初始化 FreeRTOS 相关资源

  4. 调用 nimble_port_deinit(); 反初始化 NimBLE 端口

  5. 调用 esp_bt_controller_disable(); 禁用蓝牙控制器

  6. 调用 esp_bt_controller_deinit(); 反初始化蓝牙控制器

Bluedroid 协议栈反初始化:

  1. 断开所有连接,关闭广播和扫描

  2. 调用 esp_bluedroid_disable(); 禁用 Bluedroid 协议栈

  3. 调用 esp_bluedroid_deinit(); 反初始化 Bluedroid 协议栈

  4. 调用 esp_bt_controller_disable(); 禁用蓝牙控制器

  5. 调用 esp_bt_controller_deinit(); 反初始化蓝牙控制器