CoreBluetooth开发简单蓝牙通讯发送十六进制指令

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rigel_xu/article/details/87890641

基于CoreBluetooth与蓝牙4.0设备通讯非常方便,一句话总结就是中心-设备-服务-特征,对应的关键API为CBCentralManager-CBPeripheral-CBService-CBCharacteristic

可以通过LightBlue查看你的蓝牙设备相关信息,也可以发送简单指令。

CBCentralManager scanForPeripherals时需要注意两点:

  1. APP需要后台扫描withServices必须指定要扫描的服务的UUID,不传系统会忽略不执行后台扫描;
  2. 指定服务UUID无法找到设备,可能是芯片不支持在没有连接的情况下扫描服务。如果确实需要就找芯片开发沟通,非必要就扫描所有设备再通过设备名称等过滤连接后再找到服务。

设定特征uuid为:

private let Characteristic_UUID: String = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

一、使用中心对象查找设备

centralManager = CBCentralManager.init(delegate: self, queue: .main)
func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .unknown:
            print("unknown")
        case .resetting:
            print("resetting")
        case .unsupported:
            print("unsupported")
        case .unauthorized:
            print("unauthorized")
        case .poweredOff:
            print("poweredOff")
        case .poweredOn:
            print("ok")
            central.scanForPeripherals(withServices: [], options: nil)
        }
    }

二、连接设备并查找服务

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        self.peripheral = peripheral
        // 根据设备名称来过滤
        if ((peripheral.name != nil) && (peripheral.name?.hasPrefix("XXX"))!) {
            central.connect(peripheral, options: nil)
            central.stopScan();
        }
    }

三、获取指定服务,查询指定特征

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        for service: CBService in peripheral.services! {
            print("设备中的服务有:\(service)")
        }
        //假设外设中只有一个服务
        let service = peripheral.services?.last
        //根据UUID寻找服务中的特征
        peripheral.discoverCharacteristics([CBUUID.init(string: Characteristic_UUID)], for: service!)
    }

四、发现指定特征

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        for characteristic: CBCharacteristic in service.characteristics! {
            print("外设中的特征有:\(characteristic)")
        }
        self.characteristic = service.characteristics?.last
    }

五、向特征发送十六进制指令

此特征必须是约定的可写入特征(是否可写入与设备的通讯协议一般都会定好,也可以通过LightBlue查看),指令通讯一般是十六进制指令,假设指令为打开(0x2601),为方便操作封装一个十六进制字符串转data的方法:

func dataWithHexString(hex: String) -> Data {
        var hex = hex
        var data = Data()
        while(hex.count > 0) {
            let subIndex = hex.index(hex.startIndex, offsetBy: 2)
            let c = String(hex[..<subIndex])
            hex = String(hex[subIndex...])
            var ch: UInt32 = 0
            Scanner(string: c).scanHexInt32(&ch)
            var char = UInt8(ch)
            data.append(&char, count: 1)
        }
        return data
    }

调用此方法:

if peripheral == nil || characteristic == nil {
    print("no peripheral connected")
    return;
}
let data = dataWithHexString(hex: "2601")
peripheral?.writeValue(data, for: characteristic!, type: CBCharacteristicWriteType.withoutResponse)

这里需要注意,一般的写入操作CBCharacteristicWriteType的类型是withResponse需要设备有响应,但是具体设备要看芯片设计,如果发现没有成功尝试使用withoutResponse

写入有响应会回调:

func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        print("写入数据")
}

简单的基于CoreBluetooth发送指令就介绍这些,如果涉及与蓝牙设备大数据传输代码和通讯协议相对较复杂,另外还需要注意发送数据的间隔,因为限于载波大小如果单次数据较大可能会没有响应,间隔参考值:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/rigel_xu/article/details/87890641
今日推荐