从BLE设备读取数据

我试图从蓝牙设备(BR-LE4.0-S2)读取数据。 我能够连接BLE设备,但是无法从中读取数据。我没有任何有关BLE服务的规范和特性。 这里我的问题是- (void)peripheral:didUpdateValueForCharacteristic:error:没有得到调用。 我遵循教程“ https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/PerformingCommonCentralRoleTasks/PerformingCommonCentralRoleTasks.html#//apple_ref/doc/uid/TP40013257-CH3-SW2 ”。以下是我的码。

我的要求是从BLE设备连续读取数据。 任何帮助是极大的赞赏。

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

要从BLE外围设备读取值,请按照下列步骤操作

  1. 扫描avilable设备

     NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; [self.myCentralManager scanForPeripheralsWithServices:nil options:options];` 
  2. 在检测到一个设备时,会回到“didDiscoverPeripheral”委托方法。 然后与检测到的BLE设备build立连接

     -(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]; } } 
  3. 连接成功后,请求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]; } 
  4. 请求每个服务中可用的所有特征

     - (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]; } } 
  5. 一旦我们获得了所需的特征细节,我们需要订阅它,让外围设备知道我们想要它包含的数据

     - (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]; } } } 
  6. 完成所有这些步骤后,BLE设备将通过委托方法让您知道通知状态更改

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

您将通过以下方法接收来自BLE设备的任何通知

 - (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. } } 

itZme的答案是由于didConnectToPeripheral没有被调用而进行了一些修改 (你还需要保留一个强大的外设以便连接,如下所示):

扫描可用设备:

 centralManager.scanForPeripheralsWithServices(nil, options: nil) 

在检测到一个设备时,会回到“didDiscoverPeripheral”委托方法。 然后与检测到的BLE设备build立连接。 而且还要保持对外设的强有力的参考:

 private var peripheral: [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) } } 

剩下的应该都是:

 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) }