提取 4 位蓝牙 HEX 数据 [英] Extract 4 bits of Bluetooth HEX Data

查看:29
本文介绍了提取 4 位蓝牙 HEX 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现蓝牙 FTMS(健身机).

I'm trying to implement Bluetooth FTMS(Fitness Machine).

guard let characteristicData = characteristic.value else { return -1 }
let byteArray = [UInt8](characteristicData)
let nsdataStr = NSData.init(data: (characteristic.value)!)

print("pwrFTMS 2ACC Feature  Array:[\(byteArray.count)]\(byteArray) Hex:\(nsdataStr)")

这是从 bleno 服务器返回的内容

Here is what's returned from the bleno server

PwrFTMS 2ACC 特征数组:[8][2, 64, 0, 0, 8, 32, 0, 0] 十六进制:{length = 8, bytes = 0x0240000008200000}

根据规范,返回的数据有 2 个特征,每个特征为 4 个八位字节长.我无法拆分 4 个八位字节,因此我可以将其转换为二进制并获取相关位进行解码.

Based on the specs, the returned data has 2 characteristics, each of them 4 octet long. I'm having trouble getting the 4 octets split so I can get it converted to binary and get the relevant Bits for decoding.

问题的一部分是 swift 会删除前导零.因此,我得到的不是 00 00 64 02,而是 642.我尝试使用以下方法用前导零填充它,但由于它已格式化为字符串,因此我无法将其转换为二进制使用基数:2

Part of the problem is the swift will remove the leading zero. Hence, instead of getting 00 00 64 02, I'm getting 642. I tried the below to pad it with leading zero but since it's formatted to a string, I can't convert it to binary using radix:2

let FTMSFeature = String(format: "%02x", byteArray[3]) + String(format: "%02x", byteArray[2]) + String(format: "%02x", byteArray[1]) + String(format: "%02x", byteArray[0])

我一整天都在思考这个问题,并且通过多个 SO 和 Google 都无济于事.

I've been banging my head on this for an entire day and went thru multiple SO and Google to no avail.

我如何转换:

From - [HEX] 00 00 40 02
To   - [DEC] 16386
To   - [BIN] 0100 0000 0000 0010

然后我可以到达 Bit1 = 1 和 Bit14 = 1

then I can get to Bit1 = 1 and Bit14 = 1

推荐答案

我如何转换:

从 - [HEX] 00 00 40 02
到 - [DEC] 16386
到 - [BIN] 0100 00000000 0010

From - [HEX] 00 00 40 02
To - [DEC] 16386
To - [BIN] 0100 0000 0000 0010

您可以简单地使用 ContiguousBytes 和 UnsafeBytes 方法将您的字节加载为 UInt32.请注意,它将仅使用创建结果类型所需的相同字节数(4 个字节)

You can simply use ContiguousBytes withUnsafeBytes method to load your bytes as UInt32. Note that it will use only the same amount of bytes needed to create the resulting type (4 bytes)

let byteArray: [UInt8] = [2, 64, 0, 0, 8, 32, 0, 0]
let decimal = byteArray.withUnsafeBytes { $0.load(as: UInt32.self) }
decimal  // 16386

要将字节转换为二进制,您只需要填充以保留生成的二进制字符串.请注意,当 32 位无符号整数应为 4 时,您预期的二进制字符串只有 2 个字节:

To convert from bytes to binary you just need to pad to left your resulting binary string. Note that your expected binary string has only 2 bytes when a 32-bit unsigned integer should have 4:

extension FixedWidthInteger {
    var binary: String {
        (0 ..< Self.bitWidth / 8).map {
            let byte = UInt8(truncatingIfNeeded: self >> ($0 * 8))
            let string = String(byte, radix: 2)
            return String(repeating: "0",
                          count: 8 - string.count) + string
        }.reversed().joined(separator: " ")
    }
}

let binary = decimal.binary  // "00000000 00000000 01000000 00000010"

要知道特定位是打开还是关闭,您可以执行以下操作:

To know if a specific bit is on or off you can do as follow:

extension UnsignedInteger {
    func bit<B: BinaryInteger>(at pos: B) -> Bool {
        precondition(0..<B(bitWidth) ~= pos, "invalid bit position")
        return (self & 1 << pos) > 0
    }
}


decimal.bit(at: 0)  // false
decimal.bit(at: 1)  // true
decimal.bit(at: 2)  // false
decimal.bit(at: 3)  // false
decimal.bit(at: 14) // true

如果您需要在特定字节位置获取值,您可以查看此帖子

If you need to get a value at a specific bytes position you can check this post

这篇关于提取 4 位蓝牙 HEX 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆