J'essaie de lire des données à partir d'un périphérique Bluetooth (BR-LE4.0-S2). Je pouvais connecter un périphérique BLE, mais je ne pouvais pas en lire les données. Je n'ai aucune spécification concernant les services BLE et ses caractéristiques. Voici ce que mon problème est - (void)peripheral:didUpdateValueForCharacteristic:error:
ne pas être appelé. J'ai suivi le didacticiel " https://developer.Apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/PerformingCommonCentralRoleTasks/PerformingCommonCentralRoleTasks.html## -CH3-SW2 ". Voici mon code.
Quelle est mon exigence est de lire les données en continu à partir du périphérique BLE. Toute aide est grandement appréciée.
- (void)viewDidLoad
{
self.myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
self.peripheral = [[CBPeripheral alloc] init];
self.peripheral.delegate = self;
[super viewDidLoad];
}
- (void) centralManagerDidUpdateState:(CBCentralManager *)central {
switch (central.state) {
case CBCentralManagerStatePoweredOn:
[self.myCentralManager scanForPeripheralsWithServices:nil options:nil];
break;
default:
NSLog(@"Central Manager did change state");
break;
}
}
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
NSLog(@"Discovered %@", peripheral.name);
[self.myCentralManager stopScan];
NSLog(@"Scanning stopped");
if (self.peripheral != peripheral) {
self.peripheral = peripheral;
NSLog(@"Connecting to peripheral %@", peripheral);
// Connects to the discovered peripheral
[self.myCentralManager connectPeripheral:peripheral options:nil];
}
}
- (void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"Peripheral connected");
NSLog(@"Peripheral services : %@",peripheral.services );
[self.peripheral setDelegate:self];
[peripheral discoverServices:nil];
}
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error {
if (error) {
NSLog(@"Error discovering service: %@", [error localizedDescription]);
return;
}
for (CBService *service in peripheral.services) {
[peripheral discoverCharacteristics:nil forService:nil];
}
}
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error {
int i = 0;
for (CBCharacteristic *characteristic in service.characteristics) {
[peripheral setNotifyValue:YES forCharacteristic: characteristic];
}
}
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
NSData *data = characteristic.value;
NSString *value = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"Value %@",value);
NSString *stringFromData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Data ====== %@", stringFromData);
}
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
if (error) {
NSLog(@"Error changing notification state: %@",
[error localizedDescription]);
}
NSString *value = [[NSString alloc] initWithData:self.interestingCharacteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"Value %@",value);
NSLog(@"description: %@, descriptors: %@, properties: %d, service :%@, value:%@", characteristic.description, characteristic.descriptors, characteristic.properties, characteristic.service, characteristic.value);
NSData *data = characteristic.value;
if (characteristic.isNotifying) {
NSString *stringFromData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[peripheral readValueForCharacteristic:characteristic];
NSLog(@"Data ====== %@", @"ccdc");
} else {
[self.myCentralManager cancelPeripheralConnection:peripheral];
}
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"Peripheral Disconnected");
self.peripheral = nil;
// We're disconnected, so start scanning again
NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.myCentralManager scanForPeripheralsWithServices:nil options:scanOptions];
}
Pour lire une valeur d'un périphérique BLE, procédez comme suit.
Rechercher des périphériques disponibles
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.myCentralManager scanForPeripheralsWithServices:nil options:options];`
Lors de la détection d'un périphérique, sera rappelé à la méthode déléguée "didDiscoverPeripheral". Etablissez ensuite une connexion avec le périphérique BLE détecté
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
//Connect detected device....
if (!peripheral.isConnected) {
peripheral.delegate = self;
[bluetoothManager_ connectPeripheral:peripheral options:nil];
}
}
En cas de connexion réussie, demande pour tous les services disponibles dans le périphérique BLE
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
NSLog(@"Peripheral Connected");
// Make sure we get the discovery callbacks
peripheral.delegate = self;
// Search only for services that match our UUID
[peripheral discoverServices:nil];
}
Demander toutes les caractéristiques disponibles dans chaque service
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
if (error) {
NSLog(@"Error discovering services: %@", [error localizedDescription]);
return;
}
// Loop through the newly filled peripheral.services array, just in case there's more than one.
for (CBService *service in peripheral.services) {
[peripheral discoverCharacteristics:nil forService:service];
}
}
Une fois que nous obtenons les caractéristiques requises, nous devons nous y abonner, ce qui permet au périphérique de savoir que nous voulons les données qu'il contient.
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
// Deal with errors (if any)
if (error) {
NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
return;
}
// Again, we loop through the array, just in case.
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:REQUIRED_CHARA_ID]]) {
// If it is, subscribe to it
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
}
En effectuant toutes ces étapes, le périphérique BLE vous informera du changement d'état de la notification via la méthode de délégation.
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
if (error) {
NSLog(@"Error changing notification state: %@", error.localizedDescription);
}
// Notification has started
if (characteristic.isNotifying) {
NSLog(@"Notification began on %@", characteristic);
}
}
Vous recevrez une notification de périphérique BLE de la manière suivante
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (error) {
NSLog(@"Error reading characteristics: %@", [error localizedDescription]);
return;
}
if (characteristic.value != nil) {
//value here.
}
}
Swift version de la réponse de itZme avec une petite modification car didConnectToPeripheral
n'est pas appelé (vous devez également conserver une référence forte aux périphériques afin de vous connecter, comme suit):
Rechercher les appareils disponibles: _
centralManager.scanForPeripheralsWithServices(nil, options: nil)
Lors de la détection d'un périphérique, un appel sera renvoyé à la méthode déléguée "didDiscoverPeripheral". Ensuite, établissez une connexion avec le périphérique BLE détecté.Mais gardez également une référence forte des périphériques:
private var peripherals: [CBPeripheral] = []
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
if peripheral.state == .Connected {
self.peripherals.append(peripheral)
peripheral.delegate = self
centralManager.connectPeripheral(peripheral , options: nil)
}
}
Et le reste devrait être comme ça:
extension ViewController: CBPeripheralDelegate {
func centralManager(central: CBCentralManager, didFailToConnectPeripheral peripheral: CBPeripheral, error: NSError?) {
if error != nil {
print("Error connecting to peripheral: \(error?.localizedDescription)")
return
}
}
func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
print("Peripheral connected.")
peripheral.delegate = self
peripheral.discoverServices(nil)
}
func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) {
if error != nil {
print("Error discovering services \(error?.localizedDescription)")
return
}
for service: CBService in peripheral.services! {
peripheral.discoverCharacteristics(nil, forService: service)
}
}
func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) {
if error != nil {
print("Error discovering characteristics \(error?.localizedDescription)")
return
}
for characteristic: CBCharacteristic in service.characteristics! {
if characteristic.UUID == CBUUID(string: YOUR_CHARACTERISTIC_UUID) {
peripheral.readValueForCharacteristic(characteristic)
// for some devices, you can skip readValue() and print the value here
}
}
}
func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {
if characteristic.UUID == CBUUID(string: YOUR_CHARACTERISTIC_UUID) {
print(characteristic.value)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for newChar: CBCharacteristic in service.characteristics!{
peripheral.readValue(for: newChar)
if newChar.properties.rawValue == 0x10 || newChar.properties.rawValue == 0x8C{
peripheral.setNotifyValue(true, for: newChar)
}
else if newChar.properties.rawValue == 0x12{
peripheral.setNotifyValue(true, for: newChar)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
print(characteristic)
}