BLE Legacy 广播【TX_Power_Level  Tx Power  RSSI】注意:不要仅通过RSSI来判断远近
TX_Power_Level、Tx Power、RSSI 很容易被混在一起先给结论TX_Power / TX_Power_Level 表示“发射端发射这个无线包时使用的发射功率”单位通常是 dBm。RSSI 表示“接收端收到这个无线包时测到的信号强度”单位也是 dBm。Tx Power 是发送侧概念。RSSI 是接收侧概念。首先TX_Power 和 TX_Power_Level 是不是一回事在很多上下文里可以近似理解为一回事但严格说有细微差别TX_Power_Level 更像“某个字段名”表示发射功率等级。TX_Power 更像“通用概念”或某些 HCI event/API 里的字段名。所以基本可以认为就是一个指向。TX Power 是什么意思它表示本机蓝牙芯片发 Legacy 广播包时大概用了多大的发射功率。dBm 是什么dBm是一个功率单位。可以暂时不用深入射频公式只要知道dBm 越大发射功率越强dBm 越小发射功率越弱。所以 Tx Power 可以理解为蓝牙模块“喊话”的音量。RSSI 可以理解为手机“听到”的音量。TX Power 由什么决定这个问题要分层看。第一由蓝牙芯片 / 射频硬件能力决定不是所有芯片都能随便设置任意 Tx Power。比如某些芯片可能支持-20 dBm 到 4 dBm另一些芯片可能支持-40 dBm 到 8 dBm还有一些芯片可能支持-127 dBm 到 20 dBm注意规范写的Range: -127 to 20 dBm Accuracy: ±4 dB这是 HCI 参数表达范围不代表每个芯片真的都支持从 -127 到 20。具体支持哪些档位要看芯片厂商。第二由 Controller 当前配置决定蓝牙 Controller 里面一般会有发射功率配置。不同厂商的芯片可能通过不同方式配置厂商私有 HCI Command 芯片 SDK API AT 指令 配置工具 固件默认参数比如你做蓝牙模块时可能模块 AT 指令里会有类似设置广播发射功率 设置 BLE Tx Power 设置 RF Power这些最终可能会影响 Controller 发送广播时的实际 Tx Power。第三由广播类型 / PHY / 信道策略决定在 Legacy 广播里主要是在 primary advertising channels 上发37 38 39通常可以理解为使用同一个 advertising physical channel Tx Power。但在更复杂的 BLE 体系里不同 PHY、不同角色、不同链路状态可能有不同发射功率控制。例如Advertising Tx Power Connection Tx Power LE 1M PHY Tx Power LE 2M PHY Tx Power LE Coded PHY Tx Power这些不一定完全一样。第四由法规限制决定2.4GHz 无线发射功率不是芯片想多大就多大。不同国家/地区对无线发射功率有限制。所以即使芯片硬件支持更高功率实际产品固件里也可能限制在某个范围内。第五由功耗策略决定BLE 设备尤其是电池设备通常不会一直用最高功率。因为Tx Power 越高耗电越高。 Tx Power 越低耗电越低。所以厂商会根据产品定位选择功率。例如Beacon可能希望广播距离远一些 手环可能希望功耗低一些 蓝牙模块调试工具可能默认用较高功率方便发现 近距离配网设备可能故意降低发射功率区别于Advertising Data 里的 AD Type 0x0A Tx Power Level这个是广播数据里主动携带的字段。格式类似02 0A EC含义是Length 0x02 AD Type 0x0A Value 0xEC -20 dBm这个值会放进广播数据里。扫描方可以从LE Advertising Report event - Data[i]里面解析出来。Android 里通常对应ScanRecord.getTxPowerLevel()注意只有广播数据里真的带了 AD Type 0x0A扫描方才能解析到。没带就拿不到。TX_Power_Level 和 AD Type 0x0A 的关系可以这样对应项目含义HCI_LE_Read_Advertising_Channel_Tx_Power返回的TX_Power_LevelController 当前用于 LE 广播物理信道包的发射功率Advertising Data 里的AD Type 0x0A Tx Power Level广播包中声明给扫描方看的发射功率值扫描方 AndroidScanRecord.getTxPowerLevel()Android 从广播数据AD Type 0x0A解析出来的值所以理想情况下HCI 读出的 TX_Power_Level ↓ 填入广播数据 AD Type 0x0A ↓ 扫描方 ScanRecord.getTxPowerLevel() 解析出来这三个值应该一致。但是这两个值不一定天然自动同步这是一个很重要的点。HCI_LE_Read_Advertising_Channel_Tx_Power读到的是 Controller 当前广播物理信道发射功率。而AD Type 0x0A只是放进广播数据里的一个字节。它们之间不是自动绑定的。也就是说如果你这样乱填实际广播发射功率0 dBm 广播数据里写02 0A EC那么扫描方会解析出Tx Power Level -20 dBm但这只是广播数据里声明的值不代表真实发射功率真的就是 -20 dBm。所以比较规范的做法是广播数据里 AD Type 0x0A 的值要和实际广播发射功率保持一致。而读取LE Read Advertising Physical Channel Tx Power就是一种保证一致性的方式。比较规范、比较自洽的做法是如果你想在 Advertising Data / Scan Response Data 里放 AD Type 0x0A Tx Power Level那么这个值最好应该和 Controller 实际广播发射功率一致。但是要注意并不是所有的蓝牙模组都会按照这个规范来。TX_Power 和 RSSI 的关系这两个一定要分开。假设模块发广播时Tx Power 0 dBm手机收到时RSSI -52 dBm可以理解为模块发出时是 0 dBm 信号经过空气、距离、遮挡、天线损耗之后 手机收到时测到 -52 dBm。所以Tx Power发送端发出去时的强度 RSSI接收端收到时的强度类比一下Tx Power 一个人说话时的音量 RSSI 你站在某个位置听到的音量同一个人用同样音量说话你离得近听起来大离得远听起来小。同一个 BLE 设备用同样 Tx Power 发广播手机离得近 RSSI 高离得远 RSSI 低。为什么有时候 Tx Power 用来估算距离因为理论上已知发射功率 Tx Power 再测得接收强度 RSSI 就可以估算中间路径损耗简单理解Path Loss ≈ Tx Power - RSSI例如Tx Power 0 dBm RSSI -60 dBm Path Loss ≈ 60 dB损耗越大通常距离越远。但是这个估算非常粗糙因为 RSSI 波动很大。例如同一个设备不动手机方向变了RSSI 会变 人体挡住了RSSI 会变 附近有金属RSSI 会变 换个手机RSSI 会变 广播信道不同RSSI 会变所以 Tx Power RSSI 可以辅助判断距离趋势但不能精确测距。但是如果仅仅通过RSSI来粗略判断远近那就太“粗燥”了1. 为什么不能只看 RSSI因为 RSSI 是接收端测到的值。例如手机扫描到两个设备设备 ARSSI -50 dBm 设备 BRSSI -60 dBm很多人会直接判断A 比 B 近但这不一定对。因为可能是设备 A 发射功率很低但距离很近 设备 B 发射功率很高但距离较远也可能是设备 A 天线方向正对手机 设备 B 被人体/墙体/金属遮挡所以 RSSI 强不一定就是近RSSI 弱也不一定就是远。2. 更合理的是看 Path Loss更合理的粗略判断方式是看路径损耗 ≈ Tx Power - RSSI例如设备 A Tx Power 0 dBm RSSI -50 dBm Path Loss ≈ 50 dB 设备 B Tx Power 8 dBm RSSI -50 dBm Path Loss ≈ 58 dB虽然两个设备的 RSSI 都是-50 dBm但是设备 B 发射功率更高结果手机收到的还是-50 dBm说明中间损耗更大。所以从粗略角度看设备 B 可能更远或者中间遮挡/损耗更大。但 Tx Power RSSI 也只能“粗略估计”即使用了 Tx Power 和 RSSI也不能精确测距。因为 RSSI 还会受很多因素影响手机型号 手机蓝牙天线位置 模块天线设计 人体遮挡 墙体遮挡 金属反射 2.4GHz 干扰 广播信道 37 / 38 / 39 差异 设备摆放方向 手机握持方式 环境多径反射所以正确态度应该是RSSI 不能直接代表距离 Tx Power RSSI 可以粗略反映路径损耗 路径损耗可以辅助判断远近趋势 但不能当成精确距离。

相关新闻