2012-03-28 4 views
13

Ich habe gerade mit dem Kern-Bluetooth-Framework für iOS begonnen und ich entwickle eine App, die ständig nach BLE-Geräten suchen muss, damit ich ihre RSSI-Nummer jede Minute abrufen kann damit.Core Bluetooth - konstante RSSI-Updates von Geräten innerhalb der Reichweite

Zur Zeit habe ich:

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

dies beginnt meine app-Scanning für BLE Geräte und ruft diese Delegatmethode, wenn ein Gerät entdeckt wird:

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

diese Methode wird mir die RSSI Anzahl Peripherie die Ich kann anzeigen. Die letzte Zeile ruft dann diese Delegatmethode:

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

} 

Dieser Code scheint zu arbeiten und einen Scan etwa alle 1 Minute zu tun, aber ich weiß nicht genau, warum es funktioniert ...

Die Dokumentation Auf Core-Bluetooth ist ziemlich spärlich, wenn jemand eine Idee, wie dies zu tun hat, oder hat eine bessere Möglichkeit zu tun, was ich zu erreichen versuche, wäre ich dankbar für die Hilfe!

+0

scheint zu funktionieren ... Wie oft wird das RSSI aktualisiert? EDIT: Einmal pro Minute?Ich denke, es gibt eine Zeit, wenn Sie nicht verbinden, so dass es den Scan erneut startet. – chwi

+0

Ich habe gerade angefangen, die Dokumentation selbst zu lesen, also sind Sie weiter als ich. Frage, warum rufen Sie scanForPeripheralsWithServices in der Delegate-Methode didRetrievePeripherals auf? Sie rufen es bereits nach der Zuweisung des CBCentralManagers auf. Dies könnte den wiederholten Scan verursachen, den Sie erwähnt haben. – mkr707

+0

nur meine zwei cent für> = 7.0: retrievePeripheralsWithIdentifiers muss von jetzt an verwendet werden. –

Antwort

20

Haben Sie versucht, die Scanoption auf JA zu setzen?

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

Wenn Sie dies tun, werden Sie Ihre „didDiscoverPeripheral“ Rückruf bei jeder Anzeige-Paket erhalten, die von Ihrem iPhone zu sehen ist, die in der Regel etwa alle 100 ms wäre (obwohl ich diese Callback-Timing sehen eine Menge für die gleiche Variation Gerät). Dies beinhaltet die RSSI jedes einzelnen Gerätes.

Dies sollte viel schneller sein als Ihre ~ 1 Minute Update-Rate.

+1

Was ist das Swift-Äquivalent für diese beiden Zeilen? – Gerard

+0

@Gerard: Siehe meine Antwort unten. – kbpontius

+1

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

3

Soweit ich sehen kann, sollte dies tun, was Sie wollen.

Wenn Sie nach dem Scannen von Peripheriegeräten mit dem ursprünglichen Anruf gesucht haben, sollte Ihr Stellvertreter Anrufe erhalten, sobald ein BLE-Gerät erkannt wird. Dies wird fortgesetzt, bis Sie den Scan mit einem Aufruf an

[manager stopScan]; 

stoppen Ich glaube nicht wirklich Sie den zweiten Anruf scanForPeripheralsWithServices in Ihrem centralManager benötigen: didRetrievePeripherals Methode, da, soweit ich weiß, die Scan-doesn Hör auf, bis du es sagst. Ich fange trotzdem noch damit an, und es kann noch eine Auszeit geben, die ich noch nicht gefunden habe.

Ich bin ziemlich sicher, der Grund, warum Sie etwa einmal pro Minute einen Anruf erhalten, ist, weil das BLE-Gerät nur so oft Werbung macht. Wenn es öfter Werbung macht, wie ein Gerät im Discovery-Modus, denke ich, dass Sie die Anrufe öfter bekommen werden. Ich wäre interessant, wenn Sie das bestätigen könnten. Wenn das Gerät über einen Erkennungsmodus verfügt, versuchen Sie möglicherweise, es auszulösen, um festzustellen, ob die Benachrichtigungen schneller werden.

2

Sie sollten nicht kontinuierlich scannen, da es sehr teuer für die Stromversorgung ist. Sobald Sie Geräte gefunden haben, erhalten Sie ein Array von CBPeripheral-Objekten zurück. Auf CBPeripheral können Sie RSSI lesen und einen Rückruf erhalten, wenn sich RSSI ändert. Siehe folgende Dokumentation: http://developer.apple.com/library/mac/#documentation/CoreBluetooth/Reference/CBPeripheralDelegate_Protocol/translated_content/CBPeripheralDelegate.html

+0

Muss '- [readRSSI]' das Peripheriegerät verbinden? –

+2

@BenMosher ja es tut. – luxcem

1

Swift Implementierung von @Anders Lösung:

manager.scanForPeripheralsWithServices(nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(bool: true)]) 
Verwandte Themen