从BLE设备读取数据

问题描述 投票:21回答:4

我正在尝试从蓝牙设备(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];
}
ios objective-c core-bluetooth
4个回答
72
投票

要从BLE外围设备读取值,请执行以下步骤

  1. 扫描可用设备 qazxsw poi
  2. 在检测到设备时,将回拨“didDiscoverPeripheral”委托方法。然后与检测到的BLE设备建立连接 NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; [self.myCentralManager scanForPeripheralsWithServices:nil options:options];`
  3. 成功连接后,请求BLE设备中的所有可用服务 -(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]; } }
  4. 请求每项服务中可用的所有特征 - (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]; }
  5. 一旦我们获得了所需的特性细节,我们需要订阅它,这让外围设备知道我们想要它包含的数据 - (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]; } }
  6. 完成所有这些步骤后,BLE设备将通过委托方法通知您通知状态的变化 - (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]; } } }

您将通过以下方法收到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);
    }
}

7
投票

由于没有调用- (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's answer进行了一些修改的swift版本(你还需要保留对外围设备的强引用以便连接,如下所示):

扫描可用设备:

didConnectToPeripheral

在检测到设备时,将回拨“didDiscoverPeripheral”委托方法。然后与检测到的BLE设备建立连接。但是首先要保留外围设备的强大参考:

centralManager.scanForPeripheralsWithServices(nil, options: nil)

剩下的应该是这样的:

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

0
投票
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)
    }       
}

}

-1
投票

首先你必须执行read()函数。如果执行read()函数,那么“didUpdateValueForCharesteristics”将会运行。你可以在这个函数中读取字符串值。这很简单。

© www.soinside.com 2019 - 2024. All rights reserved.