BLE 读取 RSSI 值不可靠

BLE read RSSI values unreliable

我正在尝试正确读取我所连接的 BLE 设备的 RSSI,以便将其发送到上游服务器。

我发现BluetoothGatt.readRemoteRssi()返回的RSSI有很多"jumps"。我开始做 运行 平均值(在过去 10 秒内)以获得更平滑的值。这没有帮助,因为该值有很多尖峰。

我发现做 mBluetoothAdapter.startLeScan(null); 可以使值更平滑。我知道官方文档不鼓励在连接到设备时进行扫描,但实际上 - 在 LG 和三星设备上它确实有效。

进一步 - 如果我将 null 作为回调传递,此方法将不执行任何操作(请参阅 https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/bluetooth/BluetoothAdapter.java#L2833)。这让我相信三星和 LG 确实修改了很多 Android 蓝牙堆栈。

谁能解释一下我看到了什么?谁能提供更好的读取 "real" RSSI 值的解决方案?


编辑:

我发现 onCharasteristicWritten() 被调用了好几次(?)具有相同的值,即使 HW 只发送了一次。我们现在正在手动过滤这些值。 onRssiRead() 也被调用了几次。

可能 是 Android 文档建议在连接到 BT 设备时不进行扫描的原因。

readRemoteRssi 方法 returns 已连接设备的 rssi 值,由蓝牙控制器测量。请注意,BLE 连接最多可在 37 个通道上运行,并在每个连接事件上跳转。

扫描得到的rssi值,是每个广告包的rssi值。广告只发生在三个渠道上。

主机端的蓝牙堆栈,即 Android 运行 中的软件 CPU 不会改变蓝牙控制器测量的 rssi 值。

所以我能看到您的不同结果的唯一原因是不同的无线电频道具有不同的 noise/quality 或相似之处。正如您可能在网上读到的那样,RSSI 的变化很大,而这正是我们必须忍受的。有关不同无线电频道的详细信息,请参阅 https://www.google.com/search?q=ble+channels

另请注意,远非所有外围设备在已连接到某物时继续通告。

如果您认为传递 null 没有任何作用,也许您可​​以检查 logcat 并查看是否打印了预期的错误消息?但是,我无法解释扫描将如何改变 readRemoteRssi 为已连接设备返回的值,因为那没有意义。如果您认为那是黑魔法,您必须询问蓝牙控制器公司 ;)