使用一个 CBManager 连接和写入多个外围设备
Posted
技术标签:
【中文标题】使用一个 CBManager 连接和写入多个外围设备【英文标题】:Connecting and writing to multiple peripherals with one CBManager 【发布时间】:2019-09-20 04:48:53 【问题描述】:我正在尝试制作一个 ios 应用程序,该应用程序使用 CoreBluetooth 库来启动/停止并传输来自配备 HM-10 BLE 4.0 模块的多个惯性测量单元的数据。我只从一个模块连接/写入/读取没有问题,但我无法获得与多个模块的连接。我需要做什么才能做到这一点?
我尝试创建多个 CBManager,但没有成功,我只是尝试通过单击表中的一行来连接多个外围设备,
for peripheral in peripherals
CBManager.connect(myPeripheral)
这些选项没有奏效,我希望我能获得一些关于下一步尝试的指导。我对 Swift 很陌生,在过去的几周里刚刚开始学习它。
这是我在搜索蓝牙连接时所需要的:
import UIKit
import CoreBluetooth
class ScanTableViewController: UITableViewController, CBCentralManagerDelegate
var peripherals:[CBPeripheral] = []
var manager:CBCentralManager? = nil
var parentView:MainViewController? = nil
//This is my tableView where I try to connect to all the peripherals
// that come back in the table by just selecting one peripheral.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
for peripheral in peripherals
manager?.connect(peripheral, options: nil)
// CBCentralManagerDelegate Methods
// I think this is where I'm having issues, how do I pass all the connected peripherals on to the next view?
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
//pass reference to connected peripheral to parent view
parentView?.mainPeripheral = peripheral
peripheral.delegate = parentView
peripheral.discoverServices(nil)
//set the manager's delegate view to parent so it can call relevant disconnect methods
manager?.delegate = parentView
parentView?.customiseNavigationBar()
if let navController = self.navigationController
navController.popViewController(animated: true)
print("Connected to " + peripheral.name!)
这是我使用 Connection 的课程:
// MainViewController.swift
//Bo Heyse
import UIKit
import CoreBluetooth
class MainViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate
var manager:CBCentralManager? = nil
var mainPeripheral:CBPeripheral? = nil
var mainCharacteristic:CBCharacteristic? = nil
let BLEService = "FFE0"
let BLECharacteristic = "FFE1"
@IBOutlet weak var recievedMessageText: UILabel!
//how do I get this function to send a connection to all the peripherals?
@IBAction func sendButtonPressed(_ sender: AnyObject)
let helloWorld = "Hello World!"
let dataToSend = helloWorld.data(using: String.Encoding.utf8)
if (mainPeripheral != nil)
mainPeripheral?.writeValue(dataToSend!, for: mainCharacteristic!, type: CBCharacteristicWriteType.withoutResponse)
else
print("haven't discovered device yet")
// MARK: - CBCentralManagerDelegate Methods
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)
mainPeripheral = nil
customiseNavigationBar()
print("Disconnected" + peripheral.name!)
// MARK: CBPeripheralDelegate Methods
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?)
for service in peripheral.services!
print("Service found with UUID: " + service.uuid.uuidString)
//device information service
if (service.uuid.uuidString == "180A")
peripheral.discoverCharacteristics(nil, for: service)
//GAP (Generic Access Profile) for Device Name
// This replaces the deprecated CBUUIDGenericAccessProfileString
if (service.uuid.uuidString == "1800")
peripheral.discoverCharacteristics(nil, for: service)
//Bluno Service
if (service.uuid.uuidString == BLEService)
peripheral.discoverCharacteristics(nil, for: service)
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?)
//get device name
if (service.uuid.uuidString == "1800")
for characteristic in service.characteristics!
if (characteristic.uuid.uuidString == "2A00")
peripheral.readValue(for: characteristic)
print("Found Device Name Characteristic")
if (service.uuid.uuidString == "180A")
for characteristic in service.characteristics!
if (characteristic.uuid.uuidString == "2A29")
peripheral.readValue(for: characteristic)
print("Found a Device Manufacturer Name Characteristic")
else if (characteristic.uuid.uuidString == "2A23")
peripheral.readValue(for: characteristic)
print("Found System ID")
if (service.uuid.uuidString == BLEService)
for characteristic in service.characteristics!
if (characteristic.uuid.uuidString == BLECharacteristic)
//we'll save the reference, we need it to write data
mainCharacteristic = characteristic
//Set Notify is useful to read incoming data async
peripheral.setNotifyValue(true, for: characteristic)
print("Found Bluno Data Characteristic")
使用我发布的当前代码,我得到一个返回的错误
API MISUSE: Forcing disconnection of unused peripheral <CBPeripheral: 0x280ab4000,
identifier = B5835D05-CE72-D9EC-1526-2967566810F1, name = HEAD,
state = connected>. Did you forget to cancel the connection?
有人可以就这个问题提供一些指导吗?非常感谢。
【问题讨论】:
欢迎来到 ***。您在获得此问题的有用答案方面的变化很小。代码太多,与不相关的 UI 代码混合在一起,您提供了两种变体(循环连接,在 UITableView 委托中连接)并混合描述等。请改进您的问题。创建一个最小的可重现示例。 When a row is selected, you connect to all peripherals, not just the one in that row, Is that intentional? 【参考方案1】:我想我可以看到问题所在。连接到第一个外围设备后,从导航控制器中弹出当前视图控制器。通过这样做,您的外围设备阵列将被释放,因为控制器不再可用。因此,没有参考当前发现的外围设备。当没有对外围设备的引用时,它将断开连接。 (想想关闭连接到外围设备的应用程序会强制断开连接)。
解决方案:
不要将 parentView 设置为外围代理,而是将 self (ScanTableViewController
) 设置为代理并且不要弹出 Controller。换句话说,做一些可以保留参考的事情。
【讨论】:
以上是关于使用一个 CBManager 连接和写入多个外围设备的主要内容,如果未能解决你的问题,请参考以下文章
使用 Ionic Native BLE 向 BLE 外围设备发出写入值
Android-BlutoothBle,蓝牙中心设备(peripheral)向外围设备(GattServer)连续写入多个Characteristic的注意事项
如何解决 [CoreBluetooth] 警告:对于具有多个设备连接的外围设备来说,这不是一个有效的特征