提取 4 位蓝牙 HEX 数据

Extract 4 bits of Bluetooth HEX Data

我正在尝试实施蓝牙 FTMS(健身机)。

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 服务器返回的内容

PwrFTMS 2ACC Feature Array:[8][2, 64, 0, 0, 8, 32, 0, 0] Hex:{length = 8, bytes = 0x0240000008200000}

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

部分问题是 swift 将删除前导零。因此,我得到的不是 00 00 64 02,而是 642。我尝试在下面用前导零填充它,但由于它被格式化为字符串,我无法使用 radix:2[ 将其转换为二进制文件=16=]

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

我一整天都在为此苦苦思索,经历了多次 SO 和 Google 无济于事。

如何转换:

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

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

How Can I convert:

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

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

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

要从字节转换为二进制,您只需填充以留下生成的二进制字符串。请注意,当 32 位无符号整数应为 4:

时,您预期的二进制字符串只有 2 个字节
extension FixedWidthInteger {
    var binary: String {
        (0 ..< Self.bitWidth / 8).map {
            let byte = UInt8(truncatingIfNeeded: self >> ([=11=] * 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"

要知道某个位是打开还是关闭,您可以按照以下步骤操作:

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

如果您需要获取特定字节位置的值,您可以检查这个post