ios 核心蓝牙 - 范围内设备的持续 RSSI 更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9911102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:35:56  来源:igfitidea点击:

Core Bluetooth - constant RSSI updates of in-range devices

iosios5core-bluetooth

提问by kj13ennett

I just started with the core bluetooth framework for iOS and I'm developing an app that needs to constantly scan for BLE devices so that I can retrieve their RSSI number every minute or so.

我刚开始使用 iOS 的核心蓝牙框架,我正在开发一个需要不断扫描 BLE 设备的应用程序,以便我可以每分钟左右检索它们的 RSSI 编号。

Currently I have:

目前我有:

manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[manager scanForPeripheralsWithServices:nil options:options];

this starts my app scanning for BLE devices and calls this delegate method when a device is discovered:

这将启动我的应用程序扫描 BLE 设备并在发现设备时调用此委托方法:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    NSLog(@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.UUID, advertisementData);
    //Do something when a peripheral is discovered.

    rssiLabel.text = [RSSI stringValue];

    [manager retrievePeripherals:[NSArray arrayWithObject:(id)peripheral.UUID]];}

this method gets me the peripheral's RSSI number which i can display. The last line then calls this delegate method:

此方法获取我可以显示的外围设备的 RSSI 编号。最后一行然后调用这个委托方法:

- (void) centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals {

    NSLog(@"Currently known peripherals :");
    int i = 0;
    for(CBPeripheral *peripheral in peripherals) {
        NSLog(@"[%d] - peripheral : %@ with UUID : %@",i,peripheral,peripheral.UUID);

    }

     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
     [manager scanForPeripheralsWithServices:nil options:options];

}

This code seems to be working and doing a scan roughly every 1 minute, but I don't exactly know why it working...

这段代码似乎正在工作,并且大约每 1 分钟进行一次扫描,但我不完全知道它为什么工作......

The documentation on core bluetooth is pretty sparse so if anyone has any idea on how to do this, or has a better way to do what I'm trying to accomplish I'd appreciate the help!

关于核心蓝牙的文档非常少,所以如果有人知道如何做到这一点,或者有更好的方法来完成我想要完成的任务,我将不胜感激!

回答by Anders

Have you tried changing the scan option to YES?

您是否尝试将扫描选项更改为“是”?

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber  numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[manager scanForPeripheralsWithServices:nil options:options];

If you do this you will get your "didDiscoverPeripheral" callback with every ad packet that is seen by your iPhone, which would normally be about every 100ms (although I see this callback timing varying a lot for the same device). This includes the RSSI of each device it sees.

如果你这样做,你会得到你的 iPhone 看到的每个广告包的“didDiscoverPeripheral”回调,通常大约每 100 毫秒一次(尽管我看到这个回调时间对于同一设备有很大的不同)。这包括它看到的每个设备的 RSSI。

This should be a lot faster than your ~1 minute update rate.

这应该比大约 1 分钟的更新速率快得多。

回答by Mike

Is far as I can see, this should do what you want.

据我所知,这应该做你想做的。

When you started scanning for peripherals with the original call, your delegate should begin to get calls whenever a BLE device is discovered. This will continue until you stop the scan with a call to

当您开始使用原始呼叫扫描外围设备时,只要发现 BLE 设备,您的代理就应该开始接收呼叫。这将继续,直到您通过调用停止扫描

[manager stopScan];

I don't think you actually need the second call to scanForPeripheralsWithServices in your centralManager:didRetrievePeripherals method, since, as far as I know, the scanning doesn't stop until you tell it to. I'm still getting started on this, too, though, and there may be a timeout I have not found, yet.

我认为您实际上不需要在 centralManager:didRetrievePeripherals 方法中对 scanForPeripheralsWithServices 进行第二次调用,因为据我所知,扫描不会停止,直到您告诉它为止。不过,我也仍在开始这方面的工作,可能还没有找到超时。

I'm pretty sure the reason you get a call about once a minute is because the BLE device is only advertising that often. If it advertises more often, like a device in discovery mode, I think you will get the calls more often. I would be interesting if you could confirm that. If the device has a discovery mode, you might try triggering it to see if the notices speed up.

我很确定你每分钟接到一次电话的原因是因为 BLE 设备只是经常做广告。如果它更频繁地做广告,比如处于发现模式的设备,我认为你会更频繁地接到电话。如果你能证实这一点,我会很有趣。如果设备具有发现模式,您可以尝试触发它以查看通知是否加快。

回答by yuklai

You shouldn't do continous scanning as it is very costly for power. Once you discovered devices you have an array of CBPeripheral objects returned to you. On CBPeripheral you can read RSSI and get a callback when RSSI changes. See the following documentation: http://developer.apple.com/library/mac/#documentation/CoreBluetooth/Reference/CBPeripheralDelegate_Protocol/translated_content/CBPeripheralDelegate.html

您不应该进行连续扫描,因为它的功耗非常高。一旦你发现了设备,你就会有一个 CBPeripheral 对象的数组返回给你。在 CBPeripheral 上,您可以读取 RSSI 并在 RSSI 更改时获得回调。请参阅以下文档:http: //developer.apple.com/library/mac/#documentation/CoreBluetooth/Reference/CBPeripheralDelegate_Protocol/translated_content/CBPeripheralDelegate.html

回答by kbpontius

Swift Implementation of @Anders solution:

@Anders 解决方案的 Swift 实现:

manager.scanForPeripheralsWithServices(nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])