news 2026/6/13 7:31:54

【Zephyr|ESP32-S3】基础学习:BLE服务搭建与手机蓝牙控灯

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Zephyr|ESP32-S3】基础学习:BLE服务搭建与手机蓝牙控灯

【Zephyr|ESP32-S3】基础学习:BLE服务搭建与手机蓝牙控灯

哈喽,我是余火,一个普通的牛马打工人,目前正在学如何使用Zephyr RTOS。

之前已通过 UDP server 实现了局域网控灯,手机或电脑发个命令过去,WS2812 就变色。这次来试试给ESP32-S3加上BLE(蓝牙低功耗)——手机通过蓝牙直连板子来发命令控灯。

💡本篇学习目标
bt_enable()/bt_le_adv_start():BLE 协议栈初始化与广播
BT_GATT_SERVICE_DEFINE:GATT 服务静态注册

改了哪些东西

文件改了什么
prj.conf新增 4 行 BLE 配置
boards/...overlay显式启用&esp32_bt_hci节点
CMakeLists.txt追加src/ble.c
src/ble.c新增,BLE 初始化 + GATT 服务 + 广播
src/ble.h新增,ble_init()声明
src/main.c追加ble_init_entry线程
src/wifi.c/h无改动
src/udp_server.c/h无改动

BLE 基础概念

BLE 和经典蓝牙不是一回事——BLE 专为低功耗设计,速率低但省电,适合 IoT 设备的短距离通信。

对比项经典蓝牙BLE
速率高(音频传输)低(125Kbps~2Mbps)
功耗极低(纽扣电池能用几个月)
适用场景耳机、音箱IoT 设备、传感器、手环

BLE 协议栈分多层,从硬件到应用逐层封装:

Application(你的代码:ble.c / cmd_dispatch.c) │ ▼ GATT(Generic Attribute Profile)── 语义层:Service / Characteristic │ ▼ ATT(Attribute Protocol)── 读写层:像对象的属性 get/set │ ▼ L2CAP(Logical Link Control)── 通道复用 + 分片重组 │ ▼ Link Layer ── 跳频、加密、连接管理 │ ▼ Physical(RF 2.4GHz ISM band)── 调制解调

GAP 和 GATT 是 BLE 协议栈中两个核心 Profile,各管各的事:

全称职责
GAPGeneric Access Profile设备怎么被发现连接(广播、扫描)
GATTGeneric Attribute Profile连接后怎么交换数据(服务、特征值、读写)

GATT 的层级结构:Service → Characteristic。Service 是一个功能单元,Characteristic 是里面的数据点,每个 Characteristic 有自己的 UUID 和读写属性。

UUID 类型:

类型长度示例用途
16-bit4位hex0x180F(Battery Service)、0x180D(Heart Rate)BLE SIG 分配的标准服务,自动识别
128-bit32位hexf0000000-1212-46ef-9242-8da2ba3e6a00自定义服务和特征值

本篇用自定义 128-bit UUID,避免和标准服务冲突。自定义 UUID 手机 App 不认识,会显示为 Unknown Service,这是正常的。

BLE 连接流程很简单:手机扫描 → 发现板子广播 → 连接 → 自动发现服务 → 读写特征值。

💡GATT 和面向对象的类比:GATT 的 Service/Characteristic 模式很像面向对象的类/属性——Service 就像"类"(一个功能单元),Characteristic 就像"属性"(一个数据点),UUID 就是"属性名",Write/Notify 就是"setter/getter"。BLE 底层用的 ATT 协议就是"属性的读写",GATT 只是在上面加了语义层。

启用 BLE 配置

prj.conf 新增 4 行:

CONFIG_BT=y # 启用 BLE 子系统(会自动选中 GATT、ATT 等依赖项) CONFIG_BT_PERIPHERAL=y # 外设角色:板子作为被连接方(手机是中央设备) CONFIG_BT_DEVICE_NAME="Zephyr-WS2812" # BLE 广播时对外显示的设备名 CONFIG_BT_MAX_CONN=1 # 最大同时连接数,只允许一个设备连接(省内存)
配置项作用依据
CONFIG_BT=y启用 BLE 子系统所有 BLE sample 必须
CONFIG_BT_PERIPHERAL=y外设角色(被连接方)peripheral系列 sample 均使用
CONFIG_BT_DEVICE_NAME广播设备名peripheralsample 使用CONFIG_BT_DEVICE_NAME
CONFIG_BT_MAX_CONN=1只允许一个设备连接精简内存占用

💡三个"想当然但错了"的配置CONFIG_BT_GATT=y不需要手动写(CONFIG_BT=y自动选中,手动写反而报 unused 警告);CONFIG_BT_WIFI_COEX=y这个符号不存在(很多教程误传);同时开CONFIG_WIFI=yCONFIG_BT=y时共存功能自动启用CONFIG_ESP32_SW_COEXIST_ENABLE),不需要手动加任何共存配置项。

overlay 新增 BT HCI 节点:

/* ESP32-S3 的蓝牙控制器通过 VHCI 接口和 CPU 通信(RAM 回调,不走 UART/SPI), * 默认 status = "disabled",必须在 overlay 中显式启用才会加载驱动 */ &esp32_bt_hci { status = "okay"; };

ESP32-S3 的 BT HCI 节点默认disabled,必须在 overlay 中显式启用。dtsi 中的chosen { zephyr,bt-hci = &esp32_bt_hci; }已配好,不需要重复声明。

GATT 服务定义

ble.h —— 对外只暴露一个初始化接口:

#ifndefBLE_H#defineBLE_Hvoidble_init(void);#endif

ble.c —— 自定义 UUID:

#include<string.h>#include<zephyr/kernel.h>#include<zephyr/bluetooth/bluetooth.h>#include<zephyr/bluetooth/gatt.h>#include<zephyr/bluetooth/uuid.h>#include<zephyr/logging/log.h>#include
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 7:29:51

YonSuite总账批量结账

YonSuite总账批量结账业务场景总账批量结账可以按期间方案和会计期间查询账簿做批量结账处理&#xff0c;可以减少财务人员的月结工作量&#xff0c;优化提升工作效率。系统操作操作路径&#xff1a;财务云 > 财务会计 > 总账 > 期末处理---总账批量结账1. 支持批量月…

作者头像 李华
网站建设 2026/6/13 7:27:54

MYSQL RR 解决“脏读+不可重复读“和“幻读“的本质区别

RR 解决脏读 不可重复读 和 RR 解决幻读&#xff1a;MVCC 解决快照读。这两个是否矛盾一、先说结论&#xff1a;完全不矛盾问题解决机制解决哪类读脏读 不可重复读MVCC&#xff08;ReadView 复用&#xff09;单行读幻读MVCC&#xff08;快照读&#xff09;范围读幻读&#xf…

作者头像 李华
网站建设 2026/6/13 7:23:01

责任链模式实战——同一个框架里的两种链

责任链模式实战&#xff1a;同一个框架里的两种拦截器链 本文从一个真实的生产级 Java Web 框架出发&#xff0c;展示责任链模式的两种正交实现&#xff1a;注解驱动的编译期链和数据库驱动的运行期链。完整代码可直接运行&#xff0c;核心思想可迁移至任何需要拦截器链的业务系…

作者头像 李华
网站建设 2026/6/13 7:20:58

5分钟快速搭建OBS局域网直播系统:obs-rtspserver完全指南

5分钟快速搭建OBS局域网直播系统&#xff1a;obs-rtspserver完全指南 【免费下载链接】obs-rtspserver RTSP server plugin for obs-studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-rtspserver 你是否曾经希望将OBS直播内容无缝推送到局域网内的多个设备&…

作者头像 李华