13. ESP32-S3R8N8 BLE蓝牙低功耗通信实战:从广播配置到数据收发 📅 发布时间:2026/7/8 3:17:49 👁️ 浏览次数: 13. ESP32-S3R8N8 BLE蓝牙低功耗通信实战从广播配置到数据收发很多刚开始玩ESP32-S3的朋友想用蓝牙和手机通信但一看到BLE那些服务、特性、UUID的概念就头大。别担心今天我就带你手把手走一遍用MicroPython在ESP32-S3R8N8上实现一个最简单的BLE通信。学完这篇你就能让开发板和手机互相发消息了。咱们的目标很明确让手机上的“e调试”APP能搜到并连接上我们的ESP32-S3然后我们发个字母“A”过去板子收到后回我们一个字母“B”。麻雀虽小五脏俱全这个流程涵盖了BLE从创建、广播、连接到数据收发的核心步骤。1. 先唠两句BLE是个啥蓝牙低功耗BLE你可以把它理解成蓝牙的“节能版”。它生来就是为了省电适合那些靠电池供电、需要长时间待机、偶尔传点小数据的设备比如智能手环、温湿度传感器、智能门锁这些物联网IoT设备。和传统蓝牙比如连音箱的那种比BLE连接速度更快功耗极低设备用一颗纽扣电池可能就能撑一年。ESP32-S3芯片只支持BLE不支持经典蓝牙所以咱们的手机蓝牙直接去搜是搜不到的得用支持BLE的APP比如咱们教程里用的“e调试”。2. 搭建BLE的“骨架”服务与特性BLE设备对外提供功能是靠一套“服务-特性”的模型。你可以把一个BLE设备想象成一个提供多种服务的商店。服务Service就是商店里的一个柜台比如“数据收发柜台”。特性Characteristic就是柜台里具体能买卖的东西比如“接收数据”和“发送数据”这两个商品。每个特性都有唯一的“身份证号”叫UUID。数据真正的读写操作都是针对特性来进行的。下面我们就来用代码把这个“商店”开起来。2.1 初始化BLE并创建服务首先把蓝牙功能的核心库引进来然后激活蓝牙模块。from bluetooth import BLE import bluetooth bt BLE() # 创建一个蓝牙对象这是所有操作的起点 bt.active(1) # 参数为1打开蓝牙功能接下来我们要定义服务的UUID和特性的UUID。UUID通常是一串16位或128位的数字这里我们用简单的16位数字来举例。# 定义一个服务的UUID。0x9011是十六进制数相当于十进制的36881这就是我们“数据收发柜台”的ID。 SERVER_1_UUID bluetooth.UUID(0x9011) # 定义两个特性的UUID。一个用来收数据CHAR_A一个用来发数据CHAR_B。 CHAR_A_UUID bluetooth.UUID(0x9012) # 特性A的ID CHAR_B_UUID bluetooth.UUID(0x9013) # 特性B的ID光有ID还不够我们得规定这些特性能干什么。比如特性A我们允许手机“读”它的值并且允许它主动“通知”手机也就是主动发数据给手机。特性B则允许手机“读”和“写”。# 设置特性A的权限可读(FLAG_READ) 可通知(FLAG_NOTIFY) CHAR_A (CHAR_A_UUID, bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,) # 设置特性B的权限可读(FLAG_READ) 可写(FLAG_WRITE) CHAR_B (CHAR_B_UUID, bluetooth.FLAG_READ | bluetooth.FLAG_WRITE,)现在把这两个特性打包放进我们之前定义的服务里。# 把特性A和特性B放入服务1 SERVER_1 (SERVER_1_UUID, (CHAR_A, CHAR_B),) # 目前我们只有一个服务把它放到一个服务元组里 SERVICES (SERVER_1,)最后也是最关键的一步把这个服务“注册”到BLE协议栈中。注册成功后我们会得到这两个特性对应的“句柄”可以理解为内部操作编号后面收发数据全靠它们。# 注册服务。返回值是一个嵌套的元组这里用((char_a, char_b),)来接收两个特性的句柄。 ((char_a, char_b),) bt.gatts_register_services(SERVICES)注意char_a和char_b这两个变量现在保存的就是特性A和特性B的句柄后面用bt.gatts_notify发数据、用bt.gatts_read读数据时都需要用到它们。3. 让手机能找到我广播配置商店开好了但藏在深巷没人知道。BLE设备通过“广播”来告诉周围的设备“我在这儿我叫XXX快来连接我”广播包里就装着设备名等信息。我们来写一个函数专门生成包含设备名的广播数据包。def create_adv_data(name): # BLE广播数据有固定格式[长度1, 类型1, 数据1, 长度2, 类型2, 数据2, ...] # 第一部分广播标志(Flags)。0x02表示这部分数据总长2字节0x01表示类型是“Flags”0x06是数据通用可发现模式。 flags_part bytearray([0x02, 0x01, 0x06]) # 第二部分完整的设备本地名称。0x09是“Complete Local Name”的类型码。 name_encoded name.encode(utf-8) # 把字符串转换成字节 name_length len(name_encoded) name_part bytearray([name_length 1, 0x09]) name_encoded # 长度要加上类型码自身占的1字节 # 把两部分拼接起来 adv_data flags_part name_part return adv_data # 设置我们的设备广播名手机搜到的就是这个名字 adv_data create_adv_data(ESP32S3R8N8_BLE) # 开始广播100是广播间隔单位是0.625ms100约等于62.5msadv_data就是广播内容 bt.gap_advertise(100, adv_data)执行完bt.gap_advertise你的ESP32-S3就开始对外喊话了“我是ESP32S3R8N8_BLE”4. 处理连接与数据中断事件回调BLE是事件驱动的。手机连接、断开、发数据过来这些对我们设备来说都是“事件”。我们需要写一个中断处理函数就像设置一个“管家”当这些事件发生时由“管家”来负责处理。def ble_irq(event, data): if event 1: # 事件1蓝牙已连接 print(蓝牙已连接) # 连接后可以停止广播以省电这里我们先不处理 pass elif event 2: # 事件2蓝牙断开连接 print(蓝牙断开连接) # 断开后重新开始广播等待下一次连接 bt.gap_advertise(100, adv_data) elif event 3: # 事件3写入事件即手机向我们发送了数据 print(写入事件发生) # 事件3的data是一个元组包含连接句柄和特性值句柄 conn_handle, value_handle data # 通过value_handle读取手机写过来的数据 buffer bt.gatts_read(value_handle) print(收到数据, buffer) # 判断收到的数据 if buffer bA: # 如果收到单个字符A print(向手机发送字符 B) # 通过char_a这个特性句柄以“通知”的方式向手机发送字符B # 参数1是连接句柄char_a是目标特性句柄 bt.gatts_notify(conn_handle, char_a, bB) # 将这个“管家”函数设置给蓝牙对象 bt.irq(ble_irq)这个函数是整个BLE通信的逻辑核心。它清晰地展示了连接管理连接和断开时打印信息断开后自动重启广播。数据接收当事件3写入发生时从正确的value_handle读取数据。数据发送判断收到的是否是‘A’如果是则通过bt.gatts_notify从char_a特性向手机发送‘B’。提示bt.gatts_notify是BLE中一种高效的、由服务器我们的ESP32主动向客户端手机推送数据的方式不需要手机反复来“问”。5. 实战测试与手机“e调试”APP通信代码都写好了把整个脚本上传到ESP32-S3R8N8开发板并运行。然后拿出你的手机安装APP在手机应用商店搜索并下载“e调试”APP一个常用的BLE调试工具。搜索设备打开“e调试”它会自动扫描周围的BLE设备。你应该能看到一个名叫“ESP32S3R8N8_BLE”的设备。连接设备点击这个设备名称进行连接。发现服务连接成功后APP会列出设备的所有服务。找到那个UUID为0x9011的服务可能显示为Unknown Service点进去。操作特性你会看到两个特性分别对应我们代码里的char_a(UUID: 0x9012) 和char_b(UUID: 0x9013)。找到具有“写”权限的特性通常是0x9013那个点击进入其操作界面。在发送框输入大写字母A点击“发送”。观察结果在ESP32的串口终端比如Thonny的Shell窗口你应该会看到打印出“写入事件发生”、“收到数据 b‘A’”、“向手机发送字符 B”。同时在“e调试”APP上你应该能看到从设备UUID: 0x9012的特性发来的通知数据B。恭喜你你已经完成了一个完整的BLE双向通信。手机发A设备回B。你可以修改ble_irq函数里的判断逻辑和发送的数据来实现你自己的控制逻辑比如收到‘1’开灯收到‘0’关灯。6. 几个容易踩的坑UUID冲突如果你有多个ESP32设备或者和其他BLE设备一起用尽量使用独特的UUID避免用0x9011这种简单值可以用在线生成器生成128位的UUID。广播名不显示确保广播数据包格式正确特别是长度字段。len(name)1那个1千万别漏它计算的是“类型码名称数据”的总长度。收不到数据或发不出数据首先检查特性句柄char_a、char_b是否正确获取并在ble_irq和bt.gatts_notify中被正确使用。其次确认手机操作的是正确的、具有相应权限的特性写数据要找FLAG_WRITE的特性收通知要订阅FLAG_NOTIFY的特性。连接断开后不广播检查ble_irq函数中事件2断开的处理逻辑确保调用了bt.gap_advertise重新广播。这个例程虽然简单但已经搭建起了ESP32-S3 BLE开发的基本框架。下次你想做个BLE温湿度计或者遥控小车只需要在这个框架里修改服务/特性的定义并在中断函数里填充你的业务逻辑就行了。
智能客服开源框架入门实战:从零搭建到生产环境部署 最近在做一个智能客服项目,选型时调研了几个主流的开源框架,从一脸懵到成功上线,踩了不少坑,也积累了一些心得。今天就把这个从零到一的实战过程梳理成笔记,希望能帮到同样刚入门的朋友们。 一、新手入门,先… 2026/5/17 12:50:42
FLUX.小红书极致真实V2效果对比:V2在面部微表情、眼神焦点、唇色自然度提升显著 FLUX.小红书极致真实V2效果对比:V2在面部微表情、眼神焦点、唇色自然度提升显著 1. 工具介绍与核心优势 FLUX.小红书极致真实V2是一款基于先进AI技术的本地图像生成工具,专门针对小红书平台的内容创作需求进行了深度优化。这个工具能够让用户在不需要网… 2026/5/17 12:50:40
快速上手Qwen3-ASR-1.7B:无需代码,用网页界面轻松完成语音识别 快速上手Qwen3-ASR-1.7B:无需代码,用网页界面轻松完成语音识别 1. 引言:让语音转文字变得像点外卖一样简单 你有没有遇到过这样的场景?一段重要的会议录音需要整理成文字稿,或者一段外语视频想快速了解内容ÿ… 2026/7/3 15:09:52
CTF 安卓逆向 APK 实战:3 种方法定位并解密 Timer 题目中的 Flag CTF 安卓逆向 APK 实战:3 种方法定位并解密 Timer 题目中的 Flag 在CTF竞赛中,安卓逆向工程一直是热门挑战方向。本文将以阿里CTF中的Timer题目为例,通过三种不同的技术路线,深入剖析如何高效定位关键代码并获取Flag。不同于简单的… 2026/7/8 20:00:41
基于TLE 6208-6G与PIC18F2550的直流电机控制方案 1. 项目背景与核心器件选型在工业自动化和嵌入式控制领域,直流电机因其结构简单、控制方便等优点被广泛应用。但如何实现精确的速度和方向控制一直是工程师面临的挑战。本项目采用英飞凌TLE 6208-6 G电机驱动芯片与Microchip PIC18F2550微控制器的组合方案ÿ… 2026/7/8 20:00:41
PHP 7.x 反序列化漏洞实战:从 [NPUCTF2020]ReadlezPHP 到 3 种 RCE 利用链构造 PHP 7.x 反序列化漏洞实战:从 [NPUCTF2020]ReadlezPHP 到 3 种 RCE 利用链构造 在CTF竞赛和实际渗透测试中,PHP反序列化漏洞一直是Web安全领域的热点。本文将以一道经典CTF题目[NPUCTF2020]ReadlezPHP为切入点,深入剖析PHP反序列化漏洞的实战… 2026/7/8 20:00:41
Apache POI 5.5.1 安全配置:规避CVE-2025-31672等3大常见漏洞 Apache POI 5.5.1 企业级安全配置指南:防御CVE-2025-31672等关键漏洞在企业级Java应用中,Apache POI作为处理Office文档的事实标准,其安全性直接关系到整个系统的稳健性。2025年曝光的CVE-2025-31672漏洞再次提醒我们:即使是最成熟… 2026/7/8 19:58:40
Apache POI 5.4.0 安全升级指南:修复 CVE-2025-31672 等 3 个高危漏洞 Apache POI 5.4.0 安全升级指南:修复 CVE-2025-31672 等 3 个高危漏洞 在企业级Java应用中,Apache POI作为处理Microsoft文档格式的事实标准,其安全性直接关系到业务系统的稳定性。2025年4月发布的5.4.0版本修复了包括CVE-2025-31672在内的多… 2026/7/8 19:58:40
XXE 漏洞防御:PHP 5种防护方案对比与 libxml 2.9.0+ 配置指南 XXE漏洞防御:PHP 5种防护方案对比与libxml 2.9.0配置指南 XML外部实体注入(XXE)是Web应用中一个长期存在却常被忽视的安全威胁。当PHP应用处理用户提供的XML输入时,若未正确配置XML解析器,攻击者可能读取服务器敏感文件… 2026/7/8 19:58:40
BetterNCM安装器:高效管理网易云插件的最佳选择 BetterNCM安装器:高效管理网易云插件的最佳选择 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 还在为网易云音乐插件的繁琐安装流程而烦恼吗?BetterNCM安装器是… 2026/7/8 0:02:48
运动控制系统安全设置对比:ECI3808的3种限位保护与急停逻辑实现 运动控制系统安全机制深度解析:限位保护与急停逻辑的设计哲学在精密制造与自动化领域,运动控制系统的安全设计绝非简单的功能堆砌,而是一套融合了机械工程、电气原理和软件算法的防御体系。当一台数控机床以每分钟数万转的速度运转࿰… 2026/7/8 0:06:48
AI大模型应用开发:小白也能抓住的红利风口,收藏这篇入门指南! 文章指出,虽然微软等科技巨头在裁员,但英伟达等公司却在积极扩招AI相关人才,尤其是具身智能、仿真等领域。AI行业正在经历结构性调整,传统岗位被淘汰,而大模型应用开发等新岗位需求旺盛。对于想转行或学习AI的普通人来… 2026/7/8 0:10:49
6个月转型AI工程师:实战路径与核心技能 1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公… 2026/7/7 11:26:57
TPAFE0808与PIC18F87K22的多通道信号采集方案 1. 项目背景与核心需求在工业自动化、医疗设备和科研仪器等领域,多通道信号采集与系统监测是基础且关键的技术需求。传统方案往往面临通道数量不足、信号调理复杂、系统集成度低等问题。TPAFE0808作为一款8通道模拟前端芯片,与PIC18F87K22微控制器的组合… 2026/7/7 11:26:57
STC3115与PIC18LF26K80构建高精度电池管理系统 1. STC3115与PIC18LF26K80在电池管理系统中的核心价值在现代电子设备中,电池管理系统(BMS)的重要性不亚于设备的核心处理器。STC3115作为一款高精度电池电量监测IC,与PIC18LF26K80微控制器的组合,构成了一个既能精确监控又能智能管理的完整解… 2026/7/8 14:25:08