究極のハウツー:20 分でハードウェアを使用して Bluetooth Swift アプリを構築する
前のチュートリアルでは、Bluetooth を Particle Xenon アプリケーションに追加する方法を学習しました。そうすれば、nRF Connect や Light Blue Explorer などのテスト アプリからオンボード RGB LED を制御できます。
この投稿では、さらに一歩進めます。パーティクル メッシュ RGB LED を制御する Swift アプリを開発します。すべてがうまくいけば、約 20 分でアプリが動作するはずです!
始めましょう。
今すぐ記事全体を読む時間がありませんか?
ここから PDF 版をダウンロードしてください。
セットアップ中
- Xcode をインストールします。こちらの App Store からダウンロードできます。
- 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
でした
これにより、アプリをリリースしたい場合に、アプリで Bluetooth を使用できるようになります。
それでは、すべての機能を最小限に抑えましょう!
最低限の機能
次に、接続してサービス検出を行うための最小限の機能を備えたアプリを取得します。ほとんどのアクションは 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
という名前にしましょう .どこにでも配置できますが、私は Models という別の「グループ」に配置しました
内部で、パーティクル ボードの 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 ビットをつなぎ合わせましょう。
Bluetooth ビット
Bluetooth で行うことはすべてイベント ベースです。これらのイベントを処理するいくつかの関数を定義します。重要なものは次のとおりです。
centralManagerDidUpdateState
Bluetooth ペリフェラルがオンまたはオフに切り替えられると更新されます。アプリが最初に起動したときに起動するので、Bluetooth の状態がわかります。ここでもスキャンを開始します。
centralManager
didDiscover
スキャン結果を受け取るとイベントが発生します。これを使用して接続を開始します。
centralManager
didConnect
デバイスが接続されると、イベントが発生します。ここでデバイスの検出を開始します。 注: デバイス検出は、利用可能なサービスと特性を判断する方法です。これは、接続しているデバイスのタイプを確認する良い方法です。
peripheral
didDiscoverServices
すべてのサービスが検出されたら、最初にイベントを実行します。 centralManager
から切り替えたことに注意してください peripheral
へ つながった今。ここから特徴的な発見を始めます。 RGB サービスの UUID をターゲットとして使用します。
peripheral
didDiscoverCharacteristicsFor
イベントは、提供されたサービス UUID を使用してすべての特性を提供します。これは、完全なデバイス検出を行うチェーンの最後のステップです。面倒ですが、接続フェーズ中に 1 回だけ実行する必要があります!
すべての Bluetooth 機能を定義しています。
これで、トリガーされる関数イベントが何であるかがわかりました。接続サイクル中に発生する論理的な順序で定義します。
まず、centralManagerDidUpdateState
を定義します。 Particle RGB LED Service を使用してデバイスのスキャンを開始します。 Bluetooth が有効になっていない場合、何もしません。
// 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])
}
}
2 つの周辺機器を比較すると、以前に見つけたデバイスであることがわかります。 peripheral.discoverService
を使用してサービスの検出を開始します . ParticlePeripheral.particleLEDServiceUUID
を使用できます パラメータとして。そうすれば、関心のないサービスを取得することはありません。
サービスの検出が完了すると、didDiscoverServices
が返されます イベント。すべての「利用可能な」サービスを反復処理します。 (ただし、1 つしかありません!)
// 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
}
}
}
}
この時点で、正しいサービスを提供していることを確認するのは 3 回目です。これは、多くの特性と多くのサービスがある場合に、後でより便利になります.
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");
}
}
}
}
この時点で、パーティクル メッシュ デバイスの完全なデバイス検出を行う準備が整いました。次のセクションでは、問題なく動作することを確認するために必要なものをテストします。
最小限の例をテストする
開始する前に、問題が発生した場合は、脚注にトラブルシューティングの手順をいくつか記載しました。
テストするには、Bluetooth Low Energy を搭載した 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 の下。
ライブラリをクリックします ボタン。 (ホームボタンにAppleが使っていた古いアートのようです)
アプリに挿入できるすべての選択肢を含むポップアップが表示されます。
3 つの ラベル をドラッグします 3 つの Slider をコピーします
ラベルをダブルクリックして、必要に応じて名前を変更できます。
クリックしたままにすると、便利な配置ツールがポップアップ表示されます。中央にスナップすることもできます!
それらをすべて選択してまとめて移動することもできます。それらを縦横に並べます。
それらが真ん中に留まるように、自動サイズ変更プロパティを削除しましょう。 定規アイコン をクリックします 右上にあります。次に、各赤いバーをクリックします .これにより、ラベルとスライダーが画面に表示されたままになります!
次に、[アシスタント エディタを表示] をクリックしましょう。 ボタン。 (ベン図のように見えます)
注: 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!
これにより、スライダーの値にアクセスできます。
次に、Value Changed を添付しましょう 各スライダーへのイベント。 右クリック フォルダ ビューの赤いスライダー
イベントのいくつかのオプションを提供する必要があります。 変更された値をクリックしてドラッグします イベントをコードに追加します。意味のある名前を付けてください。 RedSliderChanged を使用しました レッドスライダーのために。
さらに2回繰り返します。このステップの最後で、コードは次のようになります:
@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
にキャストする必要があります . (パーティクル メッシュ デバイスは、符号なしの 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
最後に、すっきりさせるために、Bluetooth の切断を処理する関数も追加しました。
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
をリセットすることをお勧めします この方法で nil にすると、ファントム デバイスに書き込もうとすることはありません。
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 の色が変わるはずです。
結論
この記事では、パーティクル メッシュ ボードと iOS デバイスを Bluetooth 経由で接続する方法を学習しました。利用可能な各特性に接続する方法を学びました。さらに、すべてを実行するためのクリーンなインターフェイスを作成します。
ご想像のとおり、iOS で Bluetooth を使用してうさぎの穴を下ることができます。次のガイドでは、さらに詳しく説明します:パーティクル メッシュの究極のガイド。 私のリストの購読者は、発売前のコンテンツにアクセスし、発売時に割引を受けることができます!ここをクリックしてサインアップしてください。
コード
完全なソース コードは Github で入手できます。便利だと思ったら、スターボタンを押してください。 ⭐️
-
究極のハウツー:20 分でハードウェアを使用して Bluetooth Swift アプリを構築する
前のチュートリアルでは、Bluetooth を Particle Xenon アプリケーションに追加する方法を学習しました。そうすれば、nRF Connect や Light Blue Explorer などのテスト アプリからオンボード RGB LED を制御できます。 この投稿では、さらに一歩進めます。パーティクル メッシュ RGB LED を制御する Swift アプリを開発します。すべてがうまくいけば、約 20 分でアプリが動作するはずです! 始めましょう。 今すぐ記事全体を読む時間がありませんか? ここから PDF 版をダウンロードしてください。 セットアップ中 Xcode
-
アプリで先延ばしを避ける方法は?
私たちはしばしば、いずれかのソーシャル メディア アプリを利用しています。それは私たちの生活の不可欠な部分になっており、必要なすべてのタスクを圧倒しているように見えることもあります.生活からスマートフォンを取り除いたら、人々がどのように見えるか見てみましょう。 物事を遅らせたり延期したりすることは大きな問題であり、この習慣では目標を達成することは不可能に思えます.これは、私たちの日常生活におけるスマートフォンの使用の増加に伴い、より大きな問題と見なされています.驚いたことに、先延ばしに打ち勝つのに役立つアプリがいくつかあるため、解決策は携帯電話にもあります。 私たちは、スマートフォンへの依