提取 4 位蓝牙 HEX 数据 [英] Extract 4 bits of Bluetooth HEX Data
问题描述
我正在尝试实现蓝牙 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屋!