我正在用Swift写一段代码,从BLE设备(欧姆龙BP 7000)获取数据。我能够与它配对,并获得其他服务和读取数据。但是我无法得到血压的数据,在didUpdateValueFor characteristic:
。CoreBluetooth的其他代表已经使用,并按预期工作。只是当谈到读/写数据到当前时间和读数据从血压特性,我得到的问题。如果任何人可以张贴一些建议,我应该如何进行将是有帮助的。
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
switch characteristic.uuid {
case batteryLevelCBUUID:
print("Battery level: \(characteristic.value![0])")
let valueBattery = characteristic.value?[0]
batteryLabel.text = "Battery Level =" + " " + String(describing: characteristic.value! [0]) + "%"
centerView.isHidden = false
case currentTimeCBUUID:
peripheral.readValue(for: characteristic)
let currentDate = Date()
// Write the date and time to the characteristic
writeCurrentTime(to: characteristic, in: peripheral)
// print("\(characteristic.value as Any) gives Current Time String ")
if let dateTime = extractDateTime(from: characteristic) {
print("Date and Time:", dateTime)
} else {
print("Unable to extract date and time from the characteristic.")
}
case bloodPressureMeasurementCBUUID:
decodeBloodPressureMeasurementData(from: characteristic)
print("\(characteristic.value as Any) gives 2A35 ")
default:
print("")
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
if let error = error {
// Handle write error
print("Error writing value: \(error.localizedDescription)")
} else {
// Handle successful write
print("Value written successfully")
// Check if the characteristic supports notifications
if characteristic.properties.contains(.notify) {
peripheral.setNotifyValue(true, for: characteristic)
}
}
}
func writeCurrentTime(to characteristic: CBCharacteristic, in peripheral: CBPeripheral) {
// Get the current date and time
let currentDate = Date()
let calendar = Calendar.current
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .weekday, .nanosecond], from: currentDate)
// Create the value to be written
var value = Data()
value.append(Data(bytes: &components.year!, count: 2)) // Year (2 bytes)
value.append(Data(bytes: "", count: 0))
value.append(UInt8(components.month!)) // Month (1 byte)
value.append(UInt8(components.day!)) // Day (1 byte)
value.append(UInt8(components.hour!)) // Hours (1 byte)
value.append(UInt8(components.minute!)) // Minutes (1 byte)
value.append(UInt8(components.second!)) // Seconds (1 byte)
value.append(UInt8(components.weekday!)) // Day of Week (1 byte)
value.append(contentsOf: components.nanosecond!.bytes(2)) // Fractions of a second (2 bytes)
// Write the value to the Current Time characteristic
peripheral.writeValue(value, for: characteristic, type: .withResponse)
}
func decodeBloodPressureMeasurementData(from characteristic: CBCharacteristic) {
guard let data = characteristic.value else {
print("No data available for decoding.")
return
}
let flags = data[0] // Flags byte
let unitFlags = (flags & 0b00000001) // Bit 0 indicates the unit of blood pressure values
let timestampFlags = (flags & 0b00000010) // Bit 1 indicates the presence of timestamp
// Decode systolic, diastolic, and mean arterial pressure values
let systolicPressure = (data[1] + (data[2] << 8))
let diastolicPressure = (data[3] + (data[4] << 8))
let meanArterialPressure = (data[5] + (data[6] << 8))
// Decode pulse rate value
let pulseRate = (data[7] + (data[8] << 8))
// Decode unit of blood pressure values
let unit: String = (unitFlags != 0) ? "kPa" : "mmHg"
// Process and use the decoded values as needed
print("Systolic Pressure: \(systolicPressure) \(unit)")
print("Diastolic Pressure: \(diastolicPressure) \(unit)")
print("Mean Arterial Pressure: \(meanArterialPressure) \(unit)")
print("Pulse Rate: \(pulseRate) bpm")
}
1条答案
按热度按时间mbskvtky1#
我假设您的当前时间是Current Time Service的一部分。错误代码128(0x 80)表示“数据字段被忽略”。因此,您发送的是设备不支持的字段,或者发送的内容超出了范围。文档还解释了所有的值都是little-endian。
规范指出,当前时间可以选择写入(有响应),不允许在没有响应的情况下写入。所以你写回应是正确的。由于您得到的是0x 80而不是一般的写入失败,因此我将假设该特性在此设备上是可写的。
现在,请参阅GSS v9的第3.62节,了解有关当前时间特性的详细信息。结构为10个八位字节,精确时间256(9个八位字节),后面跟着调整原因(1个八位字节)。
现在,转到定义精确时间256的第3.90节。它是一个Day Date Time结构(3.71节),后面跟着Factions 256 uint 8。
你懂的一步一步地通过规范来构建格式。不要猜测。永远不要认为这是显而易见的。按照规范操作。我将跳过一些步骤并组装整个格式:
为了方便起见,我经常在FixedWidthIntegers上使用这个扩展:
蓝牙的工作日与Foundation的不同:
有了这些,我相信这将是正确的包:
所以你在解码血压。当它们是medfloat 16时,看起来像是将它们当作整数来对待,而忽略了文档中的比例因子。从GSS的2.3节开始,它解释了如何解释一般的数值,特别是2.3.2节中关于标量的数值。然后参见第3.31节,详细解释了血压测量特性。您可能会发现Personal Health Devices Transcoding白色很有帮助。“medfloat 16”通常被称为SFLOAT,因此您可以阅读白皮书的第2.2.2节以了解详细信息和示例编码。
如果你在阅读以上内容后有关于血压的问题,可以针对你的具体问题打开一个新的问题。输入是什么?输出应该是什么?您得到的是什么输出?