OTA篇(一):通过swift发送数据到设备,进入OTA模式

发布于:2025-07-16 ⋅ 阅读:(13) ⋅ 点赞:(0)

在开发智能蓝牙移动app中,我们需要进行ota功能的开发;
具体操作流程记录一下:
一.在发送设备进入到OTA模式的地方进行第一步操作:

//ota升级
  let ins: UInt8 = 0xFF
  let len: UInt8 = 4
  let data: [UInt8] = [0x5A,0xA5,0x67,0x76]
  let packet = self.allExpanded.buildInstructionPacket(ins: ins, len: len, data: data)
  • buildInstructionPacket方法是根据指令格式构建数据包
    func buildInstructionPacket(ins: UInt8, len: UInt8, data: [UInt8]) -> Data {
        var packet = Data()
        packet.append(ins)
        packet.append(len)
        packet.append(contentsOf: data)
        let crc = packet.reduce(0, { $0 &+ $1 }) & 0xFF ^ 0xFF
        packet.append(UInt8(crc))
        return packet
    }

二:发送构建好的数据包到蓝牙

  • packet就是上面构建好的数据包,发送此命令给底层设备
  • self.model?.mSendotacharater是需要发送进入OTA的UUID
  • self.model?.mPeripheral是服务
BleManager.shared.writeValue(packet, self.model?.mSendotacharater, self.model?.mPeripheral)

三,此时就是蓝牙管理数据层,调用发送写入方法;

    //写入蓝牙数据
    func writeValue(_ value:Data?, _ character:CBCharacteristic?, _ periperal:CBPeripheral?){
        if value != nil && character != nil && periperal != nil {
            writeataValue(value!, for: character, periperalData: periperal)
        }
    }
  • value就是BleManager.shared.writeValue发送过来的构建好的数据
  • writeataValue是蓝牙写入方法,如下
    func writeataValue(_ value:Data, for characteristic: CBCharacteristic?, periperalData periperal: CBPeripheral?){
        let data:Data = value
        if (characteristic?.properties.rawValue)! & CBCharacteristicProperties.writeWithoutResponse.rawValue != 0 {
            periperal?.writeValue(data, for: characteristic!, type: .withoutResponse)
        } else {
            
            periperal?.writeValue(data, for: characteristic!, type: .withResponse)
        }
    }

好了,数据发送到设备,进入ota模式就成功了;

以下是两个方法:
1.调用服务成功后,获取到特征值

 //调取服务成功,读取特征值
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        if error != nil {
            if let error = error {
                print("发现蓝牙特征出现错误,错误原因:\(error)")
            }
        } else {
            for character in service.characteristics ?? [] {
                print("==character== ",character.uuid)
                
                // 重新设计制作 2023/6/27 13:46
                if character.uuid == RECEIVE_DATA_UUID {
                    
                    for model in successList {
                        
                        // 当前的peripheral 相等
                        if model.mPeripheral == peripheral{
                            
                            model.readTempCharater = character
                            //peripheral.discoverDescriptors(for: character)
                            //peripheral.readValue(for: character)
                            peripheral.setNotifyValue(true, for: character)
                            // 打开通知代码
                            //peripherals(peripheral: peripheral, didDiscoverCharacteristicsForService: service, error: error as NSError?)
                        }
                    }
                }
                // Ota
                else if character.uuid == SEND_OTA_UUID {
                    
                    for model in successList {
                        if model.mPeripheral == peripheral {
                            model.mSendotacharater = character
                            //开启通知
                            peripheral.setNotifyValue(true, for: character)
                        }
                    }
                }else if character.uuid == RECEIVE_FILE_UUID{
                    for model in successList {
                        if model.mPeripheral == peripheral {
                            
                            //开启通知
                            peripheral.setNotifyValue(true, for: character)
                        }
                    }
                }
            }
        }
    }

2.在外设中查询服务,打开通知服务CCCD

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if error != nil {
    if let error = error {
        print("扫描服务出现错误,错误原因:\(error)")
    }
} else {
    for service in peripheral.services ?? [] {
        print("服务UUID为...:\(service.uuid)");
        peripheral.discoverCharacteristics(nil, for: service)
        
        if service.uuid == CBUUID(string: "FFF2") {
            // 发现目标服务,设置通知和温度采样间隔
            //peripheral.setNotifyValue(true, for: service.characteristics?.first!)
            //setTemperatureSamplingInterval(interval: 0x02)
            enableNotification(peripheral) // 调用enableNotification()方法
        }
    }
}
}
    // 打开通知服务CCCD
    func enableNotification(_ peripheral: CBPeripheral) {
        // 将CCCD的值设置为1,表示打开通知服务
        let value: [UInt8] = [0x01, 0x00]
        let cccd = CBUUID(string: "2902")
        let characteristic = peripheral.services?.first?.characteristics?.first(where: { $0.uuid == cccd })
        peripheral.writeValue(Data(value), for: characteristic!, type: .withResponse)
    }

网站公告

今日签到

点亮在社区的每一天
去签到