我是Swift的新手,因此有一些非常基本的问题。我计划开发一个简单的iPhone应用程序,它可以与连接到eBike控制器的ESP 32(双向)对话。ESP 32设置为通过BLE传输和接收数据。它发送4个信号:mode(1,2,3),light(on/off),bat(battery;值在31.5和41.5之间)和速度(浮点),并接受命令:“um”用于更改模式,“li”用于在灯光开/关之间切换
相应的UUID如下
#define SERVICE_UUID "19074fb4-161b-47c7-964e-9d087266d6a7"
#define CHARACTERISTIC_UUID_RX "101880eb-a78e-4cee-b252-56e06093f4da"
#define CHARACTERISTIC_UUID_TX_MODE "5d64d30b-3e03-4e65-82a2-a85e9d568f84"
#define CHARACTERISTIC_UUID_TX_LIGHT "dfbec318-8292-4b34-87b5-f13e4efb1560"
#define CHARACTERISTIC_UUID_TX_BAT "a5b79c5d-977a-4ef0-b3f3-b8f26e166378"
#define CHARACTERISTIC_UUID_TX_SPEED "b0bfad34-c571-41a5-8bc3-7726ced1ebbe"
在Swift方面,我有UI,但我不能让按钮(模式,灯光,连接)和连接正常工作。
以下是我的swift文件,包括BLE函数:
//
// BLEController.swift
// Bike Controller
//
// Created by David Melinc on 19.05.22.
//
import Foundation
import CoreBluetooth
struct Peripheral: Identifiable {
let id: Int
let name: String
let rssi: Int
}
class BLEController: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeripheralDelegate {
var myCentral: CBCentralManager!
var myPeripheral: CBPeripheral!
@Published var isSwitchedOn = false
@Published var peripherals = [Peripheral]()
@Published var mode: UInt16 = 0
@Published var light: String = " "
@Published var bat: UInt16 = 0
@Published var speed: UInt16 = 0
let SERVICE_UUID = CBUUID(string: "19074fb4-161b-47c7-964e-9d087266d6a7")
let CHARACTERISTIC_UUID_RX = CBUUID(string: "101880eb-a78e-4cee-b252-56e06093f4da")
let CHARACTERISTIC_UUID_TX_MODE = CBUUID(string: "5d64d30b-3e03-4e65-82a2-a85e9d568f84")
let CHARACTERISTIC_UUID_TX_LIGHT = CBUUID(string: "dfbec318-8292-4b34-87b5-f13e4efb1560")
let CHARACTERISTIC_UUID_TX_BAT = CBUUID(string: "a5b79c5d-977a-4ef0-b3f3-b8f26e166378")
let CHARACTERISTIC_UUID_TX_SPEED = CBUUID(string: "b0bfad34-c571-41a5-8bc3-7726ced1ebbe")
override init() {
super.init()
myCentral = CBCentralManager(delegate: self, queue: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
isSwitchedOn = true
}
else {
isSwitchedOn = false
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
var peripheralName: String!
if let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
peripheralName = name
}
else {
peripheralName = "Unknown"
}
let newPeripheral = Peripheral(id: peripherals.count, name: peripheralName, rssi: RSSI.intValue)
print(newPeripheral)
peripherals.append(newPeripheral)
}
func connectBLE(peripheral1) {
print("trying to connect to \(peripheral1)")
self.myCentral.connect(peripheral1, options: nil)
print(2)
}
}
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
self.myPeripheral.discoverServices(nil)
print("Connected to "+peripheral.name!)
}
func startScanning() {
print("startScanning")
myCentral.scanForPeripherals(withServices: nil, options: nil)
self.perform(#selector(stopScanning), with: self, afterDelay: 5)
}
@objc func stopScanning() {
print("stopScanning")
myCentral.stopScan()
}
}
UI文件如下:
import SwiftUI
struct BLEdevices: View {
//@StateObject var bleController = BLEController()
@EnvironmentObject var bleController: BLEController
var body: some View {
ZStack {
Color("Themecolor")
.edgesIgnoringSafeArea(.all)
VStack (spacing: 10) {
Text("Bluetooth Devices")
.font(.largeTitle)
.frame(maxWidth: .infinity, alignment: .center)
List(bleController.peripherals) { peripheral in
HStack {
Text(peripheral.name)
Spacer()
Text(String(peripheral.rssi))
Spacer()
Button(action: {
//bleController.connectBLE(peripheral.name)
}) {
Text("CONNECT")
.font(.system(size: 10))
.fontWeight(.bold)
.padding()
.foregroundColor(.black)
.frame(alignment: .center)
.background(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.white, lineWidth: 2)
.background(Color.white.cornerRadius(10)))
}
}
}
.frame(height: 600)
HStack (spacing: 10) {
Button(action: {
bleController.startScanning()
}) {
Text("SCAN")
.font(.title)
.fontWeight(.bold)
.padding()
.foregroundColor(.black)
.frame(width: 150, alignment: .center)
.background(
RoundedRectangle(cornerRadius: 25)
.stroke(Color.white, lineWidth: 2)
.background(Color.white.cornerRadius(25)))
}
Button(action: {
bleController.stopScanning()
}) {
Text("STOP")
.font(.title)
.fontWeight(.bold)
.padding()
.foregroundColor(.black)
.frame(width: 150, alignment: .center)
.background(
RoundedRectangle(cornerRadius: 25)
.stroke(Color.white, lineWidth: 2)
.background(Color.white.cornerRadius(25)))
}
}
}
}
}
}
struct BLEdevices_Previews: PreviewProvider {
static var previews: some View {
BLEdevices()
}
}
我想在扫描周围环境后运行connectBLE功能。
因此,我的问题如下:
1.)在我扫描了整个区域后,我如何连接到特定的设备?我有问题从“peripheral.name”返回到CBPeripheral格式,我可以使用它来放入我的myCentral.connect函数。2.)在两个设备连接后,我如何在它们之间接收和传输数据?来自ESP 32的所有信号都通过来自ESP 32的通知使用单独的UUID传输,但是我不知道我是如何在Swift端获得/处理它们的。通过按钮“mode”和“light”,我想向ESP 32发送简单的ASCII代码。
如果有人能在这里帮助我,我将非常感激,因为我被卡住了。
最佳大卫
1条答案
按热度按时间u4dcyp6a1#
重要的是,您要广告要找到的服务,而不仅仅是创建/促进。nRF connect等应用程序可以帮助您确定服务是否被广告,否则扫描服务(该特定服务)将不成功。
至于第二个问题:看他的作品https://www.raywenderlich.com/231-core-bluetooth-tutorial-for-ios-heart-rate-monitor
你可以读出要读的特性,反之亦然。通知并不总是需要的。