2016-08-18 26 views
6

Tôi nhận được dữ liệu thông qua BLE và tôi muốn chuyển đổi chúng thành các giá trị thập phân, tuy nhiên tôi nghi ngờ tôi làm điều gì sai bởi vì phạm vi giá trị dường như là không chính xácSwift - chuyển đổi dữ liệu với các giá trị thập phân

từ BLE tôi nhận characteristic.value

24ffa400 6d08fcff fffffbff 0d001500 5eff

được xây dựng bằng thư giá trị IMU.

khi tôi cố chuyển đổi hai byte đầu tiên, trong ví dụ này là 24ff là giá trị trục X gia tốc, tôi nhận được giá trị từ khoảng 1000-30000 (tôi đã giới thiệu một số chuyển động động cho cảm biến để xem giá trị đang thay đổi như thế nào).

này phải là sai lầm kể từ khi tài liệu nói rằng quy mô gia tốc là ±16G Có hai thông tin quan trọng hơn:

chuỗi các byte trong khung diễn ra như sau: [LSB, MSB]

giá trị là 16bit và sử dụng hai của bổ sung

đây là cách tôi chuyển đổi dữ liệu vào giá trị thập phân:

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

Tôi cho rằng tôi nên lấy giá trị từ phạm vi < -16: 16> thay vì giá trị lớn mà tôi đã đề cập ở trên, có gì sai với cách tiếp cận của tôi?

Cảm ơn trước

EDIT: Thiếu phương pháp thực hiện

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 
} 

Trả lời

2

Với một số NSData,

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

bạn có thể lấy hai byte đầu tiên trong [LSB, MSB] trật tự dưới dạng số nguyên 16 bit có chữ ký với

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

Con số này nằm trong khoảng -32768 .. 32767 và phải được thu nhỏ để phạm vi điểm nổi theo đặc điểm kỹ thuật của thiết bị, ví dụ:

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

scaled là một Double và có thể được chuyển đổi thành một chuỗi với String(scaled) hoặc sử dụng NSNumberFormatter.

+0

Vì vậy, tôi có thể bỏ qua hai chức năng Thực hiện đúng? Tôi cũng nên chú ý đến LSB và MSB? Bây giờ tôi đã sth thích này lớp 'func getAccelerometerData (giá trị: NSData) -> đúp { hãy dataFromSensor = dataToSignedBytes8 (giá trị) hãy byte: [int8] = [dataFromSensor [0], dataFromSensor [1]] hãy để i16 = UnsafePointer (byte) .memory trả lại (16.0 * Tăng gấp đôi (i16)/32768.0) ' và có vẻ như đang hoạt động, bạn có thể xác thực mã không? – DCDC

+0

@DCDC: Tôi không biết dataToSignedBytes8 của bạn làm gì, điều đó có vẻ không cần thiết, bạn có thể truy cập dữ liệu trực tiếp như tôi đã trình bày. Nếu không, nó có vẻ chính xác. Nó giả định rằng 'Int16' sử dụng một biểu diễn bộ nhớ nhỏ, đó là trường hợp cho tất cả các thiết bị iOS hiện tại. –

+0

@DCDC: Tôi đã cập nhật mã để làm cho trật tự byte an toàn! –

Các vấn đề liên quan