gxmad
gxmad

Reputation: 2230

Get a string from BLE

Hello I am beginner in swift, and I am trying to make an application that communicate one BLE with a polar heart rate, I have a problem to get the correct information from data structure generated by characteristic.value, I really have a problem to transform that from uint8 to something more simple like int or strings.

her is my code:

func peripheral(_ peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) {

    if characteristic.uuid == POLARH7_HRM_MEASUREMENT_CHARACTERISTIC_UUID {
        print("Get the new heart BPM : ", terminator:"")

        var wavelength: UInt16?
        if let data = characteristic.value {
            var bytes = Array(repeating: 0 as UInt8, count:(characteristic.value?.count)!/MemoryLayout<UInt8>.size)

            data.copyBytes(to: &bytes, count:data.count)
            let data16 = bytes.map { UInt16($0) }
            wavelength = 256 * data16[1] + data16[0]

        }
        print("W : ")
        print(wavelength)
    }

    if characteristic.uuid == POLARH7_HRM_BODY_LOCATION_CHARACTERISTIC_UUID {
        print("Get the new sensor location", terminator:"")
        print(characteristic.value)
        //let data = NSData(data: characteristic.value as! Data)

    }

    if characteristic.uuid == POLARH7_HRM_MANUFACTURER_NAME_CHARACTERISTIC_UUID {
        print("Get the new name", terminator:"")
        print(characteristic.value)
    }

}

I trie a lot of ways, but I am new to swift and swift 3 is not easy because every year there is an update in this language so the most tips a found were in objective-c or swift 2. like in this exemples :

    // Instance method to get the manufacturer name of the device
- (void) getManufacturerName:(CBCharacteristic *)characteristic
{
    NSString *manufacturerName = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];  // 1
    self.manufacturer = [NSString stringWithFormat:@"Manufacturer: %@", manufacturerName];    // 2
    return;
}

or

    - (void) getHeartBPMData:(CBCharacteristic *)characteristic error:(NSError *)error
{
    // Get the Heart Rate Monitor BPM
    NSData *data = [characteristic value];      // 1
    const uint8_t *reportData = [data bytes];
    uint16_t bpm = 0;

    if ((reportData[0] & 0x01) == 0) {          // 2
        // Retrieve the BPM value for the Heart Rate Monitor
        bpm = reportData[1];
    }
    else {
        bpm = CFSwapInt16LittleToHost(*(uint16_t *)(&reportData[1]));  // 3
    }
    // Display the heart rate value to the UI if no error occurred
    if( (characteristic.value)  || !error ) {   // 4
        self.heartRate = bpm;
        self.heartRateBPM.text = [NSString stringWithFormat:@"%i bpm", bpm];
        self.heartRateBPM.font = [UIFont fontWithName:@"Futura-CondensedMedium" size:28];
        [self doHeartBeat];
        self.pulseTimer = [NSTimer scheduledTimerWithTimeInterval:(60. / self.heartRate) target:self selector:@selector(doHeartBeat) userInfo:nil repeats:NO];
    }
    return;
}

thanks in advance

Upvotes: 2

Views: 3057

Answers (2)

gxmad
gxmad

Reputation: 2230

perhaps other people searching the same answer after. here is the way I get the int.

let data = characteristic.value
let count = (data?.count)! / MemoryLayout<UInt8>.size
var array = [UInt8](repeating: 0, count: count)
data?.copyBytes(to: &array, count:count * MemoryLayout<UInt8>.size)
print("Get the new heart BPM : ", terminator : "")
if ((array[0] & 0x01) == 0) {
    let bpm = array[1]
    let bpmInt = Int(bpm)
    print(bpmInt)
}

Upvotes: 1

Thomas
Thomas

Reputation: 2063

The data sent from BLE devices is usually in unicode, so you will need to convert these unicode values to whatever you need it to be.

Here is an example for converting it to strings:

// Convert byte to unicode string
let unicodeString = String(data: characteristic.value!, encoding: String.Encoding.utf8)

// Initialize value
var value: String? = nil

// Convert unicode to actual value
for element in unicodeString!.unicodeScalars {
    value = "\(element.value)"
}

// If value exists
if let value = value {
    // Do something with the value
}

Upvotes: 2

Related Questions