0

I try to create a small iOS app in Xcode, using Swift 3. I try to connect to a BLE device and then read battery level.

I get this response:

...UUID = Battery Level, properties = 0x12, value = <30>...

And then I try to convert the HEX 30 to decimal 48. But I don't know how.

I have tried this:

print(String(bytes: characteristic.value!, encoding: String.Encoding.utf8))
print(Int(strtoul(str, nil, 16)))
let dataBLE = String(data: characteristic.value!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
print(dataBLE)

But none of these work. How can I convert from hex to decimal with the value from characteristic.value?

Brian
  • 14,610
  • 7
  • 35
  • 43
jakobdo
  • 1,282
  • 14
  • 20
  • 1
    Of what type is `characteristic.value`? – shallowThought Dec 16 '16 at 20:54
  • Does this post help? It's updated for Swift 3: [Reading a BLE Peripheral Characteristic and checking its value](http://stackoverflow.com/questions/32894363/reading-a-ble-peripheral-characteristic-and-checking-its-value) – leanne Dec 16 '16 at 21:12
  • shallowThought: How can i see the type of value ? – jakobdo Dec 16 '16 at 21:22
  • leanne: I'm not sure how to use the suggested solution. Do i need all the code? – jakobdo Dec 16 '16 at 21:35
  • Have you checked whether this service offers the `org.bluetooth.characteristic.battery_level` property? That's the preferred way to get the battery level of a device, and will return a percentage between 0 and 100. It's unclear what the actual value you're reading is (or what type it is, or what characteristic it comes from). You show a bunch of `print` statements, but don't show what they output. – Rob Napier Dec 16 '16 at 22:09
  • I have this function: func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){ switch characteristic.uuid.uuidString{ case "2A19": print(characteristic.value) default: print("Something") And 2A19 = org.bluetooth.characteristic.battery_level – jakobdo Dec 16 '16 at 22:55
  • It looks like .value = bytes – jakobdo Dec 16 '16 at 23:14

2 Answers2

3

That should work:

let data = characteristic.value
var byte:UInt8 = 0
data.copyBytes(to: &byte, count: 1)

let valueInInt = Int(byte)
print(valueInInt)
Michał Kwiecień
  • 2,734
  • 1
  • 20
  • 23
2

The value for org.bluetooth.characteristic.battery_level (0x2A19) seems to be a single uint8 (UInt8 in Swift). And the result of characteristic.value! is Data, which is a Collection of UInt8, and in your case, it contains only one UInt8 value.

Try this:

print(characteristic.value![0])

But, when you need to use other various characteristics in your app (it's a very common scenario for apps using BLE), the linked article shown in leanne's comment would be very useful.

OOPer
  • 47,149
  • 6
  • 107
  • 142
  • Where can i read more about which type of result is returned from the BLE device? And how do i know that value is Data? In some of my tries, i also saw Optional("0") when i printed .value. I'm new to swift and xcode, so i apologise for all the questions. – jakobdo Dec 17 '16 at 09:25
  • I see, i have to look into this of course: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.battery_level.xml – jakobdo Dec 17 '16 at 09:26
  • @jakobdo, seems you have found one by yourself. _And how do i know that value is Data?_ Check [this](https://developer.apple.com/reference/corebluetooth/cbcharacteristic/1518878-value), the type of the `value` property is of type `Data?`. It can contain various types of data, so you need to convert it to the desired type. Converting to `UInt8` is shown in my answer, converting to many other types with more generic and smarter way is shown in the linked article. And about `Optional("0")`, when you print some data of Optional type -- like `Data?` (aka `Optional`) you get it. Unwrap it. – OOPer Dec 17 '16 at 09:35
  • Thank you so much for all the info. I have coded many different languages before, but i really find swift a little hard to understand. Do you have good sources to learn swift 3 ? – jakobdo Dec 17 '16 at 10:22
  • @jakobdo, I took two and a half years to learn Swift, since the first public beta of Swift. You, at least, should read two Swift books carefully the [Swift book](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/index.html#//apple_ref/doc/uid/TP40014097) and the [Using book](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/index.html#//apple_ref/doc/uid/TP40014216). And you may not want to take two and a half years to learn Swift, Apple's dev forums or this site would be a good help. – OOPer Dec 17 '16 at 10:32
  • Thanks, will look info those 2 right away. And now that i/you got the right "battery level" i jumped into getting this: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.manufacturer_name_string.xml but this is utf8s, how do i extract that info? I don't see a "utf8s" in the protocol from leanne's link / article. – jakobdo Dec 17 '16 at 10:54
  • @jakobdo, the linked article does not work for strings. But Swift String has an initializer taking `Data`. Try `String(data: characteristics.value!, encoding: .utf8)!`. – OOPer Dec 17 '16 at 11:09
  • Nice. I tried that "combo" when i tried to get the UInt8 value, but did not think of using the "String" to getting a string.. DOH. Thanks anyways, think it is time to "close" this thread. I hope i see you around next time i have a question. – jakobdo Dec 17 '16 at 11:28