2012-03-28 14 views
13

Po prostu zacząłem od podstawowej architektury bluetooth dla iOS i pracuję nad aplikacją, która musi stale skanować urządzenia BLE, aby móc pobierać ich numer RSSI co minutę lub więc.Core Bluetooth - stała aktualizacja RSSI urządzeń w zasięgu

Obecnie mam:

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

ten zaczyna moja aplikacja skanowanie urządzeń ble i nazywa to metoda delegata, gdy urządzenie zostanie wykryte:

- (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]];} 

metoda ta staje mi numer RSSI obwodowego, który mogę wyświetlić. Ostatni wiersz następnie wywołuje tę metodę Delegat:

- (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]; 

} 

Kod ten wydaje się działać i robi Skanuj mniej więcej co 1 minutę, ale nie wiem dokładnie, dlaczego to działa ...

Dokumentacja na rdzeń bluetooth jest dość rzadki, więc jeśli ktoś ma jakiś pomysł, jak to zrobić, lub ma lepszy sposób robienia tego, co próbuję osiągnąć, byłbym wdzięczny za pomoc!

+0

wydaje się działać ... Jak często RSSI aktualizowane? EDYCJA: Raz na minutę?Wydaje mi się, że jest pewien czas, kiedy się nie łączysz, aby ponownie rozpocząć skanowanie. – chwi

+0

Właśnie zacząłem czytać dokumentację, więc jesteś bardziej niż ja. Pytanie, dlaczego dzwonisz do ScanForPeripheralsWithServices w trybie delegatów didRetrievePeripherals? Wywołujesz go już po przydzieleniu CBCentralManager. Może to powodować powtarzanie skanowania, o którym wspomniałeś. – mkr707

+0

tylko moje dwa centy za> = 7.0: retrievePeripheralsWithIdentifiers musi być używany od teraz. –

Odpowiedz

20

Czy próbowałeś zmienić opcję skanowania na TAK?

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

Jeśli zrobisz to dostaniesz „didDiscoverPeripheral” zwrotnego z każdym pakietem reklam, które są postrzegane przez iPhone, które normalnie byłyby co około 100ms (choć widzę to zwrotna rozrządu różnym dużo dla tego samego urządzenie). Obejmuje to RSSI każdego urządzenia, które widzi.

To powinno być dużo szybsze niż twoja ~ 1 minuta aktualizacji.

+1

Jaki jest odpowiednik Swift dla tych dwóch linii? – Gerard

+0

@Gerard: Zobacz moją odpowiedź poniżej. – kbpontius

+1

Swift3: 'manager.scanForPeripherals (withServices: [sensorTagAdvertisingUUID], opcje: [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber (value: true)])' – nablahero

3

Jak daleko widać, powinno to zrobić to, co chcesz.

Po rozpoczęciu skanowania urządzeń peryferyjnych z pierwotnym połączeniem, uczestnik powinien zacząć odbierać połączenia za każdym razem, gdy wykryje urządzenie BLE. Będzie to kontynuowane do momentu zatrzymania skanowania z wezwaniem do

[manager stopScan]; 

Nie sądzę rzeczywiście trzeba drugie wywołanie scanForPeripheralsWithServices w swojej centralManager: Metoda didRetrievePeripherals, ponieważ, o ile mi wiadomo, nie robi skanowanie zatrzymaj się, dopóki jej nie powiesz. Nadal jednak zaczynam od tego, i nie ma jeszcze czasu, którego jeszcze nie znalazłem.

Jestem prawie pewny, że powodem, dla którego dzwonisz, raz na minutę, jest to, że urządzenie BLE reklamuje się tak często. Jeśli reklamuje się częściej, tak jak urządzenie w trybie wykrywania, to myślę, że będziesz częściej odbierać połączenia. Byłbym interesujący, gdybyś mógł to potwierdzić. Jeśli urządzenie ma tryb wykrywania, możesz spróbować go uruchomić, aby sprawdzić, czy powiadomienia przyspieszają.

2

Nie należy wykonywać ciągłego skanowania, ponieważ jest to bardzo kosztowne. Po odkryciu urządzeń masz do dyspozycji szereg obiektów CBPeripheral. Na CBPeripheral można odczytać RSSI i uzyskać wywołanie zwrotne, gdy zmienia się RSSI. Zobacz następującą dokumentację: http://developer.apple.com/library/mac/#documentation/CoreBluetooth/Reference/CBPeripheralDelegate_Protocol/translated_content/CBPeripheralDelegate.html

+0

Czy '- [readRSSI]' wymaga podłączenia urządzenia peryferyjnego? –

+2

@BenMosher tak to robi. – luxcem

1

Swift Wdrożenie rozwiązania @Anders:

manager.scanForPeripheralsWithServices(nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(bool: true)]) 
Powiązane problemy