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