This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Reading BLE Characteristics in iOS

Hi - I am trying to send a signed 16bit Integer from nRF52 to iOS. Using the following characteristic reader from Nordic in the nRF Toolbox on Github (here).

        static func readSInt16Value(ptr aPointer : inout UnsafeMutablePointer<UInt8>) -> Int16 {
    let anInt16Pointer = UnsafeMutablePointer<Int16>(OpaquePointer(aPointer))
    let val = CFSwapInt16LittleToHost(UnsafeMutablePointer<UInt16>(OpaquePointer(anInt16Pointer)).pointee)
    aPointer = aPointer.advanced(by: 2)
    return Int16(val)
   }

On the nRF52 side, packaging as follows:

'#define UINT16_TO_BSTREAM(p,n) {*(p)++ = (uint8_t)(n); *(p)++ = (uint8_t)((n)>>8);}

Any guidance on what I might be doing wrong would be greatly appreciated. Thanks!

  • So BLE doesn't really care about data type. Are you trying to read the characteristic or are you sending notifications? To read a characteristic from iOS use the readValueForCharacteristic method. I guess you should look at the Core Bluetooth Programming Guide.

  • Thanks. I'm sending notifications. I probably could have framed the question better. Since I know the iOS side is correct since Nordic wrote it, I don't see any of the BLE examples that utilize a 16bit signed integer - they are all uint8. Simply changing the type from uint8 to int16 on the nRF side doesn't work. So I'm trying to understand how I would need to change one of the "typical" BLE examples so that it sends it in correct format. How does it need to be "packaged" on the nRF side?

  • Finally found the solution. There is no "packaging" necessary on the nRF side. One of the main issues was not being able to handle a negative 16bit number. Anyway, here is the Swift code in the "didUpdateValueForCharacteristic function:

      func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    
       if characteristic.uuid == CHAR1_UUID {
                   
       let data = characteristic.value
       var pointer = UnsafeMutablePointer<UInt8>(mutating: (data! as NSData).bytes.bindMemory(to: UInt8.self, capacity: data!.count))
                
       let char1Data = NORCharacteristicReader.readUInt16Value(ptr: &pointer)
       let s: Int16 = Int16(bitPattern: UInt16(char1Data))
    }
    }
    

    The only real change from the Nordic Toolbox code was to add the last line for the bitPattern. Anyway, hope it might help someone else with the same issue. Surprising how long it took for only one line of code!

Related