iOS Swift BLE UART, где didUpdateValueFor вызывается только дважды и выходит - PullRequest
0 голосов
/ 30 мая 2018

У меня есть встроенный процессор, отправляющий строки через BLE UART на iPhone.Я могу подключиться к устройству, настроить характеристики UART, но он читает только два символа и didUpdateValueFor больше не вызывается.Я должен что-то настраивать неправильно.Там, похоже, переполнение буфера, или это не отдых для каждого чтения.

Я хочу иметь возможность установить соединение UART между платой и iPhone.Я могу позаботиться о разборе.

Точно не я посылаю символ '0' каждые 250 мс с доски.Он получает два 0 и событие больше не вызывается.

//  ViewController.swift


import UIKit
import CoreBluetooth

class ScannerVC: UIViewController, CBCentralManagerDelegate {

    var centralManager: CBCentralManager!
    var peripheral: CBPeripheral!
    var scannedGrowZeboDevices: [CBPeripheral] = []
    var timer: Timer!
    var connectionVC: ConnectionVC!

    override func viewDidLoad() {
        super.viewDidLoad()


   }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        var msg = ""
        switch (central.state) {
        case .poweredOff:
            msg = "Bluetooth is powered off"
        case .poweredOn:
            msg = "Bluetooth is powered on"
            timer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(ScannerVC.stopScanning), userInfo: nil, repeats: false)
            centralManager.scanForPeripherals(withServices: nil, options: nil)
        case .unsupported:
            msg = "Bluetooth is unsopported"
        case .resetting:
            msg = "The BLE Manager is resetting; a state update is pending"
        case .unknown:
            msg = "BThe state of the BLE Manager is unkown"
        default:
            break
        }
        print("Status: \(msg)")
    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
            if peripheralName.contains("Grow") || peripheralName.contains("paul") {
                print("Peripheral Name: \(peripheralName)")
                for existing in scannedGrowZeboDevices {
                    if existing.identifier == peripheral.identifier {
                        print("Peripheral already exists, returning")
                        return
                    }
                }
                // adding peripheral to the array //
                scannedGrowZeboDevices.append(peripheral)

                self.peripheral = peripheral
                print("There are \(scannedGrowZeboDevices.count)     peripherals in the array")
            }
        }
    }

    @objc func stopScanning() {
        timer.invalidate()
        centralManager.stopScan()
        print("Scanning stopped")
        performSegue(withIdentifier: "toNavigation", sender: scannedGrowZeboDevices)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toNavigation" {
            if let navController = segue.destination as? UINavigationController {
                let connectionVC = navController.viewControllers.first as! ConnectionVC
                centralManager.delegate = connectionVC
                connectionVC.centralManager = self.centralManager
                connectionVC.growzeboDevices = sender as! [CBPeripheral?]
            }
        }
    }

}


 func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        //*********************************************************************************
        // Added May 28, 2018
        // This shows there is a connection to the peripheral
        //*********************************************************************************

        print("[DEBUG] Connected to peripheral  \(peripheral.identifier.uuidString)")
      //  self.activePeripheral = peripheral



        peripheral.discoverServices(nil)
    }

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        let defaults = UserDefaults.standard
        if let services = peripheral.services as [CBService]? {
            //print("Discovered Services for: \(String(describing: peripheral.name))")
            for service in services {
                peripheral.discoverCharacteristics(nil, for: service)
                print("Found serial port service")
            }

            //**********************************************************************
            // Added May 28, 2018
            // Add the TX and RX for the discovered services
            //*********************************************************************

            print("[DEBUG] Found services for peripheral: \(peripheral.identifier.uuidString)")


        //    for service in peripheral.services! {
        //        let theCharacteristics = [CBUUID(serialPortServiceUuid), CBUUID(serialPortServiceUuid)]
        //    }

            if let name = peripheral.name {
                print("Connected to: \(name)")
                if let _ = defaults.dictionary(forKey: peripheral.name!) {
                    // To do if the card has already been connected before
                } else {
                    // To do if the card getting connected first time
                    settingsToSave["name"] = peripheral.name!
                    settingsToSave["connected"] = true
                    defaults.set(settingsToSave, forKey: peripheral.name!)
                    let detailsVC = storyboard?.instantiateViewController(withIdentifier: "detailsVC") as! DetailsVC
                    centralManager.delegate = detailsVC
                    let cm = centralManager
                    detailsVC.centralManager = cm
                    detailsVC.peripheral = peripheral
                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                        self.navigationController?.pushViewController(detailsVC, animated: true)
                    }
                }
            }
            growzebosTableView.reloadData()
        }
    }




    //************************** Functionality Starts here *******************************//
    override func viewDidLoad() {
        super.viewDidLoad()

        vegSettings = GrowzeboBoxModel()
        bloomSettings = GrowzeboBoxModel()
        customSettings  = GrowzeboBoxModel()
        setupPickerViews()
        //*************************************************
        // Added May 15, 2018
        // Thiz sets up the object for picking AUX values
        setupPumpPickerViews()

        let defaults = UserDefaults.standard
        savedSettings = defaults.dictionary(forKey: peripheral.name!)!

        deviceName.text = peripheral.name
   //     state.text = String("\(peripheral.state)")
        let buf = [UInt8]()
 //   let buf: [UInt8] = [10000]
        dataRxCredits = Data.init(buf)
        let buf2: [UInt8] = [0xFF]
        disconnectCredit = Data.init(bytes: buf2)
        // adding targets to sliders //

   func open() -> Bool {
        var ok = false
        if peripheral.state == .connected {
            state.text = "Connected"
    //        nTxCredits = 0
       //     pendingData = nil
            pendingCredits = false
            peripheral.delegate = self
            initServicesAndCharacteristics()
            openSerialPortService()
            ok = true
        }
        else{
            state.text = "Disconnected"
        }
        return ok
    }

    // Initialize all the required services and characteristics //
    func initServicesAndCharacteristics() {
        var s: CBService?
        var c: CBCharacteristic?
        service = nil
        creditsCharacteristic = nil
        fifoCharacteristic = nil
        deviceIdService = nil
        fwVersionCharacteristic = nil
        modelNumberCharacteristic = nil
        for i in 0..<peripheral.services!.count {
            s = peripheral.services![i]
            if let data = s?.uuid.data {
                let dataInBytes = [UInt8](data)
                if (s?.uuid.data.count == 16) && (memcmp(dataInBytes, serialPortServiceUuid, 16) == 0) {
                    service = s
                }
                else if (s?.uuid.data.count == 2) && (memcmp(dataInBytes, deviceIdServiceUuid, 2) == 0) {
                    deviceIdService = s
                }
            }
        }
        if service != nil {
            if service!.characteristics != nil {
                for i in 0..<service!.characteristics!.count {
                    c = service!.characteristics![i]
                    if let data = c?.uuid.data {
                        let dataInBytes = [UInt8](data)
                        if (c?.uuid.data.count == 16) && (memcmp(dataInBytes, serialPortFifoCharactUuid, 16) == 0) {
                            fifoCharacteristic = c
                        }
                        else if (c?.uuid.data.count == 16) && (memcmp(dataInBytes, creditsCharactUuid, 16) == 0) {
                            creditsCharacteristic = c
                        }
                    }
                }
            }
        }
        if deviceIdService != nil {
            if deviceIdService!.characteristics != nil {
                for i in 0..<deviceIdService!.characteristics!.count {
                    c = deviceIdService!.characteristics![i]
                    if (c?.uuid.data.count == 2) {
                        modelNumberCharacteristic = c
                    }
                    else if (c?.uuid.data.count == 2) {
                        fwVersionCharacteristic = c
                    }
                }
            }
        }
    }

    // Opening serial port //
    func openSerialPortService() {

  //      serialPortVersion = 2
        peripheral.setNotifyValue(true, for: creditsCharacteristic!)
        peripheral.setNotifyValue(true, for: fifoCharacteristic!)
        peripheral.writeValue(dataRxCredits!, for: creditsCharacteristic!, type: .withoutResponse)
    }

    // Closing serial port //
    func closeSerialPortService() {
        peripheral.setNotifyValue(false, for: creditsCharacteristic!)
        peripheral.setNotifyValue(false, for: fifoCharacteristic!)
        peripheral.writeValue(disconnectCredit!, for: creditsCharacteristic!, type: .withoutResponse)
    }

    // Send a serial message to the card //
    @objc func sendSerialMessage(_ message: String) {
        if (peripheral.state != .connected)
        {
            SVProgressHUD.dismiss()
            navigationController?.popToRootViewController(animated: true)
            print("Disconected")
        }
        let msgToSend = message.appendingFormat("\r")
        //let msg = "show\r"
        let buf: [UInt8] = Array(msgToSend.utf8)
        let data = Data(buf)
        peripheral.writeValue(data, for: fifoCharacteristic!, type: CBCharacteristicWriteType.withoutResponse)
        print("\(message) sent")
        commandname = message
    }
...