如何在ios swift中为BLE设备写入characteristc值

Bha*_*ker 5 characteristics ios core-bluetooth cbperipheral swift

我正在开发 iOS BLE 应用程序来为手机充电。我做了所有正确的事情来发现特征。首先扫描外围设备并连接到它。发现具有通知和无响应写入属性的服务(FFB0)和特征(FFB1,FFB2)。

\n\n

我找到了客户端特征配置描述符。我想向 PCB 发送命令以解锁充电 我想将值写入 FFB2 特性,但外设没有响应。这是我的代码。

\n\n

我已经搜索了与此相关的所有内容,但没有找到任何解决方案如果有人提供此问题的解决方案,这将对我有所帮助。

\n\n

这是客户提供的文件:

\n\n

每个PCB上都有一个BLE4.0蓝牙模块,每个蓝牙模块都有一个单独的12字节长度的地址码,PCB数据通道,Service UUID为OxFFBO,包括两个特征值,分别是OxFFBI和OxFFB2,通信长度数据为1--20字节。\nOxFFB1为APP数据下载通道。OxFBB2为蓝牙上传数据通道。

\n\n

开机进入空闲模式,空闲模式下两个灯会闪烁。它会发送一个ID码(一个字节)到手机,手机中的APP会获取该ID码(一个字节)。\nID码可以通过手机设置来设置。是指通过ID码发送相应的解锁指令。

\n\n

解锁指令为0x55,0xe1,(ID0+1),时间,解锁指令说明如下:

\n\n

ID0为ID码,“time”为用户解锁时间(5-120分钟),\n请注意是二进制到十六进制的转换,\ntime==05表示5分钟,\ntime==6表示6分钟,\n时间==A表示10分钟,以此类推。\n如果PCB的ID0为0xff,\n解锁PCB 60分钟为:0x55,0xe1,0x00,0x3c;\n如果PCB的ID0为0x05 ,\n解锁 PCB 10 分钟为:0x55、0xe1、0x06、0x0a

\n\n

当PCB上的MCU收到解锁指令时,将开始打开输出并计时。\n计时时间到后系统再次进入空闲模式。\n在空闲模式下,长按该键进入关机休眠时间模式。

\n\n

uart 波特率设置为 9600。\nAPP 向 MCU 发送的查询指令为 0x55 0x01\nMCU 回复 APP 的信息格式为:0x55,0x02,bat_level,xH,XL(xH XL 代表当前电池电压值,\nxH - 代表高8位,XL---代表低8位)

\n\n
import CoreBluetooth\n\nlet batteryServiceCBUUID = CBUUID(string: "FFB0")\nlet batteryServiceRequestCBUUID = CBUUID(string: "FFB1")\nlet batteryServiceRequestCBUUID2 = CBUUID(string: "FFB2")\n\n class ChargingViewController: UIViewController , CBPeripheralDelegate \n ,CBCentralManagerDelegate {    \n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)  \n }\n func centralManagerDidUpdateState(_ central: CBCentralManager) {\n\n    switch central.state {\n    case .unknown:\n        print("central.state is .unknown")\n    case .resetting:\n        print("central.state is .resetting")\n    case .unsupported:\n        print("central.state is .unsupported")\n    case .unauthorised:\n        print("central.state is .unauthorised")\n    case .poweredOff:\n        print("central.state is .poweredOff")\n    case .poweredOn:\n\n\n        centralManager.scanForPeripherals(withServices: [batteryServiceCBUUID])\n\n        print("central.state is .poweredOn")\n    @unknown default:\n        fatalError()\n    }\n\n    print("state: \\(central.state)")\n\n }\n func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, \n advertisementData: [String : Any], rssi RSSI: NSNumber) {\n\n    print(peripheral)\n    batteryServicePeripheral = peripheral\n    batteryServicePeripheral.delegate = self\n    centralManager.stopScan()\n    centralManager.connect(batteryServicePeripheral)\n\n }\n  func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {\n\n    print("Connected=======>\\(String(describing: batteryServicePeripheral))")\n    batteryServicePeripheral.delegate = self\n    batteryServicePeripheral.discoverServices([batteryServiceCBUUID])\n\n}\n\nfunc centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, \n error: Error?) {\n\n    print("Fail To Connect=======>\\(String(describing: error))")\n}\n\n\nfunc centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: \nCBPeripheral, error: Error?) {\n\n    if error == nil {\n\n        print("Disconnected========>\\(peripheral)")\n    }else {\n\n        print("Disconnected========>\\(String(describing: error))")\n    }\n }\n// MARK: - \xef\xa3\xbf CBPeripheral Delegate Methods\n\nfunc peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {\n\n    guard let services = peripheral.services else { return }\n\n    for service in services {\n\n        print("SPAKA:PERIPHERALSERVICES============>\\(service)")\n        peripheral.discoverCharacteristics(nil, for: service)\n\n    }\n\n}\n\nfunc peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {\n\n    if let characteristics = service.characteristics {\n        //else { return }\n\n        for characteristic in characteristics {\n\n            print(characteristic)\n\n\n            if characteristic.uuid == batteryServiceCBUUID {\n\n               peripheral.setNotifyValue(true, for: characteristic)\n\n            }\n\n            if characteristic.uuid == batteryServiceRequestCBUUID2 {\n\n                batteryCharacteristics = characteristic\n\n\n                let str1 = "55e100"\n                let data = String(format: "%@%@",str1,hexTimeForChar)\n\n                guard let valueString = data.data(using: String.Encoding.utf8)  else \n    {return}\n\n\n\n                peripheral.writeValue(valueString, for: characteristic , type: \n        CBCharacteristicWriteType.withoutResponse)\n                print("Value String===>\\(valueString.debugDescription)")\n                peripheral.setNotifyValue(true, for: characteristic)\n\n            }\n\n        }\n    }\n    peripheral.discoverDescriptors(for: batteryCharacteristics)\n}\n\n\nfunc peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {\n\n    if error == nil {\n        print("Message sent=======>\\(String(describing: characteristic.value))")\n    }else{\n\n        print("Message Not sent=======>\\(String(describing: error))")\n    }\n\n\n\n\n}\n\nfunc peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: \nCBCharacteristic, error: Error?) {\n\n    if error == nil {\n        print("SPAKA : IS NOTIFYING UPDATED STATE ======>\\(characteristic.isNotifying)")\n        print("SPAKA : UPDATED DESCRIPTION ======>\\(String(describing: \n characteristic.description))")\n\n\n    }else{\n        print("SPAKA : ERRORUPDATEDNOTIFICATION\\(String(describing: error))")\n    }\n\n\n}\n\n\nfunc peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {\n\n    print("SPAKA: UPDATED VALUE RECEIVED========>\\(String(describing: characteristic.value))")\n    print("characteristic UUID: \\(characteristic.uuid), value: \\(characteristic.value)")\n\n    guard let str = characteristic.value else { return  }\n\n    if let string = String(bytes: str, encoding: .utf8) {\n        print("SPAKA==========>:::\\(string)")\n    } else {\n        print("not a valid UTF-8 sequence")\n    }\n\n\n\n}\n\nfunc peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {\n\n    guard let desc = batteryCharacteristics.descriptors else { return }\n\n\n    for des in desc {\n\n        print("BEGIN:SPAKA DESCRIPTOR========>\\(des)")\n        discoveredDescriptor = des\n\n        print("Descriptor Present Value and uuid: \\(des.uuid), value: \\(String(describing: des.value))")\n        peripheral.readValue(for: discoveredDescriptor)\n\n\n    }\n\n\n}\n\nfunc peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {\n    if let error = error {\n        print("Failed\xe2\x80\xa6 error: \\(error)")\n        return\n    }\n\n    print("Descriptor Write Value uuid: \\(descriptor.uuid), value: \\(String(describing: descriptor.value))")\n}\n\nfunc peripheral(_ peripheral: CBPeripheral, didUpdateValueFor descriptor: CBDescriptor, error: Error?) {\n\n    if let error = error {\n        print("Failed\xe2\x80\xa6 error: \\(error)")\n        return\n    }\n\n    print("Descriptor Updated Value uuid: \\(descriptor.uuid), value: \\(String(describing: descriptor.value))")\n\n}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Cod*_*odo 7

有关 PDB 的信息有些难以破译,但包含了很好的信息。听起来好像 PCB 包含蓝牙转 UART 模块。一种特性是向PCB发送数据,一种特性是从PCB接收数据。

我还是不明白需要发送到PCB的命令。如果您有权访问 Android 代码,那么您可以在那里找到答案。

以下是可能的最小代码:

let batteryServiceUUID = CBUUID(string: "FFB0")
let rxCharacteristicUUID = CBUUID(string: "FFB1")
let txCharacteristicUUID = CBUUID(string: "FFB2")

var centralManager: CBCentralManager!
var batteryPeripheral: CBPeripheral? = nil
var batteryService: CBService? = nil
var txCharacteristic: CBCharacteristic? = nil
var rxCharacteristic: CBCharacteristic? = nil

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    if central.state == .poweredOn {
        centralManager.scanForPeripherals(withServices: [batteryServiceUUID])
    }
}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    batteryPeripheral = peripheral
    batteryPeripheral!.delegate = self
    centralManager.stopScan()
    centralManager.connect(batteryPeripheral!)
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    batteryPeripheral!.discoverServices([batteryServiceUUID])
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    peripheral.discoverCharacteristics(nil, for: peripheral.services![0])
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    for characteristic in service.characteristics! {
        if characteristic.uuid == rxCharacteristicUUID {
            rxCharacteristic = characteristic
            peripheral.setNotifyValue(true, for: rxCharacteristic!)
        } else if (characteristic.uuid == txCharacteristicUUID) {
            txCharacteristic = characteristic
        }
    }
    sendInitialCommand()
}

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    if let value = characteristic.value {
        print("Data received")
        print(value as NSData)
    }
}

func sendInitialCommand() {
    let cmdBytes: [UInt8] = [0x55, 0xe1, 0x00, 0x0a]
    let cmd = Data(cmdBytes)
    batteryPeripheral!.writeValue(cmd, for: txCharacteristic!, type: .withoutResponse)
}
Run Code Online (Sandbox Code Playgroud)