DCDC DCDC - 2 years ago 194
iOS Question

Swift - converting data to decimal values

I'm getting data via BLE and I want to convert them into decimal values, however I suspect I do something wrong because value range appears to be incorrect

from BLE I receive


24ffa400 6d08fcff fffffbff 0d001500 5eff

which is constructed maily of IMU values.

when I try to convert the first two bytes, in this example
which is accelerometer X axis value, I get a value from range 1000-30000 (I introduced some dynamic movement to the sensor to see how the value is changing).

This must be wrong since docs say that accelerometer scale is

There are two more important information:

sequence of bytes in frame goes as follows: [LSB, MSB]

values are 16bit and utilizes two's complement

this is how I convert data into decimal value:

class func getAccelerometerData(value: NSData) -> [String] {

let dataFromSensor = dataToSignedBytes8(value)
let bytes:[Int8] = [dataFromSensor[1], dataFromSensor[0]]

let u16 = UnsafePointer<Int16>(bytes).memory

class func twosComplement(num:Int16) -> String {
var numm:UInt16 = 0
if num < 0 {
let a = Int(UInt16.max) + Int(num) + 1
numm = UInt16(a)
else { return String(num, radix:10) }
return String(numm, radix:10)

I suppose I should obtain values from range <-16:16> instead of huge values I mentioned above, what is wrong with my approach?

Thanks in advance

Missing method implementation

class func dataToSignedBytes8(value : NSData) -> [Int8] {
let count = value.length
var array = [Int8](count: count, repeatedValue: 0)
value.getBytes(&array, length:count * sizeof(Int8))
return array

Answer Source

Given some NSData,

let value = NSData(bytes: [0x24, 0xff, 0xa4, 0x00] as [UInt8], length: 4)
print(value) // <24ffa400>

you can retrieve the first two bytes in [LSB, MSB] order as a signed 16-bit integer with

let i16 = Int16(littleEndian: UnsafePointer<Int16>(data.bytes).memory)
print(i16) // -220

This number is in the range -32768 .. 32767 and must be scaled to the floating point range as per the specification of the device, for example:

let scaled = 16.0 * Double(i16)/32768.0
print(scaled) // -0.107421875

scaled is a Double and can be converted to a string with String(scaled), or using a NSNumberFormatter.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download