2016-08-18 7 views
6

Я получаю данные через BLE, и я хочу, чтобы преобразовать их в десятичные значения, однако я подозреваю, что я что-то неправильно, потому что диапазон значений оказывается невернымSwift - преобразование данных в десятичные значения

от BLE я получаю characteristic.value

24ffa400 6d08fcff fffffbff 0d001500 5eff

который строится Maily ИДУ значений.

Когда я пытаюсь преобразовать первые два байта, в этом примере 24ff, который является значением оси X акселерометра, я получаю значение от диапазона 1000-30000 (я ввел некоторое динамическое движение к датчику, чтобы увидеть, как изменяется значение).

Это должно быть неправильным, так как документы говорят, что акселерометр масштаб ±16G Есть два более важная информация:

последовательность байтов в рамке выглядит следующим образом: [LSB, MSB]

значения 16bit и использует двоичное дополнение

это как преобразовать данные в десятичное значение:

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

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

    let u16 = UnsafePointer<Int16>(bytes).memory 
    return([twosComplement(u16)]) 
} 

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

Я полагаю, что я должен получать значения от диапазона < -16: 16> вместо огромных значений, о которых я упоминал выше, что не так с моим подходом?

Заранее спасибо

EDIT: Missing реализация метода

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 
} 

ответ

2

Учитывая некоторые NSData,

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

вы можете получить первые два байта в [LSB, MSB] порядка как подписанное 16-битовое целое число с

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

Это число в диапазоне -32768 .. 32767 и должна быть расширена до диапазоне с плавающей точкой в ​​соответствии со спецификацией устройства, например:

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

scaled является Double и может быть преобразован в строку с String(scaled), или с использованием NSNumberFormatter.

+0

Так что я могу опустить функцию двухкомпонента вправо? Также следует обратить внимание на порядок LSB и MSB? теперь я STH нравится этот класс 'Func getAccelerometerData (значение: NSData) -> Двойной { пусть dataFromSensor = dataToSignedBytes8 (значение) пусть байты: [INT8] = [dataFromSensor [0], dataFromSensor [1]] let i16 = UnsafePointer (байты) .memory return (16.0 * Double (i16)/32768.0) ' и, кажется, работает, не могли бы вы проверить код? – DCDC

+0

@DCDC: Я не знаю, что делает ваш dataToSignedBytes8, что кажется ненужным, вы можете напрямую обращаться к данным, как я показал. В противном случае это выглядит правильно. Предполагается, что 'Int16' использует представление в виде маленького конца, что относится ко всем текущим устройствам iOS. –

+0

@DCDC: Я обновил код, чтобы сделать его безопасным байтом! –

 Смежные вопросы

  • Нет связанных вопросов^_^