从字节获取字符串(Corebluetooth,Swift)



只是为了看看是否有人可以帮助我解决一些BLE问题。我正在尝试制作一个从我的划船机获取东西的应用程序,但我无法弄清楚如何将字节变成字符串?这很难解释,但这是我的VC:

import UIKit
import CoreBluetooth

let rowerServiceCBUUID = CBUUID(string: "CE060000-43E5-11E4-916C-0800200C9A66")
let characteristic1CBUUID = CBUUID(string: "CE060031-43E5-11E4-916C-0800200C9A66")
let characteristic2CBUUID = CBUUID(string: "2AD1")
class HRMViewController: UIViewController {
@IBOutlet weak var heartRateLabel: UILabel!
@IBOutlet weak var bodySensorLocationLabel: UILabel!
var centralManager: CBCentralManager!
var pmPeripheral: CBPeripheral!
var wattValue: Int!
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil)
// Make the digits monospaces to avoid shifting when the numbers change
heartRateLabel.font = UIFont.monospacedDigitSystemFont(ofSize: heartRateLabel.font!.pointSize, weight: .regular)
}
func onHeartRateReceived(_ heartRate: Int) {
heartRateLabel.text = String(heartRate)
print("BPM: (heartRate)")
}
}
extension HRMViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
print("Central state update")
if central.state != .poweredOn {
print("Central is not powered on")
} else {
print("Central scanning for", rowerServiceCBUUID);
centralManager.scanForPeripherals(withServices: [rowerServiceCBUUID],
options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print(peripheral)
peripheral.delegate = self
pmPeripheral = peripheral
pmPeripheral.delegate = self
centralManager.stopScan()
centralManager.connect(pmPeripheral!)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("Connected!")
pmPeripheral.discoverServices(nil)
}
}
extension HRMViewController: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
print(service)
print(service.characteristics ?? "characteristics are nil")
peripheral.discoverCharacteristics(nil, for: service)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?){
guard let characteristics = service.characteristics else { return }
for characteristic in characteristics {
print(characteristic)
if characteristic.properties.contains(.read) {
print("(characteristic.uuid): properties contains .read")
}
if characteristic.properties.contains(.notify) {
print("(characteristic.uuid): properties contains .notify")
}
peripheral.readValue(for: characteristic)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic,
error: Error?) {
switch characteristic.uuid {
case characteristic1CBUUID:
let bodySensorLocation = bodyLocation(from: characteristic)
bodySensorLocationLabel.text = bodySensorLocation
default:
print("Unhandled Characteristic UUID: (characteristic.uuid)")
}
}
private func bodyLocation(from characteristic: CBCharacteristic) -> String {
guard let characteristicData = characteristic.value,
let byte = characteristicData.first else { return "Error" }
switch byte {
case 0: return "0"
case 1: return "1"
case 2: return "2"
case 3: return "3"
case 4: return "4"
case 5: return "5"
case 6: return "6"
case 7: return "7"
case 8: return "8"
default:
return "Reserved for future use"
}
}
}

具体来说,最底部的文本是我卡住的地方,每个 Corebluetooth 指南都将数字交换为文本,但我的是一个字符串数组(如下所示:https://youtu.be/rXDCBVQXdbg(

我被困住了,不知道该何去何从。任何帮助将不胜感激!

从您使用的 UUID 中,您当前关注的是 Concept2 性能监视器蓝牙智能通信接口定义第 11 页上记录的C2 划船常规状态特征

文档说消息将由 19 个字节组成:

  • 字节 0:经过时间 Lo(0.01 秒 lsb(
  • 字节 1:经过时间中间
  • 字节 2:经过时间高
  • 字节 3:距离 Lo (0.1 m lsb(
  • 字节 4:距离中
  • 字节 5:距离高
  • 字节 6:锻炼类型(枚举(

以 3 个字节存储的经过时间:字节 0 是最低有效字节 (LSB(,其次是中字节和高字节。单位是0.01s。所以要得到秒,它必须除以 100。

距离的存储方式类似。单位为0.1m。

锻炼类型在字节 6 中作为枚举给出。因此不包含文本。只是一个数字代码。

要对其进行解码,请使用如下所示的代码。该函数onRowingGeneralStatusUpdate(for:)替换您命名混乱的函数bodyLocation(from:)

func onRowingGeneralStatusUpdate(characteristic: CBCharacteristic) {
guard let data = characteristic.value else { return }
// elapsed time in sec
let elapsedTime: Double = Double(Int(data[0]) + 256 * Int(data[1]) + 65536 * Int(data[2])) / 100.0
// distance in m
let distance: Double = Double(Int(data[3]) + 256 * Int(data[4]) + 65536 * Int(data[5])) / 10.0
let workout: String =  workoutType(for: data[6])
}
func workoutType(for code: UInt8) -> String {
switch code {
case 0:
return "Just row, no splits"
case 1:
return "Just row, splits"
case 2:
return "Fixed dist, no splits"
case 3:
return "Fixed dist, splits"
case 4:
return "Fixed time, no splits"
case 5:
return "Fixed time, splits"
case 6:
return "Fixed time, interval"
case 7:
return "Fixed dist, interval"
case 8:
return "Variable, interval"
case 9:
return "Variable, undef rest, interval"
case 10:
return "Fixed, calorie"
case 11:
return "Fixed, watt-minutes"
case 12:
return "Fixed cals, interval"
default:
return ""
}
}

最新更新