Быстрое преобразование значения BLE характеристики c в строку - PullRequest
0 голосов
/ 03 марта 2020

У меня проблема, которая не имеет смысла. Все, что я делаю, я думаю, довольно стандартно для BLE. В любом случае, у меня есть модуль BLE, из которого я отправляю строковые данные в приложение iOS, и я отображаю эти данные на интерфейсе. Поскольку это мой первый запуск с использованием BLE-кода в приложении iOS, я использую учебник adafruit в качестве руководства, которое можно найти здесь: Учебник Adafruit

Как я уже сказал, довольно стандартные вещи. Здесь нет ничего особенного. Код, который я написал, способен выполнить все шаги BLE. Но когда он получает данные, данные /0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0. Сначала я думал, что источник на передающей стороне был неправильным. Но я открыл другое тестовое приложение, которое позволяет мне видеть отправленные данные BLE, и входящие данные правильно отформатированы. Это должно быть проблемой с моим кодом. Я не уверен, почему это происходит или в чем проблема. Я действительно мог бы использовать другую пару глаз, чтобы увидеть, есть ли проблема с моим кодом:

Мой код инициализации кода:

required init(parent: ViewController) {

        self.parent = parent

        self.bluetoothOn = false;

        bodyTemperature = 0
        airPressure = 0
        lightLevel = 0
        fanSpeed = 0
        Humidity = 0
        otherBatteryLevel = 0
        wifiStatus = "Good"

        super.init()

        self.centralManager = CBCentralManager(delegate: self, queue: nil)
        //   self.periphal = CBPeripheralManager(delegate: self, queue: nil)
    }

Мой код didupdateState:

func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if #available(iOS 10.0, *) {
            if centralManager.state == CBManagerState.poweredOn{
                bluetoothOn = true
                self.centralManager.scanForPeripherals(withServices: [ATP_SERVICE_UUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey : false])
            }
        } else {
            // Fallback on earlier versions
        }
    }

Мой код didDiscover:

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        stopScan()
        self.blePeripheral = peripheral
        self.RSSI = RSSI
        self.blePeripheral.delegate = self
        centralManager?.connect(blePeripheral, options: nil)
        print("Found BLE module")
   //     blePeripheral.discoverServices([ATP_SERVICE_UUID])


    }

Мой код didConnect:

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        print("Connected to BLE device")
        centralManager?.stopScan()
        blePeripheral.delegate = self
        blePeripheral.discoverServices([ATP_SERVICE_UUID])
    }

Мой код didDiscoverServices:

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        guard let services = peripheral.services else{
            return
        }

        for service in services{
            peripheral.discoverCharacteristics([ATP_UART_WRITE14_UUID, ATP_UART_READ13_UUID, ATP_NOTIFY_UUID], for: service)
        }

        print("Discovered Services: \(services)")
    }

Мой код didDiscoverХарактеристики:

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        guard let characteristics = service.characteristics else{
            return
        }

        print ("Found \(characteristics.count) characteristics")

        for characteristic in characteristics{
            if characteristic.uuid.isEqual(ATP_UART_READ13_UUID){
                readCharacteristic = characteristic
              //  blePeripheral.setNotifyValue(true, for: readCharacteristic!)
                blePeripheral.readValue(for: characteristic)
                print("Rx Characteristic: \(characteristic.uuid)")

            }

            if(characteristic.uuid.isEqual(ATP_UART_WRITE14_UUID)){
                writeCharacteristic = characteristic
                print("Tx characteristic: \(characteristic.uuid)")

            }
        }
    }

Мой код didupdateNotificationState:

func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
        if(error != nil){
            print("Error changing notification state:\(String(describing: error?.localizedDescription))")

        } else {
            print("Characteristic's value subscribed")
        }

        if(characteristic.isNotifying){
            print("Subscribed. Notification has begun for: \(characteristic.uuid)")
        }
    }

И, наконец, мой didUpdateValueFor:

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        if characteristic == readCharacteristic{
       //     let ASCIIString = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue)

            var stringFromData = String(data: characteristic.value!, encoding: String.Encoding.ascii)
            if stringFromData != "" {
                let textArray = stringFromData!.components(separatedBy: "\n\r")

                for line in textArray{
                    if line.hasPrefix("bodyTemperature:") {
                        var splitString = line.characters.split(separator: ":").map(String.init)
                        bodyTemperature = Float(splitString[1])!
                        self.delegate?.PQEData(didRecieveData: bodyTemperature)
                    } else if line.hasPrefix("enclosurePressure:") {
                        var splitString = line.characters.split(separator: ":").map(String.init)
                        airPressure = Float(splitString[1])!
                        self.delegate?.PQEData(didRecieveData: airPressure)
                    } else if line.hasPrefix("lightLevel:") {
                        var splitString = line.characters.split(separator: ":").map(String.init)
                        lightLevel = Float(splitString[1])!
                        self.delegate?.PQEData(didRecieveData: lightLevel)
                    } else if line.hasPrefix("humidity:") {
                        var splitString = line.characters.split(separator: ":").map(String.init)
                        Humidity = Float(splitString[1])!
                        self.delegate?.PQEData(didRecieveData: Humidity)
                    } else if line.hasPrefix("BATT:") {
                        var splitString = line.characters.split(separator: ":").map(String.init)
                        otherBatteryLevel = Float(splitString[1])!
                        self.delegate?.PQEData(didRecieveData: otherBatteryLevel)
                    } else if line.hasPrefix("fanSpeed:") {
                        var splitString = line.characters.split(separator: ":").map(String.init)
                        fanSpeed = Int(splitString[1])!
                        self.delegate?.PQEData(didRecieveData: fanSpeed)
                    } else if line.hasPrefix("wifiStatus:") {
                        var splitString = line.characters.split(separator: ":").map(String.init)
                        wifiStatus = splitString[1]
                        self.delegate?.PQEData(didRecieveData: wifiStatus)
                    }
                }
            }
        }
    }

Дополнительные примечания:

1) В функции didDiscoverCharaceristics у меня есть закомментировал вызов функции blePeripheral.setNotifyValue. Это связано с тем, что на линии вызова peripheral.discoverCharacteristics я уже обнаруживаю характеристики NOTIFY. Я также проверил с setNotifyValue без комментариев, и результаты те же.

2) У меня есть локальная переменная blePeriphal, которая хранит ссылку на периферию для устройства ble. То же самое относится к writeCharacteristi c и readCharacteristi c

3) Когда функция blePeripheral.setNotifyValue была раскомментирована, была выполнена функция didUpdateNotificationStateFor. Тем не менее, оператор if(error != nil) будет истинным, и я получу ошибку: Error changing notification state:Optional("The request is not supported."). Я не уверен, если это связано. Тем не менее, функция didUpdateValueFor все равно будет выполняться.

4) Код, который вызывает у меня проблему, находится в функции didUpdateValueFor и строка: var stringFromData = String(data: characteristic.value!, encoding: String.Encoding.ascii)

5) Да, я пробовал var stringFromData = String(data: characteristic.value!, encoding: String.Encoding.utf8) и var stringFromData = String(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue), и результаты были одинаковыми. StringFromData - это все /0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0/0

Обновление:

6) Итак, после некоторого тестирования я столкнулся с проблемой, которая может быть связана. Делегат didUpdateValueFor вызывается только один раз и после этого, никогда больше. Я проверял это, постоянно посылая строку раз в 1/4 секунды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...