通过蓝牙接收字符串数据
Receive string data via Bluetooth
我正在创建一个与单个外围设备通信的简单 BLE 应用程序。 phone 充当中央。我有一个 iPad 用作测试的外围设备。它安装了应用程序 LightBlue 来模拟外围设备。外围设备应该以这种格式发送一串数据。
TEM:25.11 | HUM:70 | PM10:43 | PM25:32
所以我用一项服务在 LightBlue 中创建了一个空白的虚拟外围设备。
下面是我的蓝牙连接处理代码。
import UIKit
import CoreBluetooth
class ViewController: UIViewController {
fileprivate let serviceUUID = CBUUID(string: "19B10010-E8F2-537E-4F6C-D104768A1214")
fileprivate let characteristicUUID = CBUUID(string: "19B10011-E8F2-537E-4F6C-D104768A1214")
fileprivate var manager: CBCentralManager!
fileprivate var peripheral: CBPeripheral!
fileprivate var characteristic: CBCharacteristic!
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate: self, queue: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
stopScan()
}
fileprivate func startScan() {
manager.scanForPeripherals(withServices: [serviceUUID], options: nil)
}
fileprivate func stopScan() {
manager.stopScan()
}
fileprivate func disconnectFromDevice() {
guard let peripheral = peripheral else { return }
manager.cancelPeripheralConnection(peripheral)
}
fileprivate func restoreCentralManager() {
manager.delegate = self
}
}
// MARK: - CBCentralManagerDelegate
extension ViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unsupported:
print("Unsupported")
case .unauthorized:
print("Unauthorized")
case .poweredOn:
print("Powered On")
startScan()
case .resetting:
print("Resetting")
case .poweredOff:
print("Powered Off")
case .unknown:
print("Unknown")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print("Discovered \(String(describing: peripheral.name)) at \(RSSI)")
if peripheral.name == nil || peripheral.name == "" {
return
}
if self.peripheral == nil || self.peripheral.state == .disconnected {
stopScan()
self.peripheral = peripheral
central.connect(peripheral, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices([serviceUUID])
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
self.peripheral = nil
central.scanForPeripherals(withServices: nil, options: nil)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
self.peripheral = nil
}
func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
}
}
// MARK: - CBPeripheralDelegate
extension ViewController: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
print("No. of services: \(services.count)")
for service in services {
print(service.uuid)
if service.uuid == serviceUUID {
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard let characteristics = service.characteristics else { return }
for characteristic in characteristics {
print("characteristic: \(characteristic.uuid)")
if characteristic.uuid == characteristicUUID {
self.characteristic = characteristic
peripheral.setNotifyValue(true, for: characteristic)
peripheral.readValue(for: characteristic)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
print(error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if characteristic.uuid == characteristicUUID {
print("Got reply from: \(characteristic.uuid)")
print(characteristic.value)
if let data = characteristic.value, let string = String(data: data, encoding: String.Encoding.utf8) {
print(string)
} else {
print("No response!")
}
}
}
}
发现和连接部分工作正常。问题是我没有从外围设备接收到该数据字符串。
方法 peripheral(_:didUpdateValueFor:error:)
确实被解雇了。我在控制台中收到 Got reply from: 19B10011-E8F2-537E-4F6C-D104768A1214 输出。然而,当我试图通过打印 characteristic.value
来查看是否有任何数据时,它 returns nil
.
不确定是不是我的代码有问题。或者我错误地配置了 LightBlue 上的外围设备。 LightBlue 会自动发送数据吗?我也没有在任何地方看到任何 Send 按钮或任何东西。
我也上传了一个演示项目here。
您的 LightBlue 配置显示您只能在该特定特征上写入值您还必须阅读此内容
我正在创建一个与单个外围设备通信的简单 BLE 应用程序。 phone 充当中央。我有一个 iPad 用作测试的外围设备。它安装了应用程序 LightBlue 来模拟外围设备。外围设备应该以这种格式发送一串数据。
TEM:25.11 | HUM:70 | PM10:43 | PM25:32
所以我用一项服务在 LightBlue 中创建了一个空白的虚拟外围设备。
下面是我的蓝牙连接处理代码。
import UIKit
import CoreBluetooth
class ViewController: UIViewController {
fileprivate let serviceUUID = CBUUID(string: "19B10010-E8F2-537E-4F6C-D104768A1214")
fileprivate let characteristicUUID = CBUUID(string: "19B10011-E8F2-537E-4F6C-D104768A1214")
fileprivate var manager: CBCentralManager!
fileprivate var peripheral: CBPeripheral!
fileprivate var characteristic: CBCharacteristic!
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate: self, queue: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
stopScan()
}
fileprivate func startScan() {
manager.scanForPeripherals(withServices: [serviceUUID], options: nil)
}
fileprivate func stopScan() {
manager.stopScan()
}
fileprivate func disconnectFromDevice() {
guard let peripheral = peripheral else { return }
manager.cancelPeripheralConnection(peripheral)
}
fileprivate func restoreCentralManager() {
manager.delegate = self
}
}
// MARK: - CBCentralManagerDelegate
extension ViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unsupported:
print("Unsupported")
case .unauthorized:
print("Unauthorized")
case .poweredOn:
print("Powered On")
startScan()
case .resetting:
print("Resetting")
case .poweredOff:
print("Powered Off")
case .unknown:
print("Unknown")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print("Discovered \(String(describing: peripheral.name)) at \(RSSI)")
if peripheral.name == nil || peripheral.name == "" {
return
}
if self.peripheral == nil || self.peripheral.state == .disconnected {
stopScan()
self.peripheral = peripheral
central.connect(peripheral, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices([serviceUUID])
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
self.peripheral = nil
central.scanForPeripherals(withServices: nil, options: nil)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
self.peripheral = nil
}
func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
}
}
// MARK: - CBPeripheralDelegate
extension ViewController: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
print("No. of services: \(services.count)")
for service in services {
print(service.uuid)
if service.uuid == serviceUUID {
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard let characteristics = service.characteristics else { return }
for characteristic in characteristics {
print("characteristic: \(characteristic.uuid)")
if characteristic.uuid == characteristicUUID {
self.characteristic = characteristic
peripheral.setNotifyValue(true, for: characteristic)
peripheral.readValue(for: characteristic)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
print(error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if characteristic.uuid == characteristicUUID {
print("Got reply from: \(characteristic.uuid)")
print(characteristic.value)
if let data = characteristic.value, let string = String(data: data, encoding: String.Encoding.utf8) {
print(string)
} else {
print("No response!")
}
}
}
}
发现和连接部分工作正常。问题是我没有从外围设备接收到该数据字符串。
方法 peripheral(_:didUpdateValueFor:error:)
确实被解雇了。我在控制台中收到 Got reply from: 19B10011-E8F2-537E-4F6C-D104768A1214 输出。然而,当我试图通过打印 characteristic.value
来查看是否有任何数据时,它 returns nil
.
不确定是不是我的代码有问题。或者我错误地配置了 LightBlue 上的外围设备。 LightBlue 会自动发送数据吗?我也没有在任何地方看到任何 Send 按钮或任何东西。
我也上传了一个演示项目here。
您的 LightBlue 配置显示您只能在该特定特征上写入值您还必须阅读此内容