Într-o tutorialul anterior, ați învățat cum să adăugați Bluetooth la o aplicație Particle Xenon. În acest fel, puteți controla LED-ul RGB de la o aplicație de testare precum nRF Connect sau Light Blue Explorer.
În această postare, vom face un pas mai departe. Vom dezvolta o aplicație Swift pentru a controla un LED Particle Mesh RGB. Dacă totul merge bine, ar trebui să aveți o aplicație de lucru în aproximativ 20 de minute!
Să începem.
Conţinut
Nu aveți timp chiar acum să citiți articolul complet?
Descărcați versiunea PDF aici.
Pregătirea
- Instalați Xcode. Puteți să-l descărcați din App Store de aici.
- De asemenea, veți avea nevoie de o autentificare Apple. Îmi folosesc adresa de e-mail iCloud. Puteți crea un cont nou în Xcode dacă nu aveți încă unul.
- Instalați fișierul Exemplu de cod RGB pe o placă de particule.
Creați proiectul
Odată ce totul este instalat, să trecem la lucrurile distractive!
Deschideți Xcode și accesați Fișier → Proiect nou.
Selectați Aplicație cu vizualizare unică.
Apoi actualizați fișierul Denumirea proiectului să fie pe placul tău. De asemenea, mi-am schimbat identificatorul organizației în com.jaredwolff
. Modificați-l după cum doriți!
Selectați o locație pentru ao salva.
Apoi găsiți-vă Info.plist.
Actualizați info.plist
prin adăugarea Privacy - Bluetooth Peripheral Usage Description
Descrierea pe care am ajuns să o folosesc a fost App uses Bluetooth to connect to the Particle Xenon RGB Example
Acest lucru vă permite să utilizați Bluetooth în aplicația dvs. dacă vreți vreodată să îl lansați.
Acum, să facem totul minim funcțional!
Minim funcțional
În continuare, vom obține o aplicație minim funcțională pentru a ne conecta și a face o descoperire de servicii. Cea mai mare parte a acțiunii se va întâmpla în ViewController.swift
.
Permite primul import CoreBluetooth
import CoreBluetooth
Acest lucru ne permite să controlăm funcționalitatea Bluetooth Low Energy din iOS. Atunci să adăugăm atât CBPeripheralDelegate
și CBCentralManagerDelegate
la ViewController
clasă.
class ViewController: UIViewController, CBPeripheralDelegate, CBCentralManagerDelegate {
Să creăm acum variabile private locale pentru a stoca managerul central real și perifericul. Le vom înființa în continuare momentan.
// Properties
private var centralManager: CBCentralManager!
private var peripheral: CBPeripheral!
În dumneavoastră viewDidLoad
funcție, să inițiem centralManager
centralManager = CBCentralManager(delegate: self, queue: nil)
Setare delegate: self
este important. În caz contrar, statul central nu se schimbă niciodată la pornire.
Înainte de a ajunge mai departe, să creăm un fișier separat și să-l numim ParticlePeripheral.swift
. Poate fi plasat oriunde, dar l-am plasat într-un „grup” separat numit Modele pentru mai târziu.
În interior vom crea câteva variabile publice care conțin UUID-urile pentru placa noastră de particule. Ar trebui să pară familiari!
import UIKit
import CoreBluetooth
class ParticlePeripheral: NSObject {
/// MARK: - Particle LED services and charcteristics Identifiers
public static let particleLEDServiceUUID = CBUUID.init(string: "b4250400-fb4b-4746-b2b0-93f0e61122c6")
public static let redLEDCharacteristicUUID = CBUUID.init(string: "b4250401-fb4b-4746-b2b0-93f0e61122c6")
public static let greenLEDCharacteristicUUID = CBUUID.init(string: "b4250402-fb4b-4746-b2b0-93f0e61122c6")
public static let blueLEDCharacteristicUUID = CBUUID.init(string: "b4250403-fb4b-4746-b2b0-93f0e61122c6")
}
Înapoi în ViewController.swift
să împărțim biții Bluetooth.
Biti Bluetooth
Tot ce are de-a face cu Bluetooth este bazat pe evenimente. Vom defini mai multe funcții care gestionează aceste evenimente. Iată cele importante:
centralManagerDidUpdateState
se actualizează când perifericul Bluetooth este pornit sau oprit. Se va declanșa când pornește prima aplicație, astfel încât să cunoașteți starea Bluetooth. De asemenea, începem scanarea aici.
centralManager
didDiscover
evenimentul apare atunci când primiți rezultatele scanării. Vom folosi acest lucru pentru a începe o conexiune.
centralManager
didConnect
evenimentul se declanșează odată ce dispozitivul este conectat. Vom începe descoperirea dispozitivului aici. Notă: Descoperirea dispozitivului este modul în care determinăm ce servicii și caracteristici sunt disponibile. Acesta este un mod bun de a confirma la ce tip de dispozitiv suntem conectați.
peripheral
didDiscoverServices
primul eveniment după ce toate serviciile au fost descoperite. Observați că am trecut de la centralManager
la peripheral
acum că suntem conectați. Vom începe descoperirea caracteristică aici. Vom folosi UUID-ul serviciului RGB ca țintă.
peripheral
didDiscoverCharacteristicsFor
evenimentul va furniza toate caracteristicile utilizând serviciul UUID furnizat. Acesta este ultimul pas al lanțului de a face o descoperire completă a dispozitivului. Este păros, dar trebuie făcut o singură dată în timpul fazei de conectare!
Definirea tuturor funcțiilor Bluetooth.
Acum că știm care sunt funcțiile care se declanșează evenimentele. Le vom defini în ordinea logică în care se întâmplă în timpul unui ciclu de conectare.
Mai întâi, vom defini centralManagerDidUpdateState
pentru a începe scanarea unui dispozitiv cu serviciul nostru cu particule RGB LED. Dacă Bluetooth nu este activat, nu va face nimic.
// If we're powered on, start scanning
func centralManagerDidUpdateState(_ central: CBCentralManager) {
print("Central state update")
if central.state != .poweredOn {
print("Central is not powered on")
} else {
print("Central scanning for", ParticlePeripheral.particleLEDServiceUUID);
centralManager.scanForPeripherals(withServices: [ParticlePeripheral.particleLEDServiceUUID],
options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
}
}
Definirea centralManager
didDiscover
este următorul nostru pas în acest proces. Știm că am găsit un dispozitiv dacă a avut loc acest eveniment.
// Handles the result of the scan
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
// We've found it so stop scan
self.centralManager.stopScan()
// Copy the peripheral instance
self.peripheral = peripheral
self.peripheral.delegate = self
// Connect!
self.centralManager.connect(self.peripheral, options: nil)
}
Deci, nu mai scanăm folosind self.centralManager.stopScan()
. Am setat peripheral
deci persistă prin intermediul aplicației. Apoi ne conectăm la acel dispozitiv folosind self.centralManager.connect
Odată conectat, trebuie să verificăm dacă lucrăm cu dispozitivul potrivit.
// The handler if we do connect succesfully
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
if peripheral == self.peripheral {
print("Connected to your Particle Board")
peripheral.discoverServices([ParticlePeripheral.particleLEDServiceUUID])
}
}
Prin compararea celor două periferice, vom cunoaște dispozitivul pe care l-am găsit mai devreme. Vom începe o descoperire de servicii folosind peripheral.discoverService
. Putem folosi ParticlePeripheral.particleLEDServiceUUID
ca parametru. În acest fel nu primim niciun serviciu de care nu ne pasă.
Odată ce terminăm serviciile de descoperire, vom primi un didDiscoverServices
eveniment. Iterăm prin toate serviciile „disponibile”. (Deși va exista doar unul!)
// Handles discovery event
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if let services = peripheral.services {
for service in services {
if service.uuid == ParticlePeripheral.particleLEDServiceUUID {
print("LED service found")
//Now kick off discovery of characteristics
peripheral.discoverCharacteristics([ParticlePeripheral.redLEDCharacteristicUUID,
ParticlePeripheral.greenLEDCharacteristicUUID,
ParticlePeripheral.blueLEDCharacteristicUUID], for: service)
return
}
}
}
}
În acest moment, aceasta este a treia oară când verificăm pentru a ne asigura că avem serviciul corect. Acest lucru devine mai util mai târziu, când există multe caracteristici și multe servicii.
Noi sunam peripheral.discoverCharacteristics
cu o serie de UUID-uri pentru caracteristicile pe care le căutăm. Acestea sunt toate UUID-urile pe care le-am definit ParticlePeripheral.swift
.
În cele din urmă, ne ocupăm de didDiscoverCharacteriscsFor
eveniment. Repetăm toate caracteristicile disponibile. Pe măsură ce iterăm, comparăm cu cele pe care le căutăm.
// Handling discovery of characteristics
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if let characteristics = service.characteristics {
for characteristic in characteristics {
if characteristic.uuid == ParticlePeripheral.redLEDCharacteristicUUID {
print("Red LED characteristic found")
} else if characteristic.uuid == ParticlePeripheral.greenLEDCharacteristicUUID {
print("Green LED characteristic found")
} else if characteristic.uuid == ParticlePeripheral.blueLEDCharacteristicUUID {
print("Blue LED characteristic found");
}
}
}
}
În acest moment suntem gata să facem o descoperire completă a dispozitivului dispozitivului nostru Particle Mesh. În secțiunea următoare vom testa ce avem pentru a ne asigura că lucrurile funcționează bine.
Testarea exemplului nostru minim
Înainte de a începe, dacă aveți probleme, am introdus câțiva pași de depanare în note de subsol.
Pentru a testa, va trebui să aveți un iPhone cu Bluetooth Low Energy. Majoritatea iPhone-urilor moderne o au. Ultimul iPhone care nu l-a avut, cred că a fost fie iPhone 4, fie 3G. (deci probabil esti bun)
Mai întâi, conectați-l la computer.
Mergeți în partea de sus a butoanelor de redare și oprire. Selectați dispozitivul țintă. În cazul meu mi-am ales telefonul (IPhone-ul lui Jared). De asemenea, puteți utiliza un iPad.
Atunci poți să lovești Comandă + R sau lovește asta Butonul Redare pentru a încărca aplicația pe telefon.
Asigurați-vă că aveți fila jurnal deschisă. Activați-l făcând clic pe butonul panoului inferior din colțul din dreapta sus.
Asigurați-vă că aveți o configurare a dispozitivului mesh și rulați exemplul de cod. Poti sa te duci la acest post pentru a-l obține. Amintiți-vă că placa Particle Mesh trebuie să ruleze dispozitivul OS 1.3.0 sau o versiune ulterioară pentru ca Bluetooth să funcționeze!
Odată ce firmware-ul și aplicația sunt încărcate, să verificăm ieșirea jurnalului.
Ar trebui să arate cam așa:
View loaded
Central state update
Central scanning for B4250400-FB4B-4746-B2B0-93F0E61122C6
Connected to your Particle Board
LED service found
Red LED characteristic found
Green LED characteristic found
Blue LED characteristic found
Aceasta înseamnă că telefonul dvs. s-a conectat, a găsit serviciul LED! De asemenea, caracteristicile descoperite sunt importante aici. Fără acestea nu am putea trimite date către dispozitivul mesh.
Următorul pas este crearea unor glisoare, astfel încât să putem actualiza valorile RGB din mers.
Glisați spre stânga. Glisați spre dreapta.
În continuare vom adăuga câteva elemente la Main.storyboard
. Deschis Main.storyboard
și faceți clic pe Vedere dedesubt Vizualizați controlerul.
Apoi faceți clic pe Bibliotecă buton. (Se pare că arta veche folosită de Apple pentru butonul de acasă)
Veți primi o fereastră pop-up cu toate opțiunile pe care le puteți insera în aplicația dvs.
Trageți trei Etichete și copiați trei Glisoare la viziunea ta.
Puteți face dublu clic pe etichete și le puteți redenumi pe măsură ce mergeți.
Dacă faceți clic și țineți apăsat, vor apărea unele instrumente de aliniere la îndemână. Vor ajunge chiar la centru!
Puteți, de asemenea, să le selectați pe toate și să le mutați împreună. Le vom alinia pe verticală și orizontală.
Pentru ca aceștia să rămână la mijloc, să eliminăm proprietatea de redimensionare automată. Apasă pe Pictogramă riglă în dreapta sus. Apoi faceți clic pe fiecare dintre bare roșii. Acest lucru vă va asigura că etichetele și glisoarele dvs. rămân pe ecran!
Apoi să facem clic pe Afișați editorul asistent buton. (Arată ca o diagramă Venn)
Notă: asigura-te ca ViewController.swift este deschis în Editorul Asistent.
Apoi sub /properties
secțiune, Faceți clic pe butonul Control și trageți glisorul roșu în codul tău.
Repetați cu toate celelalte. Asigurați-vă că le numiți altceva. Codul dvs. ar trebui să arate astfel când ați terminat:
// Properties
private var centralManager: CBCentralManager!
private var peripheral: CBPeripheral!
// Sliders
@IBOutlet weak var redSlider: UISlider!
@IBOutlet weak var greenSlider: UISlider!
@IBOutlet weak var blueSlider: UISlider!
Acest lucru ne permite să accesăm valoarea glisoarelor.
Apoi, să atașăm fișierul Valoare modificată eveniment pentru fiecare dintre glisoare. Click dreapta pe Red Slider în vizualizarea folderului.
Ar trebui să vă ofere câteva opțiuni pentru evenimente. Faceți clic și trageți fișierul Valoare modificată eveniment la codul dvs. Asigurați-vă că îl numiți ceva care are sens. obisnuiam RedSliderChanged pentru Glisorul Roșu.
Repetați încă două ori. Codul dvs. ar trebui să arate astfel la sfârșitul acestui pas:
@IBAction func RedSliderChanged(_ sender: Any) {
}
@IBAction func GreenSliderChanged(_ sender: Any) {
}
@IBAction func BlueSliderChanged(_ sender: Any) {
}
De asemenea, am selectat fiecare dintre glisoarele către și debifat Activat. În felul acesta nu le poți mișca. Le vom activa mai târziu în cod.
De asemenea, acesta este un moment minunat pentru a schimba valoarea maximă la 255. De asemenea, setați valoarea implicită valoare de la 0,5 la 0.
Înapoi în partea de sus a fișierului. Să creăm câteva variabile locale pentru fiecare dintre caracteristici. Le vom folosi astfel încât să putem scrie variabilele glisante pe placa Particle Mesh.
// Characteristics
private var redChar: CBCharacteristic?
private var greenChar: CBCharacteristic?
private var blueChar: CBCharacteristic?
Acum, să legăm totul!
În didDiscoverCharacteristicsFor
funcția de apel invers. Să atribuim acele caracteristici. De exemplu
if characteristic.uuid == ParticlePeripheral.redLEDCharacteristicUUID {
print("Red LED characteristic found")
redChar = characteristic
Pe măsură ce găsim fiecare caracteristică, putem activa și fiecare dintre glisoarele din același loc.
// Unmask red slider
redSlider.isEnabled = true
În cele din urmă didDiscoverCharacteristicsFor
ar trebui să arate ca:
// Handling discovery of characteristics
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if let characteristics = service.characteristics {
for characteristic in characteristics {
if characteristic.uuid == ParticlePeripheral.redLEDCharacteristicUUID {
print("Red LED characteristic found")
redChar = characteristic
redSlider.isEnabled = true
} else if characteristic.uuid == ParticlePeripheral.greenLEDCharacteristicUUID {
print("Green LED characteristic found")
greenChar = characteristic
greenSlider.isEnabled = true
} else if characteristic.uuid == ParticlePeripheral.blueLEDCharacteristicUUID {
print("Blue LED characteristic found");
blueChar = characteristic
blueSlider.isEnabled = true
}
}
}
}
Acum, să actualizăm RedSliderChanged
GreenSliderChanged
și BlueSliderChanged
funcții. Ceea ce vrem să facem aici este să actualizăm caracteristica asociată cu Changed
funcţie. Am creat o funcție separată numită writeLEDValueToChar
. Vom transmite caracteristica și datele.
private func writeLEDValueToChar( withCharacteristic characteristic: CBCharacteristic, withValue value: Data) {
// Check if it has the write property
if characteristic.properties.contains(.writeWithoutResponse) && peripheral != nil {
peripheral.writeValue(value, for: characteristic, type: .withoutResponse)
}
}
Acum adăugați un apel la writeLEDValueToChar
la fiecare dintre Changed
funcții. Va trebui să aruncați valoarea la a Uint8
. (Dispozitivul Particle Mesh așteaptă un număr nesemnat de 8 biți.)
@IBAction func RedSliderChanged(_ sender: Any) {
print("red:",redSlider.value);
let slider:UInt8 = UInt8(redSlider.value)
writeLEDValueToChar( withCharacteristic: redChar!, withValue: Data())
}
Repetați acest lucru pentru GreenSliderChanged
și BlueSliderChanged
. Asigurați-vă că v-ați schimbat red
la green
și blue
pentru fiecare!
În cele din urmă, pentru a menține lucrurile curate, am adăugat și o funcție care gestionează deconectările Bluetooth.
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
În interior, ar trebui să resetați starea glisoarelor la 0 și să le dezactivați.
if peripheral == self.peripheral {
print("Disconnected")
redSlider.isEnabled = false
greenSlider.isEnabled = false
blueSlider.isEnabled = false
redSlider.value = 0
greenSlider.value = 0
blueSlider.value = 0
Este o idee bună să resetați self.peripheral
până la zero, nu încercăm niciodată să scriem pe un dispozitiv fantomă.
self.peripheral = nil
În cele din urmă, pentru că ne-am deconectat, începeți din nou scanarea!
// Start scanning again
print("Central scanning for", ParticlePeripheral.particleLEDServiceUUID);
centralManager.scanForPeripherals(withServices: [ParticlePeripheral.particleLEDServiceUUID],
options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
}
Bine! Suntem aproape gata să testăm. Să trecem la următorul (și ultimul) pas.
Testați glisoarele.
Munca grea este făcută. Acum este timpul să te joci!
Cel mai simplu mod de a testa totul este să faceți clic pe butonul Redare în stânga sus sau în Comandă + R Comanda rapidă de la tastatură. Xcode va încărca aplicația pe telefon. Ar trebui să vedeți un ecran alb urmat de un ecran cu glisoarele dvs.!
Glisoarele ar trebui să rămână în gri până când sunt conectate la placa Particle Mesh. Puteți verifica ieșirea jurnalului dacă conexiunea a fost stabilită.
View loaded
Central state update
Central scanning for B4250400-FB4B-4746-B2B0-93F0E61122C6
Connected to your Particle Board
LED service found
Red LED characteristic found
Green LED characteristic found
Blue LED characteristic found
(Arată familiar? Suntem conectați!)
Dacă ați urmat totul perfect, ar trebui să puteți muta glisoarele. Mai bine, LED-ul RGB de pe placa Particle Mesh ar trebui să schimbe culoarea.
Concluzie
În acest articol ați învățat cum să vă conectați placa Particle Mesh și dispozitivul iOS prin Bluetooth. Am învățat cum să ne conectăm la fiecare dintre caracteristicile disponibile. În plus, creează o interfață curată pentru a face totul.
După cum vă puteți imagina, puteți merge pe gaura de iepure cu Bluetooth pe iOS. Urmează mai multe în următorul meu ghid: Ghidul final pentru plasă de particule. Abonații la lista mea au acces la conținutul de pre-lansare și o reducere la ieșire! Faceți clic aici pentru a vă înscrie.
Cod
Codul sursă complet este disponibil pe Github. Dacă vi se pare util, apăsați butonul stea. ⭐️
#Cea #mai #bună #metodă #creați #aplicație #Bluetooth #Swift #hardware #în #minute
Cea mai bună metodă: creați o aplicație Bluetooth Swift cu hardware în 20 de minute