이전 자습서에서 Bluetooth를 Particle Xenon 응용 프로그램에 추가하는 방법을 배웠습니다. 그렇게 하면 nRF Connect 또는 Light Blue Explorer와 같은 테스트 앱에서 온보드 RGB LED를 제어할 수 있습니다.
이 포스트에서 우리는 한 단계 더 나아갈 것입니다. 파티클 메시 RGB led를 제어하는 Swift 앱을 개발할 것입니다. 모든 것이 순조롭게 진행된다면 약 20분 안에 앱이 작동할 것입니다!
시작하겠습니다.
지금 전체 기사를 읽을 시간이 없으신가요?
여기에서 PDF 버전을 다운로드하십시오.
설정하기
- Xcode를 설치합니다. 여기 앱 스토어에서 다운로드할 수 있습니다.
- Apple 로그인도 필요합니다. 저는 iCloud 이메일을 사용합니다. 아직 계정이 없는 경우 Xcode 내에서 새 계정을 만들 수 있습니다.
- 파티클 메시 보드에 RGB 예제 코드를 설치합니다.
프로젝트 생성
모든 것이 설치되면 재미있는 콘텐츠로 이동합니다!
Xcode를 열고 파일 → 새 프로젝트로 이동합니다.
싱글 뷰 앱을 선택합니다.
그런 다음 프로젝트 이름을 업데이트합니다. 당신의 취향에. 조직 식별자도 com.jaredwolff
로 변경했습니다. . 필요에 따라 수정하세요!
저장할 위치를 선택하세요.
다음으로 Info.plist를 찾습니다.
info.plist
업데이트 Privacy - Bluetooth Peripheral Usage Description
을 추가하여
내가 사용한 설명은 App uses Bluetooth to connect to the Particle Xenon RGB Example
이었습니다.
이렇게 하면 앱에서 블루투스를 출시하려는 경우 사용할 수 있습니다.
이제 최소한의 기능만 갖추도록 합시다!
최소 기능
다음으로 연결하고 서비스 검색을 수행하는 최소한의 기능 앱을 얻습니다. 대부분의 작업은 ViewController.swift
에서 발생합니다. .
먼저 CoreBluetooth
을 가져올 수 있습니다.
import CoreBluetooth
이를 통해 iOS에서 Bluetooth Low Energy 기능을 제어할 수 있습니다. 그런 다음 CBPeripheralDelegate
및 CBCentralManagerDelegate
ViewController
로 수업.
class ViewController: UIViewController, CBPeripheralDelegate, CBCentralManagerDelegate {
이제 실제 중앙 관리자와 주변 장치를 저장할 로컬 개인 변수를 만들어 보겠습니다. 잠시 후에 추가로 설정하겠습니다.
// Properties
private var centralManager: CBCentralManager!
private var peripheral: CBPeripheral!
viewDidLoad
에서 함수, centralManager
을 초기화합시다.
centralManager = CBCentralManager(delegate: self, queue: nil)
delegate: self
설정 중요하다. 그렇지 않으면 시작 시 중앙 상태가 변경되지 않습니다.
더 진행하기 전에 별도의 파일을 만들어 ParticlePeripheral.swift
이라고 부르겠습니다. . 어디에나 배치할 수 있지만 모델이라는 별도의 '그룹'에 배치했습니다. 나중을 위해.
내부에서 파티클 보드의 UUID를 포함하는 몇 가지 공용 변수를 만듭니다. 그들은 친숙해 보일 것입니다!
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")
}
ViewController.swift
으로 돌아가기 Bluetooth 비트를 결합해 봅시다.
블루투스 비트
블루투스와 관련된 모든 것은 이벤트 기반입니다. 이러한 이벤트를 처리하는 여러 함수를 정의할 것입니다. 다음은 중요한 사항입니다.
centralManagerDidUpdateState
Bluetooth 주변 장치가 켜지거나 꺼지면 업데이트됩니다. 앱이 처음 시작될 때 실행되어 블루투스 상태를 알 수 있습니다. 여기에서도 스캔을 시작합니다.
centralManager
didDiscover
스캔 결과를 받으면 이벤트가 발생합니다. 이것을 사용하여 연결을 시작합니다.
centralManager
didConnect
장치가 연결되면 이벤트가 발생합니다. 여기서 장치 검색을 시작하겠습니다. 참고: 장치 검색은 사용 가능한 서비스와 특성을 결정하는 방법입니다. 이것은 우리가 어떤 유형의 기기에 연결되어 있는지 확인하는 좋은 방법입니다.
peripheral
didDiscoverServices
모든 서비스가 검색되면 이벤트가 먼저 발생합니다. centralManager
에서 변경되었음을 알 수 있습니다. peripheral
으로 이제 연결되었습니다. 여기에서 특성 발견을 시작하겠습니다. RGB 서비스 UUID를 대상으로 사용할 것입니다.
peripheral
didDiscoverCharacteristicsFor
이벤트는 제공된 서비스 UUID를 사용하여 모든 특성을 제공합니다. 이것은 전체 장치 검색을 수행하는 체인의 마지막 단계입니다. 털이 많지만 연결 단계에서 한 번만 하면 됩니다!
모든 블루투스 기능 정의.
이제 트리거되는 함수 이벤트가 무엇인지 알았습니다. 연결 주기 동안 발생하는 논리적 순서로 정의하겠습니다.
먼저 centralManagerDidUpdateState
을 정의합니다. Particle RGB LED 서비스로 장치 스캔을 시작합니다. 블루투스가 활성화되어 있지 않으면 아무 작업도 수행하지 않습니다.
// 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])
}
}
centralManager
정의 didDiscover
프로세스의 다음 단계입니다. 이 이벤트가 발생한 경우 장치를 발견했다는 것을 알고 있습니다.
// 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)
}
따라서 self.centralManager.stopScan()
을 사용하여 스캔을 중지합니다. . peripheral
를 설정합니다. 그래서 앱을 통해 지속됩니다. 그런 다음 self.centralManager.connect
을 사용하여 해당 장치에 연결합니다.
연결되면 올바른 장치로 작업하고 있는지 다시 확인해야 합니다.
// 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])
}
}
두 주변 장치를 비교하여 이전에 찾은 장치를 알 수 있습니다. peripheral.discoverService
을 사용하여 서비스 검색을 시작합니다. . ParticlePeripheral.particleLEDServiceUUID
를 사용할 수 있습니다. 매개변수로. 그렇게 하면 관심 없는 서비스는 선택하지 않습니다.
서비스 검색을 마치면 didDiscoverServices
을 받게 됩니다. 이벤트. 우리는 모든 "사용 가능한" 서비스를 반복합니다. (하나뿐이겠지만!)
// 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
}
}
}
}
이 시점에서 우리가 올바른 서비스를 제공하는지 확인하는 것은 세 번째입니다. 이것은 나중에 많은 특성과 많은 서비스가 있을 때 더 편리합니다.
우리는 peripheral.discoverCharacteristics
이라고 부릅니다. 우리가 찾고 있는 특성에 대한 UUID 배열로. ParticlePeripheral.swift
에서 정의한 모든 UUID입니다. .
마지막으로 didDiscoverCharacteriscsFor
이벤트. 사용 가능한 모든 특성을 반복합니다. 반복하면서 찾고 있는 것과 비교합니다.
// 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");
}
}
}
}
이 시점에서 파티클 메시 장치의 전체 장치 검색을 수행할 준비가 되었습니다. 다음 섹션에서는 제대로 작동하는지 확인하기 위해 무엇을 테스트해야 하는지 알아보겠습니다.
최소한의 예제 테스트
시작하기 전에 문제가 발생하는 경우 각주에 몇 가지 문제 해결 단계를 넣어두었습니다.
테스트하려면 저전력 블루투스 기능이 있는 iPhone이 있어야 합니다. 대부분의 최신 iPhone에는 이 기능이 있습니다. 마지막으로 iPhone이 없는 것은 iPhone 4 또는 3G라고 생각합니다. (그래서 당신은 좋은 것 같습니다)
먼저 컴퓨터에 연결합니다.
재생 및 중지 버튼으로 상단으로 이동합니다. 대상 장치를 선택하십시오. 제 경우에는 휴대전화(Jared의 iPhone ). iPad를 사용할 수도 있습니다.
그런 다음 Command + R을 누를 수 있습니다. 또는 재생 버튼을 누르세요. 휴대전화에 앱을 로드합니다.
로그 탭이 열려 있는지 확인하십시오. 오른쪽 상단 모서리에 있는 하단 창 버튼을 클릭하여 활성화합니다.
메쉬 장치가 설정되어 있고 예제 코드를 실행 중인지 확인하십시오. 이 포스트로 가시면 받으실 수 있습니다. Bluetooth가 작동하려면 파티클 메시 보드에서 장치 OS 1.3.0 이상을 실행해야 합니다.
펌웨어와 앱이 모두 로드되면 로그 출력을 확인해보자.
다음과 같아야 합니다.
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
이것은 귀하의 전화가 연결되었음을 의미합니다. LED 서비스를 찾았습니다! 여기서도 발견되는 특성이 중요합니다. 그것들이 없으면 메쉬 장치로 데이터를 보낼 수 없습니다.
다음 단계는 RGB 값을 즉시 업데이트할 수 있도록 슬라이더를 만드는 것입니다.
왼쪽으로 슬라이드합니다. 오른쪽으로 슬라이드하세요.
다음으로 Main.storyboard
에 몇 가지 요소를 추가합니다. . Main.storyboard
열기 보기를 클릭합니다. View Controller 아래에 있습니다.
그런 다음 라이브러리를 클릭합니다. 단추. (애플이 홈 버튼에 사용했던 오래된 아트처럼 보입니다.)
앱에 삽입할 수 있는 모든 선택 항목이 포함된 팝업이 표시됩니다.
세 개의 라벨 드래그 3개의 슬라이더 복사 당신의 보기에.
레이블을 두 번 클릭하고 이동하면서 이름을 바꿀 수 있습니다.
클릭하고 있으면 편리한 정렬 도구가 나타납니다. 중앙에 맞추기도 합니다!
모두 선택하여 함께 이동할 수도 있습니다. 세로 및 가로로 정렬하겠습니다.
중간에 머물 수 있도록 autoresizing 속성을 제거합시다. 자 아이콘을 클릭합니다. 오른쪽 상단에 있습니다. 그런 다음 각 빨간색 막대를 클릭합니다. . 이렇게 하면 레이블과 슬라이더가 화면에 유지됩니다!
다음으로 어시스턴트 편집기 표시를 클릭합니다. 단추. (벤 다이어그램처럼 보입니다)
참고: ViewController.swift 어시스턴트 편집기에서 열려 있습니다.
그런 다음 /properties
아래 섹션, Control-클릭 및 드래그 빨간색 슬라이더 당신의 코드에.
다른 모든 것들과 함께 반복하십시오. 이름을 다르게 지정하십시오. 완료되면 코드가 다음과 같아야 합니다.
// 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!
이를 통해 슬라이더 값에 액세스할 수 있습니다.
다음으로 변경된 값을 첨부하겠습니다. 각 슬라이더에 이벤트. 오른쪽 클릭 폴더 보기의 빨간색 슬라이더에서
이벤트에 대한 몇 가지 옵션을 제공해야 합니다. 변경된 값을 클릭하고 드래그합니다. 귀하의 코드에 이벤트. 의미가 있는 이름을 지정하십시오. RedSliderChanged를 사용했습니다. 빨간 슬라이더를 위해.
두 번 더 반복합니다. 이 단계가 끝나면 코드가 다음과 같아야 합니다.
@IBAction func RedSliderChanged(_ sender: Any) {
}
@IBAction func GreenSliderChanged(_ sender: Any) {
}
@IBAction func BlueSliderChanged(_ sender: Any) {
}
또한 각 슬라이더를 선택하고 활성화됨을 선택 취소했습니다. . 그렇게 하면 그들을 움직일 수 없습니다. 나중에 코드에서 활성화하겠습니다.
또한 지금은 최대값을 255로 변경하기에 좋은 시기입니다. . 또한 기본 값을 0.5에서 0으로 설정합니다.
파일 맨 위로 돌아갑니다. 각 특성에 대한 일부 지역 변수를 생성해 보겠습니다. 파티클 메시 보드에 슬라이더 변수를 쓸 수 있도록 이것을 사용할 것입니다.
// Characteristics
private var redChar: CBCharacteristic?
private var greenChar: CBCharacteristic?
private var blueChar: CBCharacteristic?
이제 모든 것을 하나로 묶자!
didDiscoverCharacteristicsFor
에서 콜백 함수. 그 특성을 할당합시다. 예를 들어
if characteristic.uuid == ParticlePeripheral.redLEDCharacteristicUUID {
print("Red LED characteristic found")
redChar = characteristic
각 특성을 찾으면 같은 지점에서 각 슬라이더를 활성화할 수도 있습니다.
// Unmask red slider
redSlider.isEnabled = true
결국 didDiscoverCharacteristicsFor
다음과 같아야 합니다.
// 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
}
}
}
}
이제 RedSliderChanged
을 업데이트하겠습니다. GreenSliderChanged
및 BlueSliderChanged
기능. 여기서 우리가 하고자 하는 것은 Changed
와 관련된 특성을 업데이트하는 것입니다. 기능. writeLEDValueToChar
라는 별도의 함수를 만들었습니다. . 특성과 데이터를 전달하겠습니다.
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)
}
}
이제 writeLEDValueToChar
에 대한 호출을 추가합니다. 각 Changed
기능. 값을 Uint8
로 캐스팅해야 합니다. . (Particle Mesh 장치는 부호 없는 8비트 숫자를 예상합니다.)
@IBAction func RedSliderChanged(_ sender: Any) {
print("red:",redSlider.value);
let slider:UInt8 = UInt8(redSlider.value)
writeLEDValueToChar( withCharacteristic: redChar!, withValue: Data([slider]))
}
GreenSliderChanged
에 대해 이 작업을 반복합니다. 및 BlueSliderChanged
. red
를 변경했는지 확인하세요. green
로 및 blue
각각!
마지막으로 깔끔하게 유지하기 위해 블루투스 연결 해제를 처리하는 기능도 추가했습니다.
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
내부에서 슬라이더의 상태를 0으로 재설정하고 비활성화해야 합니다.
if peripheral == self.peripheral {
print("Disconnected")
redSlider.isEnabled = false
greenSlider.isEnabled = false
blueSlider.isEnabled = false
redSlider.value = 0
greenSlider.value = 0
blueSlider.value = 0
self.peripheral
을 재설정하는 것이 좋습니다. 그런 식으로 우리는 팬텀 장치에 쓰기를 시도하지 않습니다.
self.peripheral = nil
마지막으로 연결이 끊어졌으므로 스캔을 다시 시작하십시오!
// Start scanning again
print("Central scanning for", ParticlePeripheral.particleLEDServiceUUID);
centralManager.scanForPeripherals(withServices: [ParticlePeripheral.particleLEDServiceUUID],
options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
}
괜찮은! 테스트할 준비가 되었습니다. 다음(그리고 마지막) 단계로 넘어갑시다.
슬라이더를 테스트합니다.
힘든 작업이 완료되었습니다. 이제 플레이할 시간입니다!
모든 것을 테스트하는 가장 쉬운 방법은 재생 버튼을 클릭하는 것입니다. 왼쪽 상단 또는 Command + R 키보드 단축키. Xcode가 휴대전화에 앱을 로드합니다. 슬라이더가 있는 화면에 의해 진행되는 흰색 화면이 표시되어야 합니다!
슬라이더는 파티클 메시 보드에 연결될 때까지 회색으로 유지되어야 합니다. 연결이 완료되면 로그 출력을 확인할 수 있습니다.
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
(익숙해 보이죠? 우리는 연결되어 있습니다!)
모든 것을 완벽하게 따랐다면 슬라이더를 움직일 수 있어야 합니다. 더 좋은 점은 파티클 메시 보드의 RGB LED가 색상을 변경해야 한다는 것입니다.
결론
이 기사에서는 Bluetooth를 통해 파티클 메시 보드와 iOS 장치를 연결하는 방법을 배웠습니다. 사용 가능한 각 특성에 연결하는 방법을 배웠습니다. 또한 무엇보다도 모든 작업을 수행할 수 있는 깔끔한 인터페이스를 만드세요.
상상할 수 있듯이 iOS에서 Bluetooth를 사용하면 토끼굴로 들어갈 수 있습니다. 앞으로 나올 가이드인 파티클 메시에 대한 궁극적인 가이드에 더 많은 내용이 있습니다. 내 목록의 구독자는 사전 출시 콘텐츠에 액세스할 수 있으며 출시 시 할인을 받을 수 있습니다! 여기를 클릭하여 가입하세요.
코드
전체 소스 코드는 Github에서 사용할 수 있습니다. 유용하다고 생각되면 별 버튼을 누르십시오. ⭐️