У меня проблема, которая не имеет смысла. Все, что я делаю, я думаю, довольно стандартно для 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 секунды.