BLE蓝牙开发从底层机制到工程实战:连接、GATT、低功耗与调试全解析
1. 从频段、调制到拓扑先把BLE的底层骨架搭清楚这两年跟蓝牙打交道的时间越长越觉得一个扎心的现实是很多人项目卡住不是API用错了而是对BLE的底层机制理解停留在“能用就行”的层面。这次我把BLE技术体系里真正影响开发决策的知识点串成了一份完整笔记从物理层的频段选择、调制方式到协议栈的架构分工再到连接建立、配对绑定、GATT读写、广播扩展、Mesh配网和低功耗策略基本覆盖了日常开发会用到的全部关键环节。不管是刚接触蓝牙开发的新手还是已经在用ESP32、nRF52、iPhone或者uni-app做项目的开发者这份梳理都能帮你少走一些弯路。先聊物理层。BLE工作在全球通用的2.4GHz ISM频段也就是2400MHz到2483.5MHz这一段具体到信道划分BLE把这段频谱分成了40个信道每个信道带宽2MHz。需要注意这40个信道里只有37个用于数据通信编号范围是0到36剩下的37、38、39三个信道是专用的广播信道。为什么特意留三个广播信道这就要说到抗干扰和快速发现的取舍了。2.4GHz频段还有Wi-Fi、经典蓝牙、Zigbee甚至微波炉在抢资源BLE设计者把广播信道放在2402MHz、2426MHz、2480MHz这三个位置上刻意错开Wi-Fi最常用的1、6、11信道中心频率避免在设备发现阶段就撞车。同时广播包只在三个信道上轮流发扫描方也在这三个信道上轮流听不需要像Wi-Fi那样全频段扫描设备发现的功耗和时间都能降下来。调制方面BLE用的是GFSK即高斯频移键控。这个方案和经典蓝牙一致但BLE把物理层的速率定为1Mbps后来又引入了2Mbps的PHY选项。1Mbps模式下符号速率就是1Msym/s2Mbps则是2Msym/s。GFSK的原理简单说就是对原始0/1比特流先做高斯滤波再用滤波后的信号去控制载波频率偏移这样做的好处是频谱效率高带外辐射小而且接收端的非相干解调电路可以做得非常简单对芯片成本十分友好。BLE 5.0之后新增的2M PHY本质上是把符号速率翻倍同样一个数据包在空中的占用时间几乎减半意味着吞吐率翻倍的同时功耗也降了——因为在同样多的数据量下射频开启时间更短。不过2M PHY的接收灵敏度会比1M PHY差几个dB所以远距离场景反而要往另一个方向走用125kbps或者500kbps的编码PHYcoded PHY。再来看拓扑结构。BLE经典的单点连接是piconet模型一个中心设备Central/GATT Client可以连接多个外围设备Peripheral/GATT Server比如手机同时连手表、耳机、心率带。但这个模型里一个外设只能被一个中心连接广播者Broadcaster和观察者Observer之间则根本不建立连接纯粹靠广播单向传数据。BLE 5.0之后有了广播扩展理论上广播集合可以做到数十万个设备而且广播和扫描之间的信道选择也更灵活。到了BLE Mesh拓扑进一步升级为多对多的中继网络设备之间可以互相转发消息覆盖范围不再受单跳距离限制这也是Mesh Remote Provisioning远程配网能成立的物理基础。MAC层到链路层之间的设计也值得展开说一下。BLE链路层定义了五种状态Standby、Advertising、Scanning、Initiating、Connection。设备在任一时刻只能处于其中一种状态状态迁移由主机Host侧的GAP层控制。实际开发中你调用startAdvertising()、startScanning()、connect()这些API底层就是在驱动链路层做状态切换。链路层还有一个常被忽视的角色——白名单White List。当扫描或发起连接时可以配置白名单只对指定的设备地址响应这样既能过滤掉无意义的广播也能减少空中唤醒次数是低功耗设计里很实用的一招但大多数应用的代码里都只用了acceptAll的默认策略。2. 连接是怎么建立起来的从广播包到连接事件的完整链路BLE连接过程是面试常问、实际开发也绕不开的基础。这句话说起来简单但里面的细节非常密。从外围设备发出第一个广播包开始到中心设备和外围设备进入稳定收发状态中间经历了广播、扫描、发起连接、连接参数协商、链路层握手机制等多个环节。我拆开讲。2.1 广播包的结构解析广播包Advertising Packet由两个部分组成广播PDU和附加的AdvA广播者地址。AdvA是链路层自己加的Host层看不到。用户能看到的是广播数据其格式是一条条AD Structure依次排列每条结构由Length、Type、Data三段组成。Length占据第一个字节表示Type加Data的总长度Type是1字节的AD Type枚举值比如0x01表示Flags、0xFF表示Manufacturer Specific Data、0x16表示Service DataData就是业务载荷。这里我强调一下Flags这个字段。Flags里的bit定义直接决定了设备的行为类别bit0是LE Limited Discoverable Modebit1是LE General Discoverable Modebit2是BR/EDR Not Supported。绝大多数低功耗蓝牙外设都应该把bit1置1bit2也置1表示这是一个只支持LE的通用可发现设备。但总有项目不设置Flags或者Flags设置错误导致手机扫描不到或者连接时报错这是排查广播问题时第一眼要看的地方。广播类型本身也分好几种可连接的非定向广播Connectable Undirected、可连接的有向广播Connectable Directed、不可连接的非定向广播Non-connectable Undirected、可扫描的非定向广播Scannable Undirected。日常外设基本都是可连接的非定向广播这样中心设备既能看到广播又能发起连接。不可连接广播一般用于Beacon类应用比如iBeacon、Eddystone。如果你做的是Beacon把广播类型配成不可连接即可否则手机可能尝试连接反而浪费资源。2.2 中心设备发起连接之前发生了什么扫到什么参数才算“发现一个设备”扫描方拿到的核心信息有两个设备地址和广播数据。设备地址分Public Address和Random Address两种Random Address又可以细分为Static、Private Resolvable可解析私有地址、Private Non-resolvable三类。iOS 13之后系统在后台扫描时看到的设备地址很多都是Private Resolvable这种地址会定期变化但可以通过配对时交换的IRKIdentity Resolving Key在本地解析回真实身份。如果你做的是iOS外设且开启了CBPeripheralManager的isAdvertising并发广播你会在日志里看到地址一直变——这就是Private Resolvable在起作用不是设备出了问题。中心设备决定发起连接后链路层会直接进入Initiating状态。发起连接的时候要配置一个关键参数扫描窗口和扫描间隔。每次扫描随机选择一个信道监听一个扫描窗口然后跳到下一个扫描间隔。窗口和间隔不相等是为了避免和广播方的节奏锁定在一起导致永远错过。窗口越大发现概率越高但功耗也越高。2.3 连接建立和连接事件的时序逻辑连接建立成功后双方进入Connection状态。链路层定义了一个核心概念叫连接事件Connection Event中心设备在每个连接事件开始时发送一个数据包外设收到后可以在限定时间内回包双方在这个事件窗口内完成一轮或多轮数据交换。连接事件每隔一个connInterval发生一次。connInterval范围是7.5ms到4秒以1.25ms为步进。假设你设了30ms的间隔那每秒就有大约33个连接事件每个事件内能传的包数由connSlaveLatency和supervisionTimeout共同约束。connSlaveLatency的值表示从设备可以跳过多少个连接事件不响应。这个参数是低功耗外设的核心调节手段。举个例子心率计每50ms产生一次心搏数据但用户不希望手环每秒都被唤醒。设置connSlaveLatency4意味着外设每5个连接事件只需响应一次射频只在这一个事件里打开收发其余4个事件可以安心睡。supervisionTimeout则是连接保活的兜底机制如果在这个时间内100ms到32秒双方都没有成功收发任何一个包链路层就判定连接丢失直接断开。经验值是supervisionTimeout至少是connInterval乘以(connSlaveLatency1)的2倍以上否则误判断连的概率会很高。2.4 iOS/Android对连接参数的态度差异这里必须强调一个平台差异。Android允许你在发起连接时直接指定connectionInterval系统通常会照做。但iOS有一套自己的连接参数审核规则如果你作为外设端请求了一个iOS认为不合理的间隔iOS会在30秒后强制改成合理值甚至直接拒绝连接。iOS认为合理的连接间隔是30ms到50ms之间从设备延迟推荐0到4超时时间推荐20秒或以上。我做外设时一般直接向iOS请求30ms、slaveLatency4、supervisionTimeout20s既满足iOS的约束也能省电。3. 配对、绑定与安全连接之后的身份与加密体系连接建立不等于数据安全了。BLE在连接之后还有一套独立的配对与安全机制这套体系分三个层次Legacy Pairing旧式配对、Secure Connections安全连接LE Secure Connections、以及LESC的数值比较模式。很多人说“BLE协议栈不是有加密吗”这句话只说对了一半——默认连接是非加密的所有数据都是明文在空中传输只有完成配对并启动加密之后链路才是安全的。3.1 配对流程的三个阶段第一阶段是特性交换。中心设备和外设交换各自的I/O能力是否支持显示、键盘、是否支持OOB、认证需求是否需要MITM防护、以及密钥大小。第二阶段根据算法生成短期密钥STK或长期密钥LTK。Legacy Pairing使用STKSTK由PIN码6位数字和双方随机数计算生成很容易被暴力破解现在已经不建议使用。Secure Connections使用ECDH P-256椭圆曲线密钥交换生成LTK安全性大幅提升而且支持FIPS认证。第三阶段是传输密钥分配包括LTK、IRK、CSRK连接签名解析密钥等信息的分发。判断一个设备用的是Legacy还是Secure Connections看配对过程中是否出现了“数值比较”Numeric Comparison就大致能判断出来。数值比较是Secure Connections新增的MITM防护方式双方各自显示一个6位数字用户确认一致即可完成认证。如果设备只支持Legacy配对时通常直接弹“输入PIN码”或“确认配对”不会有6位数字比对的过程。3.2 绑定与重新连接配对完成后如果双方都支持绑定Bonding会把LTK等密钥持久化存储下次连接时直接使用已保存的密钥进行加密无需重新配对。这对用户体验至关重要手环第一次连手机要弹窗以后每次自动连上靠的就是绑定后的LTK自动恢复加密。但绑定的密钥存储在协议栈里如果应用卸载、系统重置或清除了蓝牙缓存绑定关系就会丢失下次连接又要重新发起配对——这也是iOS上“忽略此设备”、Android上“清除蓝牙共享数据”后一切要重来的原因。在iOS开发里绑定还有一个隐藏坑如果你在centralManager(_:didDiscover:advertisementData:rssi:)回调里拿到的是peripheral对象但当你调用connect(_:options:)时使用了新的peripheral实例iOS很可能因为peripheral的UUID不一致而无法恢复之前的加密上下文导致连接成功后仍然要求重新配对。我的习惯是所有拿到的peripheral实例统一保存在一个[UUID: CBPeripheral]字典里每次连接都用同一个实例。3.3 实际项目中如何选择安全等级如果做的是心率计、温湿度传感器这类非敏感数据设备用Just Works配对即无MITM保护的Secure Connections就够用了。Just Works本质是“无需用户输入直接确认”安全性比Legacy但不如数值比较胜在用户无感知。如果设备涉及支付、门锁、医疗数据则必须开启MITM保护并且设备端最好带显示屏或键盘否则无法弹数值比对。BLE安全等级的选型逻辑和Web HTTPS并不完全一样更多是“身份确认数据加密”的组合只用加密不确认身份仍然会被中间人攻击。密钥更新和加密续期也是容易被忽略的。连接建立后可以用encrypt命令重新生成链路层加密密钥这个过程叫密钥刷新Key Refresh。在LE Secure Connections里LTK本身可更新协议栈会使用DHKey交换生成新的LTK。但由于LTK更新频率极低很多工程师干脆忽略了这一步。如果设备长期在线建议每隔几小时或每次关键操作前主动触发一次密钥刷新降低长期同一密钥带来的泄露风险。4. GATT与ATT你读写的那条数据通道到底是什么连接只是修了一条路路上面跑的“车”是ATTAttribute Protocol和GATTGeneric Attribute Profile。绝大多数开发者对GATT的理解停留在“找Service、找Characteristic、读、写、订阅通知”这个层面但这个层面之下还有一堆设计取舍值得搞懂。4.1 Attribute的构成和句柄ATT的基本单元是Attribute属性每个属性由四部分组成Attribute Handle句柄、TypeUUID、Permissions权限、Value值。句柄是一个16位的索引协议栈内部用它来定位属性。Type用UUID表示可以是16位的标准UUID也可以是128位的自定义UUID。Permissions定义了该属性是否可读、可写、是否需加密、是否需要认证。权限是由server侧的ATT层强制执行的不是逻辑上的约定客户端没有权限时直接返回错误码。GATT在ATT之上定义了Service、Characteristic、Descriptor这三层。Service是一组相关Attribute的集合Characteristic包含一个声明Declaration和若干属性值是数据交互的最小单元。Descriptor则是对Characteristic的补充描述比如NOTIFY、INDICATE使能开关CCCD就是一个常见的Descriptor句柄固定为0x2902。4.2 通知、指示与写入的实际差异GATT有四种数据上行方式Read、Write、Notify、Indicate。Read是客户端发请求服务端返回Write是客户端写入Notify是服务端主动推数据但不需要客户端ACKIndicate是服务端推数据客户端必须回ACK。Notify丢包不感知适合高频数据和允许偶发丢失的场景比如心率、加速度计原始数据Indicate有可靠性保证适合命令响应、电量监测这类不能丢的数据。选择Notify还是Indicate不仅是可靠性的差异还直接影响功耗。Notify由于无需ACK双方射频开启的时间短功耗更低Indicate每个包都要等待ACK等于每个数据包至少占用两个连接事件。如果数据量大且要求不丢可以考虑用Notify加应用层序列号的方式来兜底而不是无脑Indicate。4.3 Write Without Response和MTU放大GATT写入也分两类Write Request带响应和Write Without Response不带响应。带响应的写入需要server逐包回ACK速度和抗干扰更好不带的吞吐率更高但不保证送达。在iOS上CBPeripheral的maximumWriteValueLength(for:)方法可以查询当前连接的最大写入长度MTU交换后这个值一般在185字节左右如果不做MTU协商就只有23字节。你说的“根据蓝牙的deviceid建立连接”实际上iOS侧建立连接用的是UUID不是设备广播里的deviceid这一点在uni-app跨平台开发里尤其容易踩坑。4.4 GATT安全权限和缓存ATT的Permissions和Characteristic的Properties是两个维度的概念。Properties读、写、通知、指示是“这个东西能不能这样操作”的能力描述Permissions是“要达到什么安全等级才能操作”的准入控制。举个例子一个Characteristic可以声明可读属性但Permissions要求必须加密才能读。在iOS CoreBluetooth里你需要在service的CBCharacteristicProperties里设置.notifyEncryptionRequired来实现类似效果。可惜这个API比较冷门很多开发者根本不知道存在导致他们用明文传输敏感数据而不自知。GATT还有一个容易出问题的机制是缓存GATT Cache。服务发现和属性枚举很耗时所以协议栈会把发现的信息缓存起来下次连接直接复用。但如果服务端改了Service结构客户端却还拿着旧缓存就会出现“读到空值、写不了、特征找不到”的怪问题。Android上遇到这种情况正确做法是清除系统蓝牙缓存通常在系统设置-蓝牙里“清除共享数据”或者修改Service的UUID和特征数强制客户端重新发现。iOS上则可以通过CBPeripheral的discoverServices(nil)和discoverCharacteristics手动重新发现。实际项目中每次OTA固件升级后如果服务端有结构变化最好建议用户冷启动App并清除蓝牙缓存防止被旧数据坑半天。5. 广播扩展与扫描响应BLE 5.0之后的数据通道重构BLE 5.0引入了几个对应用层影响深远的能力2M PHY、Coded PHY、广播扩展Advertising Extensions、以及更大的广播数据包。广播扩展是很多人没吃透的一个点它在底层对广播包的发送方式做了重构从原来只能在一个广播信道上发一个短包变成了可以在广播信道上先发一个“辅助包”AUX_ADV_IND里面指明真正的广播数据在哪个次要信道Secondary Channel上、以什么事件偏移发送。数据部分则转移到次要信道上通过连续事件传输最多可以支持1650字节的广播数据。这个机制的问题在于广播扩展的兼容性不如传统ADV_IND。如果你把广播类型从传统改成扩展广播老的BLE 4.x设备可能就看不到你了。实际做项目时如果目标用户里含旧设备建议开启兼容模式同时发送传统广播和扩展广播或者只在需要大广播载荷时切换。扫描响应Scan Response则是另一个实用但容易被忽略的机制。外设发一个可扫描广播扫描方可以主动请求一个额外的扫描响应包最多31字节。这个包里可以放广播包里放不下的信息比如设备名称、服务UUID列表。iOS设备在后台扫描时系统不会主动请求扫描响应除非你实现了centralManager(_:didDiscover...)并规定扫描选项里包含CBCentralManagerScanOptionAllowDuplicatesKey并且在回调里主动调用retrievePeripherals(identifiers:)。这又是一个和Android行为不同的点Android的ScanFilter和ScanSettings可以配置是否请求扫描响应。6. BLE Mesh Remote Provisioning远程配网是怎么把门槛再降一截的BLE Mesh本身已经比较复杂Mesh Remote Provisioning远程配网则是在Mesh网络中通过已配网的节点为中继节点之外的未配网设备完成配网。传统BLE Mesh配网要求新设备必须在一跳范围内由配网器Provisioner通过广播或GATT承载直接完成配网。但在实际工程中设备可能被安装在天花板、管道井或者墙内人根本凑不到跟前这时候远程配网就派上用场了。Remote Provisioning的基本思路是配网器先和某个已入网的节点建立一条远程配网通道这个节点作为“代理”转发配网PDU给远处的未配网设备。具体工作机制涉及Mesh的Subnet Bridge功能和Remote Provisioning Server/Client模型。新设备要支持Remote Provisioning Protocol节点要支持Remote Provisioning Server配网器要支持Remote Provisioning Client。协议栈里远程配网的PDU封包格式和普通配网几乎一样只是承载方式多了代理关系这一层。实现层面的关键点是扫描阶段的协议交互。传统的Provisioning扫描是配网器自己扫描附近的未配网设备但远程配网需要代理节点报告它能看到哪些未配网的beacon再由配网器指定代理节点去连接并配网。这意味着节点侧要维护一个“可达未配网设备列表”并且支持把扫描结果异步上报给配网器。如果你用的是Zephyr或Nordic的nRF Connect SDK这个功能已经有现成example可以参考但要注意不同芯片的Flash空间和RAM限制Remote Provisioning会显著增加协议栈内存占用。7. ESP32轻度睡眠打开BLE低功耗场景的实测与避坑ESP32的低功耗一直是大家关心的点尤其是“轻度睡眠”Light Sleep下能不能保持BLE连接和广播。答案是能但效果取决于你的硬件设计和软件配置。ESP32在Light Sleep模式下CPU停止运行片上SRAM保持供电可以配置定时器或外部IO唤醒。为了让BLE在轻度睡眠下仍然工作需要把蓝牙控制器Controller保留在睡眠状态中的一部分功能让调制解调器保持唤醒以维持连接事件这就是ESP-IDF中的modem sleep模式。在Modem Sleep模式下ESP32的射频只在连接事件前后打开其余时间关闭整体电流可以做到几毫安级别但连接保持不受影响。具体到ESP-IDF配置需要关注几个参数CONFIG_BTDM_CTRL_MODEM_SLEEP、CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG或EBBR、以及bt_controller_enable时传入的bt_sleep_enable标志。如果你用的是ESP-IDF的esp_bt_controller_config_t默认sleep模式可能是ESP_BT_MODEM_SLEEP_MODE_ORIG这个模式下广播间隔和连接间隔会被主机限制实测中容易发现广播间隔和设定值不符。切换到EBBR模式后行为更符合预期功耗也更低。你还需要处理主机侧的睡眠协作。ESP32的Bluedroid或NimBLE协议栈在Light Sleep状态下不能直接被中断唤醒必须用esp_pm模块配置电源管理锁Power Management Lock。连接或广播期间建议用esp_pm_lock_acquire获取一个ESP_PM_APB_FREQ_MAX锁在连接事件或广播事件结束后立即释放。实测下来连接间隔30ms、slaveLatency4时Light Sleep下的平均电流大概在2到5毫安比Active模式下的30毫安低一个数量级。如果不加锁直接进Light Sleep你会发现蓝牙经常断连或唤醒不及时。ESP32的另一个坑是射频前端校准和睡眠唤醒后的执行时间。每次从Light Sleep醒来系统需要重新锁相环和校准RF这个时间大概在几十到上百微秒。如果睡眠时间太短小于几个连接间隔频繁唤醒反而比不睡更耗电。我的建议是连接间隔在50ms以上、且slaveLatency≥2时再用Modem Sleep否则直接保持Active效率反而更高。8. 平台开发中的BLE细节iOS 13、iPhone 13与uni-app的典型坑最后聊几个具体平台上的BD问题。iOS系统从13开始强化了后台蓝牙限制iPhone 13系列运行iOS 17之后的设备也不例外。核心变化有两个一是后台扫描时CBCentralManagerScanOptionAllowDuplicatesKey默认不生效二是后台状态下只能使用有限的服务UUID过滤。如果你在后台想要持续收到广播包必须在前台提前把设备加入扫描或者使用CBPeripheralManager启动外设模式。关于“uni-app里能不能基于BLE deviceid建立连接”这个问题我得先厘清概念。uni-app封装了uni.openBluetoothAdapter、uni.startBluetoothDevicesDiscovery、uni.createBLEConnection等一系列API。在uni-app和iOS原生层面你拿到的deviceId字段其实对应的是CoreBluetooth的identifier UUID而不是广播数据里的设备自定义ID。iOS的identifier本质是一个随机生成的UUID系统每次重置蓝牙缓存或还原设备时可能变。所以“根据deviceid建立连接”在iOS上成立的前提是这个deviceid必须是通过扫描得到的那一版identifier而且要保证它还没被系统重置。如果把后端数据库里存的自定义deviceId直接拿来调用connect大概率连接失败。uni-app在iOS上还有一个坑是MTU。uni.setBLEMTU在iOS上无效因为iOS的MTU由系统根据连接情况自动协商无法由客户端强制设置。你只能通过uni.getBLEDeviceCharacteristics拿到特征后再用uni.readBLECharacteristicValue去试探。实测下来iOS上的MTU默认是185Android则可以用setBLEMTU主动调整到512。如果你的业务需要快速传输大量数据跨两端时一定要做不同的分包策略。iPhone 13系列本身还有一个天线和射频特性值得注意——它支持BLE 5.0但没有开放2M PHY的外部配置接口CoreBluetooth在连接时是自动选择PHY的。开发者在iOS上不需要也不能手动指定PHY系统会在centralManager(_:didUpdate:peripherals:...)回调后自动协商。Android上则需要用BluetoothLeAudioCodec或BluetoothGatt的setPreferredPhy来主动选。这种平台差异导致同样的外设在Android上可能跑到了2M PHYiOS上却还是1M吞吐率表现自然不同。调试时要先确认双方的PHY版本否则表面看是代码问题实际是物理层速率的问题。9. 开发调试中的几个通用排查链路不管用什么平台BLE调试有个通行的排查链路我把它固化成了自己的排查清单。第一步是先看广播。用nRF Connect或LightBlue扫描确认设备在广播、广播类型正确、广播数据里包含期望的服务UUID。如果扫描不到检查三件事设备是否处于可发现模式、广播类型是否可连接或可扫描、频段信道是否被Wi-Fi干扰。第二步是看连接。连接失败时抓取Host日志确认链路层返回的错误码0x3E表示连接超时0x22表示LL参数不被接受0x13表示远程用户终止连接。第三步是看服务。连接成功后主动discoverServices看能否枚举到所有Service和Characteristic枚举不到就考虑GATT缓存问题。第四步是看数据。用日志工具打印ATT层的收发区分是Notify没发出来、MTU不够、还是接收方没使能CCCD。最后别忽略Android的BluetoothAdapter状态变化回调。Android的BLE连接在系统蓝牙开关切换或飞行模式切换后经常隐性断开且不会触发onConnectionStateChange回调这是Android的BluetoothGatt断开机制和iOS的差异之一。遇到“明明连着却收不到数据”的问题建议在应用层加一个心跳机制定时读取一个只读特征或发一个空的Write Request用返回值判断连接是否还活在这条链路上。这个方法实现成本极低却能在线上环境里省掉大量无谓的排查时间。10. 关于BLE功耗、距离、吞吐率的三组实测数据做技术笔记还是得留点硬数据收尾。以下三组数据来自我多个项目中的实测环境和设备不同会有浮动但数量级是可靠的。功耗方面单次广播间隔100ms的Beacon设备使用CR2032电池约220mAh平均电流约5到10微安理论续航2到3年。带连接的心率胸带连接间隔30ms、slaveLatency4平均电流约0.5到1.5毫安使用120mAh电池能跑4到7天。ESP32在连上BLE但处于Modem Sleep的模式下整体电流约3毫安能撑几天到两周不等。距离方面1M PHY在开阔空间的实际有效距离通常是10到30米Coded PHY 125kbps可以到100到200米但如果中间有墙或金属结构衰减非常明显。吞吐率方面2M PHY配合MTU 512和Write Without Response实测最大吞吐率约1.2Mbps到1.4Mbps1M PHY则只有600到800kbps。如果你要传音频或OTA固件这个吞吐率差异直接决定了体验。这三组数据不是用来背的而是帮助你在方案设计阶段快速判断BLE是否够用。需要高吞吐走Wi-Fi需要长续航走BLE需要远距离且数据量小走Coded PHY千万不要拿BLE去硬扛几Mbps的连续数据流那不是它的设计目标。我见过太多项目前期拍脑袋定了BLE方案中期发现带宽不够后期只能改硬件代价远比一开始选型时多花两天调研要大得多。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →