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;

person WrightsCS    schedule 23.08.2012    source источник


Ответы (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 секунду было достаточно, но это зависит от того, как часто ваше периферийное устройство рекламирует (то есть его интервал рекламы).

person Anders    schedule 06.10.2012

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

person jojo    schedule 27.08.2012

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

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

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

person l0gg3r    schedule 17.02.2014