我有一个嵌入式CPU通过BLE UART将字符串发送到iPhone。我可以连接到设备,设置UART特性,但它只读取两个字符,并且不再调用didUpdateValueFor。我必须设置错误的东西。似乎有一些缓冲区溢出或者每次读取都没有休息。
我希望能够在主板和iPhone之间建立UART连接。我可以照顾解析。
是的,我不是每隔250毫秒从电路板发送一个字符'0'。它拿起两个'0'并且不再调用该事件。
// ViewController.swift
import UIKit
import CoreBluetooth
class ScannerVC: UIViewController, CBCentralManagerDelegate {
var centralManager: CBCentralManager!
var peripheral: CBPeripheral!
var scannedGrowZeboDevices: [CBPeripheral] = []
var timer: Timer!
var connectionVC: ConnectionVC!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
var msg = ""
switch (central.state) {
case .poweredOff:
msg = "Bluetooth is powered off"
case .poweredOn:
msg = "Bluetooth is powered on"
timer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(ScannerVC.stopScanning), userInfo: nil, repeats: false)
centralManager.scanForPeripherals(withServices: nil, options: nil)
case .unsupported:
msg = "Bluetooth is unsopported"
case .resetting:
msg = "The BLE Manager is resetting; a state update is pending"
case .unknown:
msg = "BThe state of the BLE Manager is unkown"
default:
break
}
print("Status: \(msg)")
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
if peripheralName.contains("Grow") || peripheralName.contains("paul") {
print("Peripheral Name: \(peripheralName)")
for existing in scannedGrowZeboDevices {
if existing.identifier == peripheral.identifier {
print("Peripheral already exists, returning")
return
}
}
// adding peripheral to the array //
scannedGrowZeboDevices.append(peripheral)
self.peripheral = peripheral
print("There are \(scannedGrowZeboDevices.count) peripherals in the array")
}
}
}
@objc func stopScanning() {
timer.invalidate()
centralManager.stopScan()
print("Scanning stopped")
performSegue(withIdentifier: "toNavigation", sender: scannedGrowZeboDevices)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toNavigation" {
if let navController = segue.destination as? UINavigationController {
let connectionVC = navController.viewControllers.first as! ConnectionVC
centralManager.delegate = connectionVC
connectionVC.centralManager = self.centralManager
connectionVC.growzeboDevices = sender as! [CBPeripheral?]
}
}
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
//*********************************************************************************
// Added May 28, 2018
// This shows there is a connection to the peripheral
//*********************************************************************************
print("[DEBUG] Connected to peripheral \(peripheral.identifier.uuidString)")
// self.activePeripheral = peripheral
peripheral.discoverServices(nil)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
let defaults = UserDefaults.standard
if let services = peripheral.services as [CBService]? {
//print("Discovered Services for: \(String(describing: peripheral.name))")
for service in services {
peripheral.discoverCharacteristics(nil, for: service)
print("Found serial port service")
}
//**********************************************************************
// Added May 28, 2018
// Add the TX and RX for the discovered services
//*********************************************************************
print("[DEBUG] Found services for peripheral: \(peripheral.identifier.uuidString)")
// for service in peripheral.services! {
// let theCharacteristics = [CBUUID(serialPortServiceUuid), CBUUID(serialPortServiceUuid)]
// }
if let name = peripheral.name {
print("Connected to: \(name)")
if let _ = defaults.dictionary(forKey: peripheral.name!) {
// To do if the card has already been connected before
} else {
// To do if the card getting connected first time
settingsToSave["name"] = peripheral.name!
settingsToSave["connected"] = true
defaults.set(settingsToSave, forKey: peripheral.name!)
let detailsVC = storyboard?.instantiateViewController(withIdentifier: "detailsVC") as! DetailsVC
centralManager.delegate = detailsVC
let cm = centralManager
detailsVC.centralManager = cm
detailsVC.peripheral = peripheral
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.navigationController?.pushViewController(detailsVC, animated: true)
}
}
}
growzebosTableView.reloadData()
}
}
//************************** Functionality Starts here *******************************//
override func viewDidLoad() {
super.viewDidLoad()
vegSettings = GrowzeboBoxModel()
bloomSettings = GrowzeboBoxModel()
customSettings = GrowzeboBoxModel()
setupPickerViews()
//*************************************************
// Added May 15, 2018
// Thiz sets up the object for picking AUX values
setupPumpPickerViews()
let defaults = UserDefaults.standard
savedSettings = defaults.dictionary(forKey: peripheral.name!)!
deviceName.text = peripheral.name
// state.text = String("\(peripheral.state)")
let buf = [UInt8]()
// let buf: [UInt8] = [10000]
dataRxCredits = Data.init(buf)
let buf2: [UInt8] = [0xFF]
disconnectCredit = Data.init(bytes: buf2)
// adding targets to sliders //
func open() -> Bool {
var ok = false
if peripheral.state == .connected {
state.text = "Connected"
// nTxCredits = 0
// pendingData = nil
pendingCredits = false
peripheral.delegate = self
initServicesAndCharacteristics()
openSerialPortService()
ok = true
}
else{
state.text = "Disconnected"
}
return ok
}
// Initialize all the required services and characteristics //
func initServicesAndCharacteristics() {
var s: CBService?
var c: CBCharacteristic?
service = nil
creditsCharacteristic = nil
fifoCharacteristic = nil
deviceIdService = nil
fwVersionCharacteristic = nil
modelNumberCharacteristic = nil
for i in 0..<peripheral.services!.count {
s = peripheral.services![i]
if let data = s?.uuid.data {
let dataInBytes = [UInt8](data)
if (s?.uuid.data.count == 16) && (memcmp(dataInBytes, serialPortServiceUuid, 16) == 0) {
service = s
}
else if (s?.uuid.data.count == 2) && (memcmp(dataInBytes, deviceIdServiceUuid, 2) == 0) {
deviceIdService = s
}
}
}
if service != nil {
if service!.characteristics != nil {
for i in 0..<service!.characteristics!.count {
c = service!.characteristics![i]
if let data = c?.uuid.data {
let dataInBytes = [UInt8](data)
if (c?.uuid.data.count == 16) && (memcmp(dataInBytes, serialPortFifoCharactUuid, 16) == 0) {
fifoCharacteristic = c
}
else if (c?.uuid.data.count == 16) && (memcmp(dataInBytes, creditsCharactUuid, 16) == 0) {
creditsCharacteristic = c
}
}
}
}
}
if deviceIdService != nil {
if deviceIdService!.characteristics != nil {
for i in 0..<deviceIdService!.characteristics!.count {
c = deviceIdService!.characteristics![i]
if (c?.uuid.data.count == 2) {
modelNumberCharacteristic = c
}
else if (c?.uuid.data.count == 2) {
fwVersionCharacteristic = c
}
}
}
}
}
// Opening serial port //
func openSerialPortService() {
// serialPortVersion = 2
peripheral.setNotifyValue(true, for: creditsCharacteristic!)
peripheral.setNotifyValue(true, for: fifoCharacteristic!)
peripheral.writeValue(dataRxCredits!, for: creditsCharacteristic!, type: .withoutResponse)
}
// Closing serial port //
func closeSerialPortService() {
peripheral.setNotifyValue(false, for: creditsCharacteristic!)
peripheral.setNotifyValue(false, for: fifoCharacteristic!)
peripheral.writeValue(disconnectCredit!, for: creditsCharacteristic!, type: .withoutResponse)
}
// Send a serial message to the card //
@objc func sendSerialMessage(_ message: String) {
if (peripheral.state != .connected)
{
SVProgressHUD.dismiss()
navigationController?.popToRootViewController(animated: true)
print("Disconected")
}
let msgToSend = message.appendingFormat("\r")
//let msg = "show\r"
let buf: [UInt8] = Array(msgToSend.utf8)
let data = Data(buf)
peripheral.writeValue(data, for: fifoCharacteristic!, type: CBCharacteristicWriteType.withoutResponse)
print("\(message) sent")
commandname = message
}