SWIFT – BLE comunicaciones

¡Tengo una aplicación SWIFT que debe enviar un valor a mi Arduino con el módulo Bluetooth LowEnergy!

He hecho correctamente las partes de búsqueda y conexión, pero no puedo enviar y recibir ningún dato.

Aquí está mi código para obtener una lista de dispositivos BLE disponibles y poner todo esto en una vista de tabla, luego, después de hacer clic en una celda que la aplicación proporciona para conectar el dispositivo con ellos.

Todo esto funciona perfectamente pero no sé enviar por ejemplo un personaje “a” de la aplicación a BLE y ¡obtener la respuesta de Arduino a la aplicación!

import UIKit import CoreBluetooth class BluetoothList: UITableViewController,CBCentralManagerDelegate, CBPeripheralDelegate { var listValue = [Lista]() var Blue: CBCentralManager! var conn: CBPeripheral! var a: String! var char: CBCharacteristic! func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) { if (peripheral.name == a){ self.conn = peripheral self.conn.delegate = self Blue.stopScan() Blue.connectPeripheral(self.conn, options: nil) self.performSegueWithIdentifier("ConnectionSegue", sender: nil) } else{ listValue = [ Lista(Name: peripheral.name!, RSS: RSSI.stringValue) ] self.tableView.reloadData() } } func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) { peripheral.delegate = self peripheral.discoverServices(nil) } func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) { if let servicePeripheral = peripheral.services! as [CBService]!{ for service in servicePeripheral{ peripheral.discoverCharacteristics(nil, forService: service) } } } func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) { if let characterArray = service.characteristics! as [CBCharacteristic]!{ for cc in characterArray { if(cc.UUID.UUIDString == "FF05"){ print("OKOK") peripheral.readValueForCharacteristic(cc) } } } } func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { if (characteristic.UUID.UUIDString == "FF05"){ let value = UnsafePointer((characteristic.value?.bytes.memory)!) print("\(value)") } } func centralManagerDidUpdateState(central: CBCentralManager){ switch(central.state){ case .PoweredOn: Blue.scanForPeripheralsWithServices(nil, options:nil) print("Bluetooth is powered ON") case .PoweredOff: print("Bluetooth is powered OFF") case .Resetting: print("Bluetooth is resetting") case .Unauthorized: print("Bluetooth is unauthorized") case .Unknown: print("Bluetooth is unknown") case .Unsupported: print("Bluetooth is not supported") } } override func viewDidLoad() { super.viewDidLoad() Blue = CBCentralManager(delegate: self, queue: nil) } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let currentCell = tableView.cellForRowAtIndexPath(tableView.indexPathForSelectedRow!)! as UITableViewCell a = currentCell.textLabel?.text Blue = CBCentralManager(delegate: self, queue: nil) } override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } @IBAction func Reload_BTN(sender: AnyObject) { self.tableView.reloadData() } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.listValue.count } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cella = self.tableView.dequeueReusableCellWithIdentifier("Cella", forIndexPath: indexPath) let Lista = self.listValue[indexPath.row] cella.textLabel?.text = Lista.Name cella.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator return cella } 

El siguiente código es para Swift 3 (XCode 8 Beta 6). Es un ejemplo que utiliza los UUID estándar para puertos serie como los de algunos módulos comerciales. Entonces las declaraciones para el servicio y las características deberían verse así:

 private let UuidSerialService = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" private let UuidTx = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" private let UuidRx = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" 

Y luego, el método de su delegado para didDiscoverCharacteristic puede ser algo como esto:

 public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { if let characteristics = service.characteristics { for characteristic in characteristics { // Tx: if characteristic.uuid == CBUUID(string: UuidTx) { print("Tx char found: \(characteristic.uuid)") txCharacteristic = characteristic } // Rx: if characteristic.uuid == CBUUID(string: UuidRx) { rxCharacteristic = characteristic if let rxCharacteristic = rxCharacteristic { print("Rx char found: \(characteristic.uuid)") serialPortPeripheral?.setNotifyValue(true, for: rxCharacteristic) } } } } } 

Para escribir en el Tx, algo así como los siguientes trabajos, donde el valor es un [UInt8]:

 let data = NSData(bytes: value, length: value.count) serialPortPeripheral?.writeValue(data as Data, for: txCharacteristic, type: CBCharacteristicWriteType.withResponse) 

¿Leyendo?

 public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { let rxData = characteristic.value if let rxData = rxData { let numberOfBytes = rxData.count var rxByteArray = [UInt8](repeating: 0, count: numberOfBytes) (rxData as NSData).getBytes(&rxByteArray, length: numberOfBytes) print(rxByteArray) } } 

Finalmente, si no sabe o no está seguro sobre los servicios y características de su dispositivo BLE, puede buscar una aplicación iOS gratuita llamada “LightBlue”. Descubrirá un dispositivo y, si se conecta, enumerará todos los servicios y características. Solo tenga en cuenta que obviamente su aplicación no podrá acceder al hardware BLE mientras LightBlue esté conectado a su dispositivo.