altbeacon 以 10Hz 连续检测信标 RSSI 值

altbeacon detection of beacon RSSI values continuously at 10Hz

我创建了一个 android (java) 应用程序,它使用 altbeacon 库 (github page) 通过蓝牙模块检测信标。

信标配置有 Eddystone UID,协议具有 100ms 的广告间隔和 t运行 强发射功率级别(10dBm)。 我想做的是检测频率为 10Hz(即 100 毫秒)的信标的 RSSI 值。

我已经准备了实现altbeacon库的服务,相关部分如下:

mBeaconManager = BeaconManager.getInstanceForApplication(this);

        beaconRegion = new Region("beacon_region", null, null, null);

        // use Eddystone protocol
        mBeaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));

        mBeaconManager.setAndroidLScanningDisabled(true);
        mBeaconManager.setForegroundScanPeriod(100l); // scan frequency
        mBeaconManager.setForegroundBetweenScanPeriod(0);

我从中看到信标并获取 RSSI 值的回调 didRangeBeaconsInRegion 是这样的:

@Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        Log.i(BeaconDataCollectorService.class.getSimpleName(), String.format("Found %s beacons in range", beacons.size()));
    }

What's my problem? Running the app, I notice that within didRangeBeaconsInRegion, I often don't see all the beacons.

我运行采集了几秒的数据,将获取到的数据创建成csv格式,可以看到我经常有0(表示没有检测到beacon);我把这个csv的分享放在pastebin (https://pastebin.com/zkUZC5R4)

如何通过始终能够检测到所有信标来提高扫描频率?

使用的 altbeacon 版本:

implementation 'org.altbeacon:android-beacon-library:2.16.3'

Android版本:9

谢谢

不幸的是,该库并非设计用于执行此操作,因为测距 API 是在 iOS 等价物之后建模的,这些等价物以固定的时间间隔进行聚合检测,而不是在它们到达时访问单个数据包。

如此短的扫描周期经常检测到 0 个信标的主要原因是扫描每 100 毫秒打开和关闭一次,并且需要 10 毫秒左右的时间来启动和停止。这很有可能错过检测。

好消息是:如果库在同一扫描周期内检测到两个信标数据包,那么它将停止关闭扫描,您的检测率将会提高。但是让它在 100 毫秒内检测到两个信标几乎是不可能的,因为您的信标以标称的 10Hz 做广告。

您可以尝试的一件事是首先将扫描周期设置为 1 秒。在您检测到有限数量的信标 10 秒左右后,您很有可能在一个扫描周期内检测到两个信标,然后您可以切换到 100 毫秒的扫描周期并获得更高的检测率。

您永远不会获得 100% 的检测率,原因有二:

  • 由于冲突和无线电噪声,并非所有传输的信标数据包都被接收。在近距离范围内,80-90% 是典型值。

  • “BLE 广告商不会定期发布广告。 他们会在发送数据包时随机化以避免冲突。标称 10Hz 的发射器可能有 70ms 之间的任何时间和单个数据包之间的 140 毫秒,因此对于 100 毫秒的固定扫描周期,有时会有 0、1 或 2 个包装器符合接收条件。

如果您确实需要在每次检测时都获得回调,您可以尝试在 BeaconManager 中设置一个 NonBeaconBleScanCallback,然后调用 BeaconManager.clearBeaconParsers()。这将导致所有信标检测在检测到时立即发送到该回调。然后,您将必须构建一个新的 BeaconParser 以在该回调中使用,以从原始数据包中解码信标。使用 beaconParser.parse(...)