简体   繁体   English

从 Swift 写入 BLE 外设

[英]Writing to BLE peripheral from Swift

I am building an iOS Swift app that connects to a BLE device (Redbear Labs Duo) .我正在构建一个连接到BLE 设备 (Redbear Labs Duo)的 iOS Swift 应用程序。

What works?什么工作?

  1. I am able to initiate a scan for devices我能够启动设备扫描
  2. Connect to the device连接到设备
  3. Collect services and characteristics of the BLE device - all good收集 BLE 设备的服务和特性 - 一切都很好

Where is the problem?问题出在哪儿?

  1. The BLE device (Redbear Labs Duo) also has a Wifi controller onboard and is capable of scanning for available networks. BLE 设备(Redbear Labs Duo)还具有板载 Wifi 控制器,能够扫描可用网络。 The documentation states that to scan for Wifi one must 该文件指出,要扫描 Wifi 必须
    • connect to the primary service with UUID 3EC61400-89CD-49C3-A0D9-7A85669E901E使用 UUID 3EC61400-89CD-49C3-A0D9-7A85669E901E 连接到主要服务
    • find the command characteristic with UUID 3EC61401-89CD-49C3-A0D9-7A85669E901E找到 UUID 3EC61401-89CD-49C3-A0D9-7A85669E901E 的命令特征
    • send a 2 byte command [0x20, 0xA0] to the command characteristic向命令特性发送一个 2 字节的命令 [0x20, 0xA0]
    • also set a 1 byte status indicator 0xB1 to the scan characteristic with UUID 3EC61402-89CD-49C3-A0D9-7A85669E901E还将 1 字节状态指示符 0xB1 设置为 UUID 3EC61402-89CD-49C3-A0D9-7A85669E901E 的扫描特征

My code to do the above steps is as below..我执行上述步骤的代码如下..

func scanWifi() {
    print("[DEBUG] - Scanning for Wifi")

    let command:[UInt8] = [0x02, 0xA0]
    let commandData = NSData(bytes: command, length: command.count)
    BLE.sharedInstance.write(toCharacteristic: BLE.sharedInstance.RBL_CHAR_CMD_UUID, data: commandData, withType: .withResponse)

    let state:[UInt8] = [0xB1]
    let stateData = NSData(bytes: state, length: state.count)
    BLE.sharedInstance.write(toCharacteristic: BLE.sharedInstance.RBL_CHAR_SCN_UUID, data: stateData, withType: .withResponse)

    BLE.sharedInstance.read(fromCharacteristic: BLE.sharedInstance.RBL_CHAR_SCN_UUID)
}

Everything works... but... after writing the above data to the peripheral I was expecting the below method to get called - it never did.. what am I doing wrong?一切正常......但是......在将上述数据写入外围设备后,我期待下面的方法被调用 - 它从来没有......我做错了什么?

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        if error != nil {

            print("[ERROR] Error updating value. \(error!.localizedDescription)")
            return
        }

        if characteristic.uuid.uuidString == RBL_CHAR_CMD_UUID {

            self.delegate?.bleDidReceiveData(data: characteristic.value as NSData?)
        }
    }

Update:更新:

I set a bunch of debug statements and got the following output - from the below it is apparent that我设置了一堆调试语句并得到以下输出 - 从下面很明显

  1. I am able to identify and connect to the right device and characteristics我能够识别并连接到正确的设备和特征
  2. I am able to set the notification value appropriately我能够适当地设置通知值

[DEBUG] Connecting to peripheral: 547BC3C9-4823-431C-B888-A8F3E8C699F5 [DEBUG] 连接外设:547BC3C9-4823-431C-B888-A8F3E8C699F5
[DEBUG] Connected to peripheral 547BC3C9-4823-431C-B888-A8F3E8C699F5 [DEBUG] 接外设547BC3C9-4823-431C-B888-A8F3E8C699F5
[DEBUG] Did connect to peripheral [DEBUG] 是否连接到外设
[DEBUG] Found service: 3EC61400-89CD-49C3-A0D9-7A85669E901E for peripheral: 547BC3C9-4823-431C-B888-A8F3E8C699F5 [DEBUG] 发现服务:3EC61400-89CD-49C3-A0D9-7A85669E901E for外设:547BC3C9-4823-431C-B888-A8F3E8C699F5
[DEBUG] Found characteristic: 3EC61401-89CD-49C3-A0D9-7A85669E901E for peripheral: 547BC3C9-4823-431C-B888-A8F3E8C699F5 [DEBUG] 发现特性:3EC61401-89CD-49C3-A0D9-7A85669E901E for外设:547BC3C9-4823-431C-B888-A8F3E8C699F5
[DEBUG] Found characteristic: 3EC61402-89CD-49C3-A0D9-7A85669E901E for peripheral: 547BC3C9-4823-431C-B888-A8F3E8C699F5 [DEBUG] 发现特性:3EC61402-89CD-49C3-A0D9-7A85669E901E for外设:547BC3C9-4823-431C-B888-A8F3E8C699F5
("3EC61402-89CD-49C3-A0D9-7A85669E901E", ) ("3EC61402-89CD-49C3-A0D9-7A85669E901E", )
("3EC61401-89CD-49C3-A0D9-7A85669E901E", ) ("3EC61401-89CD-49C3-A0D9-7A85669E901E", )
[DEBUG] didUpdateNotification state for characteristic CBCharacteristic: 0x1702a6c60, UUID = 3EC61401-89CD-49C3-A0D9-7A85669E901E, properties = 0x14, value = (null), notifying = YES on peripheral: CBPeripheral: 0x1740fba80, identifier = 547BC3C9-4823-431C-B888-A8F3E8C699F5, name = Duo-ZKBY, state = connected [DEBUG] 特性 CBCharacteristic 的 didUpdateNotification 状态:0x1702a6c60,UUID = 3EC61401-89CD-49C3-A0D9-7A85669E901E,属性 = 0x14,值 =(空),通知 = YES,外围设备标识符:CBPerix73C5C5C84040CBPeripher -B888-A8F3E8C699F5,名称 = Duo-ZKBY,状态 = 已连接
[DEBUG] didUpdateNotification state for characteristic: CBCharacteristic: 0x1742a3c60, UUID = 3EC61402-89CD-49C3-A0D9-7A85669E901E, properties = 0x10, value = (null), notifying = YES on peripheral: CBPeripheral: 0x1740fba80, identifier = 547BC3C9-4823-431C-B888-A8F3E8C699F5, name = Duo-ZKBY, state = connected [DEBUG] 特性的 didUpdateNotification 状态:CBCharacteristic:0x1742a3c60,UUID = 3EC61402-89CD-49C3-A0D9-7A85669E901E,属性 = 0x10,值 =(空),通知 = YES,外围设备标识符:C0BPeri-870C80C0BPeri-87C0B 431C-B888-A8F3E8C699F5,名称= Duo-ZKBY,状态=已连接

Found the solution - posting here for the benefit of others.找到了解决方案 - 在这里发帖以造福他人。

Reading through the documentation provided by Redbear Labs, the key thing to note is that the Command characteristic only supports two types of properties - PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY通读 Redbear Labs 提供的文档,需要注意的关键是 Command 特性仅支持两种类型的属性 - PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY PROPERTY_WRITE_NO_RESPONSE | PROPERTY_NOTIFY

Likewise the Scan characteristic only supports PROPERTY_NOTIFY同样,扫描特性仅支持PROPERTY_NOTIFY

Also, to have the device scan all available Wifi - we should only write a 2 byte command [0x20, 0xA0] to the Command characteristic - code for the same is below此外,要让设备扫描所有可用的 Wifi - 我们应该只向命令特性写入一个 2 字节的命令[0x20, 0xA0] - 相同的代码如下

func scanWifi() {
        print("[DEBUG] - Scanning for Wifi")

        let command:[UInt8] = [0x02, 0xA0]
        let commandData = NSData(bytes: command, length: command.count)
        BLE.sharedInstance.writeTo(characteristic: BLE.sharedInstance.RBL_CHAR_CMD_UUID, data: commandData, withType: .withoutResponse)
}

Nothing needs to be written to the scan characteristic.无需将任何内容写入扫描特性。 When Wifi scanning begins, the Scan characteristic will send a notification with value 0xB1 to indicate start of scanning and then send a notification with value 0xB2 to indicate end of scanning.当 Wifi 扫描开始时,Scan 特性将发送一个值为0xB1的通知以指示扫描开始,然后发送一个值为0xB2的通知以指示扫描结束。

The actual Wifi networks scanned will be sent via notifications on the command characteristic itself.扫描的实际 Wifi 网络将通过命令特性本身的通知发送。

After calling调用后

peripheral.writeValue(dataToWrite, for: char, type: .withResponse)

you need to call the read in this delegate function:您需要在此委托函数中调用读取:

func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {

// Call your read functions here. 
     BLE.sharedInstance.read(fromCharacteristic: BLE.sharedInstance.RBL_CHAR_SCN_UUID)

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM