CoreBluetooth подключается только к ближайшему RSSI (BLE)

Я ищу способ подключения только к ближайшему периферийному устройству на основе RSSI. Моя цель - оставить в списке другие периферийные устройства, но подключить их только к ближайшему периферийному устройству.

Поскольку RSSI доступен только при подключенном устройстве, имеет ли смысл подождать, пока все устройства будут подключены, затем определить ближайшую периферию на основе RSSI, а затем отключить остальные?

соединять

- (void) connectToPeripheral:(CBPeripheral *)peripheral
{
    NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE],CBConnectPeripheralOptionNotifyOnDisconnectionKey,nil];
    [myCBCentralManager connectPeripheral:peripheral options:options];
}

Делегаты использовали

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error;

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;

CBPeripheral

/*!
 *  @property RSSI
 *
 *  @discussion While connected, the RSSI of the link in decibels.
 */
@property(retain, readonly) NSNumber *RSSI;

3 ответа

Решение

Это то, что сработало лучше для меня. Сначала я сканировал периферийные устройства, а затем просто выбрал тот, который имеет самый высокий RSSI. (Да, это сообщает о RSSI для каждого устройства. Вам НЕ нужно сначала подключаться к нему).

Однако я нашел это ненадежным. Было просто слишком много колебаний в значении RSSI. Поэтому я сделал следующее.

Я использовал:

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];//allow duplicates with YES
[self.CM scanForPeripheralsWithServices:uuidArray options:options]; 

Обратный вызов:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 

Это будет продолжать сообщать RSSI каждого периферийного устройства, пока вы не вызовете метод:

[self.CM stopScan];

"DidDiscoverPeripheral" вам будет вызываться для каждого рекламного пакета, который видит Central (ваш iPhone). Добавьте подпрограмму в этот обратный вызов, чтобы усреднить RSSI для каждого найденного уникального периферийного устройства. Мой опыт показал, что времени сканирования в 1 секунду было достаточно, но это зависит от того, как часто ваше периферийное устройство рекламирует (то есть его рекламный интервал).

Вы можете прочитать значение rssi каждого периферийного устройства в методе делегата didDiscoverPeripheral, не подключаясь к нему.

Используйте https://github.com/LGBluetooth/LGBluetooth/ Сканирует периферию и сортирует по среднему RSSI.

[[LGCentralManager sharedInstance] scanForPeripheralsByInterval:4
                                                     completion:^(NSArray *peripherals)
 {
 }];

Вот пример кода, который сканирует периферию в течение 4 секунд и сортирует их по RSSI

Другие вопросы по тегам