ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

E104-BT02 BLE透传模块实战:硬件接线、AT指令与MTU排错全攻略

E104-BT02 BLE透传模块实战:硬件接线、AT指令与MTU排错全攻略 周六晚上十一点一个做智能家居的朋友给我发消息E104-BT02到货了照着数据手册接线上电后模块灯也亮了可手机上的扫描软件死活找不到设备。我问他串口电平是多少伏他说“测过了5V灯亮得很”。问题恰好就出在这。这颗模块在BLE透传圈里算是不多见的好脾气选手主控只要用串口把数据丢给它它就把数据塞进BLE广播包、连接帧里发出去反过来收到手机端数据也会从串口吐出来。你不需要去配置GATT服务、不需要处理蓝牙状态机、更不需要操心广播包要怎么组甚至不用懂BLE协议就能在几分钟内把两个设备用无线打通。“5分钟上手”这个说法听起来像宣传话术但只要管线接对、驱动代码路径正确四步确实能跑通上电、调AT指令、手机连上、双向透传。我之所以专门写这篇是因为社区里围绕这颗模块的提问几乎都集中在同几个地方开不了广播、连上就断、发长数据丢失、配对弹窗反复出现。这些问题九成不是模块坏了而是供电、电平、AT模式门禁和MTU理解这几关上没跨过去。下面按我从硬件到代码、从广播到排错的实际经验把这套东西完整过一遍。1. 先搞清楚E104-BT02是什么角色一颗为串口而生的BLE从机模块1.1 它在整个链路里的位置E104-BT02本质上是一颗BLE透传模块内部封装了完整的BLE协议栈对外只暴露UART串口作为数据和配置通道。它承担的角色是“蓝牙从机/外设”也就是说默认情况下它不会主动去连别人而是打开广播等待手机或者PC端的Central设备来连接。这就决定了典型应用场景往往长这样MCU通过串口发送传感器数据模块将数据经BLE Notify发给手机App手机App通过BLE Write特征下发指令模块从串口吐给MCU设备只有一个串口资源通过模块快速获得无线通信能力不需要重做硬件平台很多朋友会问它和传统的蓝牙BT2.1/BR、蓝牙3.0/EDR到底有什么区别。这里简单说透BR/EDR传统蓝牙设计目标是大数据流比如蓝牙音箱的音频传输、蓝牙耳机的通话BLE设计目标则是极短小数据包、超低功耗、秒级连接比如传感器、遥控器、门锁、电子标签。E104-BT02是纯BLE设备你不能把它当普通蓝牙模块拿去传音频或连蓝牙音箱二者协议栈完全不同工具链也不通用。市面上的“双模蓝牙”芯片是同时具备BR/EDR和BLE两套协议栈E104-BT02这类BLE透传模块只保留后者的功能。1.2 省掉了什么又付出了什么代价自己直接用nRF52832这类SoC做产品时你需要自己处理的事情包括GATT服务表的定义、特征值的读写权限设计、广播包的组包、连接参数的协商、配对绑定流程、低功耗状态切换、甚至PCB天线匹配。这些环节每一处都有大量细节稍不留神就会踩坑。透传模块把这些全部封装好了。厂商固件里已经替你实现了一套完整的从机服务通常就是大家熟知的Nordic UART ServiceNUS提供两个特征值一个用于主控接收手机数据一个用于发送数据给手机。你作为用户只需要关心UART侧收发即可。代价就是灵活性受限。你想改服务UUID你想自定义特征值权限你想在广播包里塞厂商自定义数据模块级的AT指令多半支持有限绕不过去就只能走SDK自研路线。所以我的判断是E104-BT02这类模块最适合样板验证、快速原型、小批量产品如果要做大规模量产且对协议有强定制需求还是得切到芯片级开发。2. 硬件最小系统的搭建接线之前先看这三个细节2.1 引脚分配与最小电路参考E104-BT02的引脚不多典型的最小系统只需要四根线VCC、GND、TXD、RXD。在动手接之前先把关键引脚的功能摸清楚引脚/接口方向作用VCC电源输入通常支持2.0V~3.6V典型值3.3VGND电源地必须与主控共地TXD模块输出模块串口发送脚接主控的RXRXD模块输入模块串口接收脚接主控的TXSET/EN输入配置模式使能/复位控制不同固件定义不同AUX/状态脚输出可用来判断模块连接状态、数据流状态这里单独强调一个新手特别容易犯的错TXD和RXD的交叉连接。模块TXD接主控RXD模块RXD接主控TXD。很多人看着丝印直接同名相连结果就是模块发数据主控收不到主控发AT指令模块也没反应。标题里说的“开源电路”实际指的是厂商资料包中提供的最小系统参考原理图和社区仓库中整理出的底板开源工程。我在几个社区仓库里见过比较干净的做法主控用STM32F103C8T6最小系统板模块插在转接底板上底板包含3.3V LDO、滤波电容、串口电平转换和状态LED整体原理图开源。照抄这份电路来做验证板是完全可以的但有两个地方我建议自己再确认一遍RXD引脚的输入电压范围、以及模块复位引脚是否需要外部上拉。2.2 供电和电平九成“模块坏了”的真实原因大多数BLE模块标称工作电压是2.0V至3.6V典型值3.3VE104-BT02也不例外。拿5V直接怼VCC运气好一点模块内部有LDO还能撑住运气差一点就直接冒烟或者芯片永久损坏。我那位朋友说“5V灯也能亮”就是这个道理——LED的工作电压宽模块内部逻辑器件却不一定扛得住。即使你从USB转串口工具取电也建议先做两步确认用万用表实测模块VCC引脚上的电压确保在规格书范围内确认主控串口的TX电平不能超过模块RXD引脚的耐压范围主控是5V TTL输出时不要直接连模块RXD至少加一个电阻分压或者用逻辑电平转换芯片。反过来模块TXD输出一般是3.3V电平接到5V主控RX上通常没问题因为大多数MCU的RX在3.3V时已经能识别为高电平但为了稳妥最好确认主控的输入阈值低于3.3V。电源滤波也别省。模块发射瞬间电流波动明显在VCC和GND之间放一个10uF钽电容加一个0.1uF陶瓷电容能让供电更稳定。我实测过省掉这两个电容后使用质量较差的USB供电时模块偶尔会出现连接成功但数据传输中断的诡异现象加电容后再没复现过。2.3 天线的净空与摆放E104-BT02通常是板载PCB天线或邮票孔天线这类天线对周边环境非常敏感。最直接的经验是模块边缘至少保持5mm以上的净空下方不要大面积铺铜上方不要覆盖金属外壳或LCD排线。举一个我实际调过的案例把模块固定在金属支架上时手机在3米外就收不到广播换到塑料外壳位置同样功率10米外信号依然稳定。信号强度差距在RSSI上可以体现10甚至15dBm。所以硬件设计时天线区域单独留空是投入产出比最高的一项工作。3. 驱动代码怎么写串口打通之后透传才算真通3.1 工程组织和驱动骨架开源驱动代码里最典型的是STM32标准库或HAL库工程文件结构大致如下ble_uart.c / ble_uart.h模块初始化、数据发送at_cmd.c / at_cmd.hAT指令封装与解析lowlevel_uart.c底层串口中断与DMA配置app_main.c业务逻辑一个可用的驱动骨架核心逻辑并不复杂见下面的简化代码// ble_uart.h void BLE_UART_Init(void); uint32_t BLE_UART_Send(uint8_t *buf, uint16_t len); void BLE_UART_SetRxCallback(void (*cb)(uint8_t *data, uint16_t len)); bool BLE_UART_IsConnected(void);// ble_uart.c 核心逻辑 void BLE_UART_Init(void) { UART_InitTypeDef uart; uart.baudrate 115200; // 取决于模块固件默认波特率 uart.dataBits UART_DATA_8BITS; uart.stopBits UART_STOP_1BIT; uart.parity UART_PARITY_NONE; UART_Init(uart); GPIO_SetDir(MODULE_EN_PORT, MODULE_EN_PIN, GPIO_OUTPUT); GPIO_SetDir(MODULE_SET_PORT, MODULE_SET_PIN, GPIO_OUTPUT); GPIO_WriteBit(MODULE_SET_PORT, MODULE_SET_PIN, RESET); // 进入透传模式 GPIO_WriteBit(MODULE_EN_PORT, MODULE_EN_PIN, RESET); // 使能模块 BLE_UART_EnterPassthrough(); }有细心的朋友一定会发现这套驱动实际上没做任何蓝牙协议相关的事情它只是让MCU能和模块通过UART正常聊天。这恰恰是透传模块的价值所在协议栈已经在模块内部跑起来了MCU侧只是接线员。3.2 AT指令集速查与门禁条件很多人在AT指令这里卡住不是指令拼错而是根本没进入AT模式。E104-BT02这类模块通常有两种工作状态AT配置模式模块不广播/不连接专门用来收发AT指令透传模式模块正常工作UART收到什么就通过BLE发什么怎么切换不同固件定义不同常见做法包括拉低SET/EN引脚后复位模块、上电时保持某引脚电平进入AT模式、以及发送特定退出指令。这些信息必须查你手里固件版本对应的数据手册不同批次固件可能不兼容。这里给一份常见的AT指令速查表具体命令名以你模块的官方文档为准指令/查询含义AT测试通信是否正常正常返回OKATRESET模块软复位ATMAC?查询模块MAC地址ATNAMExxx修改广播名称ATADV间隔,电平配置广播参数ATPOWER等级设置发射功率ATMTU大小查询/设置MTUATNOTIFY...控制通知模式实际操作中要注意的是AT指令通常以回车换行结尾。我曾见过一位读者的代码里发指令没带\r\n模块一直没反应他一度怀疑收到的是坏模块。加上换行后缀后立刻恢复正常。3.3 一个标准的初始化流程我建议的固件初始化顺序是GPIO初始化把SET/EN引脚设置为正确电平UART初始化建议先用115200连不上再试9600/57600发送“AT”等待“OK”确认通信通路用AT指令配置名称、广播间隔、发射功率发送保存指令并让模块重启进入透传模式主控UART收到的数据直接转发给业务逻辑这里有个容易踩的坑初始化顺序反了。如果先发AT再拉高SET/EN模块可能已经处于透传状态收到的AT指令会被当成普通数据直接通过BLE广播出去表现为“模块毫无反应”。所以配置指令一定要在模块处于AT模式时发不要跳步。另外主控程序里尽量别用阻塞式延时等待模块的AT响应。BLE模块上电后内部启动时间不定从几十毫秒到几百毫秒都有可能。更稳的做法是发完AT后等待串口接收中断用超时机制判断是否收到OK。3.4 和OLED显示模块共存的驱动组织思路社区里常有人搜“hal库驱动oled代码”最终找到的是别人整套工程里顺带包含BLE和OLED的整合源码。这说明在一个项目里同时驱动BLE模块和显示模块非常常见。STM32 HAL库工程里跑FreeRTOS时我习惯的做法是OLED走I2C独立中断优先级不占用UART资源BLE模块走USART1IDLE中断/空闲DMA状态显示任务每秒刷新一次OLED缓存显示连接状态、RSSI、发送计数OLED最合适的介入点是查状态量而不是查数据流。BLE透传数据是高频的OLED显示是低频的两者如果互相阻塞系统会显得非常卡顿。用DMA空闲中断接收BLE数据将数据放入环形缓冲业务任务再从缓冲中取数。这样OLED只管读环形缓冲里的计数器和状态变量完全不影响透传实时性。4. 广播、连接、GATT与MTU四个你迟早会撞上的底层概念虽然是透传模块但以下几个概念直接决定你能不能把数据传稳、传快、传明白。4.1 广播类型与广播参数BLE设备要被人发现必须向外发广播包。广播包的类型直接决定别人能不能连接你。常见的广播类型包括可连接且可扫描广播最常见手机能扫描到也能发起连接不可连接广播纯单向广播别人收到包但无法连接可扫描广播允许别人扫描附加数据但不一定允许连接定向广播针对特定主机只有指定设备能连接E104-BT02这类模块默认都会打开可连接广播。如果你用AT指令把广播类型改成只发数据不可连接手机自然搜不到可连接设备。遇到“扫不到模块”的问题时先确认广播类型而不是马上怀疑天线。广播间隔同样要关注。间隔越短发现越快功耗越大间隔越长省电但手机可能等一两秒才看到设备。工业应用常设在100ms到500ms之间既能保证发现速度也不会过于耗电。4.2 连接过程到底怎么发生的BLE连接不是“先配对再连”的流程。实际顺序是从机E104-BT02持续广播主机手机App扫描到广播后发起连接请求连接建立成功双方交换连接参数如果应用层要求配对/加密此时才启动配对流程配对成功后可选择是否绑定bond保存密钥这个流程可以用“两个人在展会搭话”来类比广播就像举着名片到处逛扫描就是看谁的名片有趣连接请求相当于走过去握手配对才是真正交换联系方式绑定则是把联系方式存进通讯录下次见面直接叫出名字。手机调试App里绑定(bond)后下次重连时不需要重新配对这在很多物联网场景里能大幅改善用户体验。4.3 GATT不是协议是一张数据表GATTGeneric Attribute Profile本质上是一个属性表规范用来规定数据如何组织和访问。BLE通信中数据以“服务Service”和“特征值Characteristic”的形式存在。一个典型的GATT服务里每个特征值有UUID唯一标识符属性是只读、可写、支持通知Notify还是支持指示IndicateValue实际数据缓冲区E104-BT02透传模块默认跑的NUS服务就是Nordic定义的一套经典GATT服务。主机端向Write特征值写入数据对应模块UART输出模块UART收到数据后通过Notify特征值推给主机。你可以用手机上的BLE调试助手主动探测模块的服务和特征值自己看看UUID和权限配置这样对GATT的理解会更直观。4.4 MTU20字节限制与吞吐量的关键MTUMaximum Transmission Unit在BLE里是个高频话题。默认情况下BLE的ATT层MTU是23字节扣除3字节的ATT头单次有效负载最多20字节。也就是说你不做MTU协商时一次最多发20字节超过就会自动分包或失败。Android和iOS的BLE协议栈默认MTU不尽相同很多调试App支持手动协商MTU。E104-BT02这类模块通常支持更大的MTU常见可以协商到247字节单次有效负载最多244字节。但要注意MTU协商是双向的模块支持多大、手机支持多大、系统是否自动协商三者必须都成立才能生效。实际操作中我的建议是单次不超过20字节的数据不用管MTU直接发即可稍大数据建议在应用层分包成20字节一组模块和手机都兼容需要追求高吞吐时先确认手机调试App能协商MTU再在模块侧开启大包支持做一次完整验证很多人遇到“发小数据正常发长数据就丢包”的问题本质就是MTU没协调好或模块在20字节边界分包时出错。4.5 配对与绑定为什么调试助手总是弹窗配对Pairing用于加密链路绑定Bonding则在配对基础上把密钥持久化保存。手机和E104-BT02连接后如果模块固件配置了必须配对/加密App就会弹窗要求配对。如果每次连接都弹窗大概率是模块侧没保存绑定信息手机侧之前删除了绑定记录模块的任务是在每次连接后清除了LTK等长期密钥调试时如果不想每次都折腾配对可以先把模块的配对策略设为“不要求配对”或“Just Works”模式。等方案定型后再按安全需求决定是否开启强制配对。很多BLE调试助手绑定(bond)失败不是密码不对而是两端的配对策略不匹配。5. 实测排错从扫不到设备到中途掉线完整排查链路这部分我挑几个高频问题给出完整的排查思路而不是直接说答案。建议按链路一步一步走避免跳步造成二次故障。下面用表格做一个汇总再逐个展开说明。现象主要可能原因优先级排查点手机扫不到模块供电不足、广播类型不可连接、天线净空不够电压 → AT查询广播 → 天线位置能连上但收不到数据串口TX/RX接反、模块处于AT模式、波特率不匹配串口收发测试 → 查看状态引脚 → 波特率检查大数据传输中掉线MTU协商问题、供电波动、连接间隔过大MTU → 电源 → 连接参数每次连接都弹配对框未绑定、配对策略不匹配模块配对策略 → 手机端删除重新扫描Linux下ble蓝牙命令异常双模控制器BR/EDR干扰关掉BR/EDR保留BLE5.1 现象一手机完全扫不到模块第一步测硬件。模块供电是否稳定电压是否在规格书允许范围内。模块的指示灯如果有是否正常点亮或闪烁但不亮不代表没电很多模块把指示灯复用为状态指示有些固件默认关闭LED。第二步进AT模式查配置。发送AT指令查询广播状态、广播类型、广播名称。最常见的情况是广播类型被改成了不可连接或关闭广播。如果AT能通而手机扫不到问题十有八九在广播参数上。第三步检查天线环境。把模块拿在手里天线远离金属再做手机扫描测试。如果手持就能扫到固定位置扫不到那就是摆放位置问题。5.2 现象二连上了但收发不到数据这是最常见的“假连接成功”。手机显示已连接但发指令模块没反应模块发数据手机也收不到。按照这个顺序排查用串口工具直接连接模块TXD/RXD发AT测试串口是否正常。如果UART侧都收不到模块数据先把串口接线、电平、波特率查清楚确认模块工作状态。如果模块停在AT模式透传通道是没有数据流动的确认主控串口与模块的TX/RX交叉正确不要拿着逻辑分析仪只看一路信号最后再排查手机App端特征值是否找对Notify是否已经订阅关于订阅这点多说一句BLE的Notify不是自动推送的主机必须先向CCCDClient Characteristic Configuration Descriptor写入0x0001模块才允许发送Notify。很多调试App连接后不会自动订阅你得在界面里手动点击打开通知。这个不是模块问题但特别容易被忽略。5.3 现象三传输大文件或长数据时中途掉线长数据掉线不是一个原因而是几个因素叠加MTU协商不成功模块侧按20字节分包发送手机端乱序或丢失数据校验失败后App主动断开连接间隔太长主机未及时拉取从机数据缓冲溢出发射瞬间电流较大供电电压跌落模块逻辑复位如果要传大文件正确路径是先确认MTU协商到最大再适当调小连接间隔最后用供电能力充足的电源给模块单独供电。多数情况下MTU协商问题可以列为第一排查项用调试App手动协商MTU到247字节后很多卡顿消失。5.4 现象四Linux环境下蓝牙调试时BR/EDR干扰在PC上做嵌入式蓝牙调试很常见Ubuntu等系统用bluetoothctl操作BLE设备时如果电脑自带双模蓝牙控制器BR/EDR和BLE共用同一个物理射频前端有时候BR/EDR的扫描查询过程会影响BLE的连接稳定性。社区里经常有人提到“bluetoothctl关闭br保留ble”这个经验很实用。实际操作中可以先用hciconfig查看当前控制器再通过控制器的配置项只启用LE功能避免BR/EDR自动扫描。这样能减少莫名其妙的连接失败hciconfig hci0 down hciconfig hci0 up # 仅保留LE的方式因BlueZ版本不同而异常见做法是修改main.conf的对应配置项注意一点不建议在系统级别直接完全禁用BR/EDR因为鼠标、键盘等传统蓝牙外设可能还在使用它。只在你需要稳定调试BLE模块时临时切换即可。6. 从“会用模块”到“自己搭方案”三个立刻能上手的进阶方向6.1 用E104-BT02给ESP32-S3设备做BLE配网很多物联网设备没有屏幕也没有键盘第一次联网时怎么配WiFiBLE配网是一条成熟路径。设备上电后先跑一个临时BLE服务手机App把WiFi SSID和密码通过BLE写特征发给设备设备拿到后尝试连接路由器成功后关闭或休眠BLE转入常规运行。ESP32-S3本身自带BLE控制器直接用原生BLE配网当然可行但要写整套GATT服务和配网逻辑。如果项目里已经有主控MCU且并不想依赖ESP32的原生协议栈用E104-BT02这类透传模块做配网入口主控侧只处理串口数据开发速度会快得多。这种情况下模块的运行状态通常由主控通过串口或GPIO控制BLE配网功能独立于主业务运行。6.2 用低成本国产MCU当Central主机连接BT02E104-BT02是从机但很多场景需要一个东西主动去连它。手机当然能当主机但有些项目要求低成本、固定式网关或者用8位/32位国产MCU实现采集这时候就需要一颗能跑BLE Controller的芯片来当中央设备。现在国内不少MCU厂商已经推出集成BLE Controller的系列型号WCH、泰凌微等的方案在成本和功耗上都很有竞争力社区里甚至有人把ESP32的BLE Controller单独抽取出来配合其他MCU使用。但必须提醒一点做Central侧的软件工作量通常远大于做从机侧你需要自己处理扫描、连接、服务发现、MTU协商、Notify订阅、连接参数更新。哪怕是买模块级的Central方案AT指令的粒度也往往更细、更繁琐。所以我的建议是如果只是验证E104-BT02能不能和某颗MCU打通先别急着拿它来接先用手机调试App把数据链路调通再用MCU侧验串口字节最后才轮到Central芯片上场。分阶段验证能帮你快速定位到底是模块问题、手机问题还是代码问题。BLE数字钥匙、室内定位信标这类项目基本都能在这个框架下找到验证路径。6.3 STM32 HAL库工程里增加OLED状态页面的组织套路接着3.4小节继续展开。实际项目中我用过一套比较清爽的组织方式分享出来供参考OLED用I2C接口引脚只占SCL/SDA两个软件I2C或硬件I2C都行写一个oled_task每500ms刷新一次内容来自全局结构体BLE模块状态由一个全局状态变量维护包含未初始化、广播中、已连接、数据传输中四个状态中断回调里更新计数器和状态OLED任务只读不写举个例子OLED上可以显示三行内容行内容数据来源第1行模块连接状态ble_status全局变量第2行当前RSSI模块通过AT查询/Notify回调更新第3行发送/接收计数UART收发累加器这样做的核心价值是把“高频的数据传递”和“低频的人机交互”解耦BLE串口中断永远不会被OLED刷屏阻塞。有人习惯把OLED驱动和BLE驱动写在同一个文件里前期图省事后面一旦调参就非常痛苦每个功能点都要在一个大文件里翻找。拆分成独立模块哪怕只是靠函数指针做回调后续维护体验会好一个量级。这几年调BLE模块我最大的感受是绝大多数问题都不是蓝牙协议多深奥而是供电、电平、状态模式这些基本功没做好。E104-BT02这样的透传模块把协议栈挡在身后你能接触到的错误面已经很窄了剩下的就是耐心把串口链路和状态机理顺。如果你也卡在某个“扫不到”或“连不上”的环节建议先拿起万用表测一下模块供电电压再打开串口助手发一条AT看看它到底回应了什么——很多时候答案已经在那里了。
返回列表