Read data from BLE device Read data from BLE device objective-c objective-c

Read data from BLE device


To read a value from a BLE peripheral device, follow these steps

  1. Scan for avilable devices

    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];[self.myCentralManager scanForPeripheralsWithServices:nil options:options];`
  2. On detecting a device, will get a call back to "didDiscoverPeripheral" delegate method. Then establish a connection with detected BLE device

    -(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. On successful connection, request for all the services available in the BLE device

    - (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. Request all the characteristics available in each services

    - (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. Once we get the required characteristics detail, we need to subscribe to it, which lets the peripheral know we want the data it contains

    - (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. Completing all these steps, BLE device will let you know the notification status change through delegate method

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

You will recieve any notification from BLE device in the following method

- (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 of itZme's answer with a little modification due to didConnectToPeripheral not being called (you also need to keep a strong reference to the peripherals in order to connect, as follows):

Scan for available devices:

centralManager.scanForPeripheralsWithServices(nil, options: nil)

On detecting a device, will get a call back to "didDiscoverPeripheral" delegate method. Then establish a connection with detected BLE device. But also keep a strong reference of the peripherals first:

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

And the rest should be like this:

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