从字节获取字符串(Corebluetooth,Swift) [英] Getting a String from a byte (Corebluetooth, Swift)

查看:96
本文介绍了从字节获取字符串(Corebluetooth,Swift)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只需执行此操作即可查看是否有人可以帮助我解决一些BLE问题.我正在尝试制作一个从划船机上获取东西的应用程序,但我不知道如何将字节转换成字符串?很难解释,但这是我的VC:

Just making this to see if someone could help me with some BLE problems. I'm trying to make an app which gets the stuff from my rowing machine but I can't figure out how to turn bytes into like a string? Its hard to explain but here's my 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 )

Specifically the bottom most text is where I'm stuck, every Corebluetooth guide swaps numbers into text but mine is a string array (As shown here: https://youtu.be/rXDCBVQXdbg)

我被困住了,不知道从这里去哪里.任何帮助,将不胜感激!

I'm stuck and don't know where to go from here. Any help with this would be appreciated!

推荐答案

目前,您正在使用的UUID集中在 C2赛艇常规状态特征上,该特征记录在第11页上. Concept2性能监视器蓝牙智能通信接口定义.

From the UUIDs you're using, you're currently focusing on the C2 rowing general status characteristic documented on page 11 of the Concept2 Performance Monitor Bluetooth Smart Communications Interface Definition.

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

The documentation says that the message will consists of 19 bytes:

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

经过的时间以3个字节存储:字节0是最低有效字节(LSB),其后是中字节和高字节.单位为0.01s.因此,要获得秒数,必须将其除以100.

The elapsed time in stored in 3 bytes: byte 0 is the least significant byte (LSB), followed by the medium and the high byte. And the unit is 0.01s. So to get seconds, it must be divided by 100.

相似地存储距离.单位是0.1m.

Distance is stored similarly. The unit is 0.1m.

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

The workout type is given in byte 6 as an enumeration. So text is not contained. Just a numeric code.

要对其进行解码,请使用以下代码.函数 onRowingGeneralStatusUpdate(for:)替换了您混乱命名的函数 bodyLocation(from:):

To decode it, use code like below. The function onRowingGeneralStatusUpdate(for:) replaces your confusingly named function 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 ""
    }
}

这篇关于从字节获取字符串(Corebluetooth,Swift)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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