2013-10-23 6 views
10

Ich bin ein Problem auftritt, wenn die Zeit, um einen Wert einer Charakteristik mit derKern Bluetooth verlangsamen, wenn Pakete das Senden

[peripheral writeValue:dataPacket forCharacteristic:writeChar type:CBCharacteristicWithResponse] 

und die IOS-Gerät tatsächlich physisch zwischen Schreiben des Bluetooth-Paket sendet progressiv mehr ergreift und länger.

Dies kann aus dem Debugger in der folgenden Ausgabe erläutert werden:

2013-10-23 14:12:17.510 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:17.595 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:17.598 Test App iOS[1561:60b] Packet response received 

2013-10-23 14:12:17.611 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:17.656 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:17.657 Test App iOS[1561:60b] Packet response received 

2013-10-23 14:12:22.601 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:23.123 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:23.125 Test App iOS[1561:60b] Packet response received 

2013-10-23 14:12:27.601 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:28.111 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:28.113 Test App iOS[1561:60b] Packet response received 

2013-10-23 14:12:32.611 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:34.595 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:34.597 Test App iOS[1561:60b] Packet response received 


2013-10-23 14:12:37.611 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:39.582 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:39.585 Test App iOS[1561:60b] Packet response received 

2013-10-23 14:12:42.611 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:44.570 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:44.573 Test App iOS[1561:60b] Packet response received 

2013-10-23 14:12:47.611 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:12:49.558 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:12:49.560 Test App iOS[1561:60b] Packet response received 

// Several packets omitted... 

2013-10-23 14:13:07.610 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:13:09.508 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:13:09.511 Test App iOS[1561:60b] Packet response received 

2013-10-23 14:13:12.610 Test App iOS[1561:60b] Packet sent 
2013-10-23 14:13:14.496 Test App iOS[1561:60b] Packet sent confirmation, error = (null) 
2013-10-23 14:13:14.498 Test App iOS[1561:60b] Packet response received 

// Und so weiter ...

Das Paket gesendete Nachricht wird am Ausgang der Leitung unmittelbar nach dem Befehl Writevalue Schreiben Sie das Datenpaket in das Merkmal.

Die Bestätigungsantwort für das Paket wird in der ersten Zeile der Delegatmethode didWriteValueForCharacteristic ausgegeben.

Die Nachricht Paketantwort empfangen wird in didUpdateValueForCharacteristic ausgegeben, die aufgerufen wird, wenn das BTLE-Gerät das Antwortpaket (über ein sekundäres Benachrichtigungsmerkmal) sendet, um den Empfang meines gesendeten Pakets zu bestätigen.

Wie zu sehen ist, ist die Zeit zwischen dem Aufruf der Methode writeValue forCharacteristic und dem Rückruf zur Bestätigung, dass das Paket in didWriteValueForCharacteristic gesendet wurde, anfänglich 85ms (was bereits langsam aber erträglich ist). Ich sende diese Pakete ungefähr alle 5 Sekunden und nach nur einer kleinen Anzahl von gesendeten Paketen erhöht sich diese auf ~ 2 Sekunden, nach denen sie konstant bei 2 Sekunden zu bleiben scheint. Das Antwortpaket, das von dem BTLE-Gerät zurückgesendet wird, ist immer ~ 2 ms nach der Bestätigung des Pakets, das gesendet wird.

Ich verstehe nicht, warum ich diese Verzögerung in den CoreBluetooth-Bibliotheken zwischen dem Aufruf von WriteValue und dem Bestätigungsaufruf didWriteValueForCharacteristic bekomme.

Im Übrigen funktioniert der Code einwandfrei (das BTLE-Gerät tut genau das, was es tun soll und keines der Pakete fehlt).

Ich habe eine Beispiel-App, die vom BT4.0-Modul-Hersteller (einschließlich Quelle) zur Verfügung gestellt wird, die diese wachsende Verzögerung nicht erlebt - leider ist die Beispiel-App für eine breite Palette von Implementierungen des Moduls ausgelegt, nicht nur unsere spezifische Implementierung und ist somit massiv komplex und enthält viel Code, der für unsere Implementierung nicht relevant ist. Ich habe Haltepunkte in jede Funktion in der Stichprobe gesetzt und bin manuell durchgegangen, um genau zu bestimmen, welche Befehle sie ausgeben, und ich glaube ich bin es Kopieren sie perfekt (aber offensichtlich nicht).

Ich kann nichts sehen, was sie tun, was ich nicht tue und umgekehrt. Der einzige Unterschied, den ich zwischen den beiden Projekten feststellen kann, ist der, dass meinerseits ARC verwendet wird und die manuelle Referenzzählung verwendet wird.

Weitere Informationen: Alles auf dem Haupt-Thread ausgeführt wird (wie es mit dem Modulhersteller Beispielanwendung ist) Ich schaffe den Central Manager die Hauptwarteschlange (ähnlich in Modulhersteller Beispielanwendung) CPU-Last auf dem iOS Gerät ist nur bei 3%, während meine App läuft und nichts scheint wegen CPU-Belastung etc. verzögert werden.

Ich reibe meine Haare mit diesem, und wenn jemand mögliche Ursachen oder Lösungen für dieses Problem vorschlagen kann Ich wäre ewig dankbar!

Danke, Rich-

+0

Es ist wirklich, wirklich interessant, dass ihre Probe App nicht diese Verzögerung nicht zeigt, sondern bei Ihnen der Fall ist. Ich habe keinen guten Grund, warum das so ist. Es ist Voodoo, aber um es auszuschließen, können Sie versuchen, eine einfache manuelle Retain-Count-App zu erstellen, um zu sehen, ob ARC es beeinflusst? – cbowns

+0

Es ist etwas, das ich in Erwägung gezogen hatte. Ich habe noch nie irgendwelche Probleme mit ARC gehabt, aber da ich andere Möglichkeiten ausschliesse, komme ich zu dem Schluss, dass ich beweisen muss, dass ARC nicht das Problem verursacht und etwas wie Sie vorschlagen. –

+0

Ich hatte noch einen weiteren Gedanken: Es könnte sich lohnen, sowohl Ihre CoreBluetooth-App als auch die Beispiel-App mit Instrumenten zu profilieren, um zu sehen, welche Objekte wann erstellt werden. Wenn Ihre App einen subtilen Fehler bei der Erstellung von Ressourcen hat, die nie veröffentlicht werden, benötigt CoreBluetooth möglicherweise mehr Zeit für die Aktualisierung von Objekten, die nicht mehr verwendet werden. Dies könnte der Grund für die Verlangsamung sein. – cbowns

Antwort

7

Ich habe einige Fortschritte in diesem Bereich und die Nachricht ist nicht gut gemacht. Es stellt sich heraus, dass meine ursprüngliche Beschreibung des Problems falsch ist. Ich hatte (immer eine schlechte Sache) angenommen, dass die von dem Modullieferanten produzierte Beispiel-App korrekt wäre, aber die Timing-Zahlen, die sie melden, falsch sind - wenn sie ~ 3ms zum Senden des Pakets und zum Abrufen der Antwort sagen, sind sie nur Timing von der -didWriteValueForCharacteristic und nicht die Zeit zwischen dem Aufrufen der WriteValueForCharacteristic und der DidWriteValueForCharacteristic - sobald ich diese Zeit inklusive ihrer App verhält sich so langsam wie meins.

Nach all den weiteren Untersuchungen scheint es, dass die iOS CoreBluetooth-Bibliotheken die Verzögerung verursachen, die zwischen dem Senden und Senden des Pakets liegt - diese willkürlichen Verzögerungen können zwischen 80ms und 2seconds liegen. Weiß jemand, warum die iOS-Bibliotheken beim Senden des eigentlichen Pakets so langsam sind? Unser gleichwertiger Code unter Android läuft mehr oder weniger sofort.

Wenn ich meinen zynischen Hut auf hätte, würde ich sagen, dass Apple dies absichtlich verhindern will, dass Anwendungen, die eine schnelle Antwort erfordern, mit BTLE entwickelt werden und dadurch die Hardwareentwickler zwingen, Bluetooth 3 zu verwenden, das den Apple Sicherheitschip benötigt und dadurch effektiv ein Apfel Lizenzkosten auf Einheiten entstehen hergestellt ...

+1

Ich habe das gleiche Problem. Hast du sonst noch etwas gefunden? – mohkhan

+0

Ich stieß auch auf dasselbe Problem mit iOS 9. Hat jemand jemals etwas herausgefunden? – Pierre

1

Zunächst einmal überprüfen, was Sie in erhalten:

-(void) peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic 
error:(NSError *)error { 

} 

wenn der Fehlercode ist 0 das heißt, Sie Wert senden, ohne es zu bestätigen, peripheren. Überprüfen Sie, ob Ihre periheral diese Methode implementiert:

//assuming 
@property (strong, nonatomic) CBPeripheralManager  *peripheralManager; 

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests 
{ 
    NSLog(@"WRITE REQUEST!!! %lu",(unsigned long)requests.count); 
    //check if there are data 

    for (CBATTRequest * req in requests) { 
    //send reposnse to Central that you recivied write value and eg/accept/reject the write request 
    [self.peripheralManager respondToRequest:req 
              withResult:CBATTErrorSuccess]; 
    } 


}