takashiskiのブログ

覚書の殴り書き

iOSやAndroid上のUnityとBLEで繋がるセンサー付コントローラを作る

概要

Unity製のiOS,AndroidアプリとBluetoothで繋がる自作専用ハードウェアを作りたい。 と言うシチュエーションは最近増えてきました。こうした場合はBLE(Blutooth Low Energy)経由で接続することが多いです。

過去の例だと BLE NANO RedBearLab BLE Nanoキット V2 - スイッチサイエンスiOSのネイティブ実装例が見つかります。

しかし現在はWifi+Blutoothに両対応した安価なESP32ボードが手に入ります。 もし安価なESP32ベースで専用BTコントローラを仕立てて、iOSAndroidと(Unityから)繋ぐことが出来ると、変なゲームやインスタレーションが作れそうです。

本エントリではUnity製アプリ内でESP32に繋いだジャイロセンサの値を反映する。というサンプルを作成します。 (端末の近くにある該当のESP32を名前決め打ちで引当て(Scan)、ESP32を発見したら自動で接続を行い、ESP32はデータをiOS,Androidに送りつけて、iOS,Android端末側で画面に表示する、というのをやります)

BLE自体の仕組みについては くらげのIoTテクノロジーさんが詳しいので、一読をおすすめします。

クラゲのIoTテクノロジー

実例

IMUからQuaternionを受け取ってCube回してます。

takashiski.hatenablog.com

本エントリで解説しないこと

お願い

  • 手元にiOS開発環境がないのでiOSの動作確認がとれません。動いたら教えてください。

執筆時の環境

  • Windows10 april 2018
  • Android8.0(XperiaXCompact)
  • Unity2018 1.0b13
  • ArduinoIDE1.8.0

必要なもの

  • ESP32 dev kit
  • microUSBケーブル
  • 後述のアセット

amazonから買うときは、primeのものを買うようにしましょう。そうでないと中国発送で届くまでに2週間かかります。

amazon以外だと秋月電子あたりで買えるんじゃないでしょうか。

準備

  1. PCにUnityのandroid/iOSのビルド環境を用意する
  2. PCにESP32の開発環境入れる
  3. BLEをUnityのiOS,Androidで動かすための ネイティブプラグイン アセットを買う

PCにUnityのandroid/iOSのビルド環境を用意する

androidに関しては参考文献を参照してください。 参考文献通りに進めれば基本的に問題ないですが、一点変更がありました。

android studioインストーラのインストール項目のandroid SDKをチェックしていることを確認するよう書いてありますが、2018/05/15次点では一覧に表示されませんでした。

無視してそのままandroid studioをインストールしたのちにandroid studioを起動すると「SDKが見つからなかった」と表示がでてそのまま半強制的にSDKをインストールすることになりました。(r25 系である必要がありそうです)

https://qiita.com/relzx/items/7f8e7817c9edd11c5023qiita.com

framesynthesis.jp

PCにESP32の開発環境を入れる

別記事に書いてあるので参考にしてください。

takashiski.hatenablog.com

基本的に公式に書いてある通りの手順に沿って手を動かすだけです。

github.com

BLEをUnityのiOS,Androidで動かすための ネイティブプラグイン アセットを買う

買ってください。20ドルです。

Unity自体はBLEの処理を持っておらず、デバイスごとにネイティブで書く必要があります。

以下のアセットを購入すると、20ドルでiOS, tvOS, androidでBLEが取り扱えるようになります。

ネイティブの処理を自前で書いて連携できるなら買わなくても大丈夫です。がんばってゴリゴリ書いてください。

実装方針・概要確認

この記事では動確程度のため、サンプルコードを最小限の改変で動かすことを目標にします。

Unity側のBLEアセットのSimpleTestというサンプルシーンがScanとnotifyの受け取り・表示をするので使います。

ESP32側はSimpleTestにあうように実装を決めます。BLE_notifyというサンプルスケッチを使います。

SimpleTestがやってること

  1. BLEデバイスをScanする
  2. Scanで見つかったデバイスのうち識別情報が一致したデバイスに自動的に接続する
  3. 接続したデバイスから受け取ったバイト列を表示する(BLE notify)

BLE_notify.inoがやっていること

  • 次の処理を繰り返す
    1. notifyで1バイトの変数valueの値を投げる
    2. valueをインクリメントをする
  • 受信デバイスから見ると、0, 1, 2, ..., FF, 0, 1, ....という順番でデータが飛んでくる

やらなければならないこと

識別情報を一致させないといけません。一致さえさせれば動作確認は取れます。

今回識別情報と呼称しているのは以下の三点の組です。

  • Device Name
  • Service UUID
  • Characteristic UUID

UUIDとして今回は16bit UUIDと呼ばれるHEX4桁のものを利用します。 実際利用する際は16bitではなく、以下のXXXXに16bit UUIDを埋め込んだほとんどが共通部のUUIDを埋め込みます。

//16bit
XXXX

//full length
0000XXXX-0000-1000-8000-00805F9B34FB

今回はそれぞれ以下のように設定します

  • Device Name : MyESP32
  • Service UUID : 2220
  • Characteristic UUID : 2221

ESP32

ファイル > スケッチ例 > ESP32 BLE Arduino > BLE_notifyを開きます。 今後も改造することとしますので、適当な名前で別名保存してください。私はBLE_Unity.inoにします。

変更箇所は35, 36行目です。

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define SERVICE_UUID        "00002220-0000-1000-8000-00805F9B34FB"
#define CHARACTERISTIC_UUID "00002221-0000-1000-8000-00805F9B34FB"

Device NameはデフォルトがMyESP32なので変更は不要です。

これをビルド・書き込みしたら完了です。 そのまま電源を入れたままにしておけば、Unity側のインストールが終わり次第すぐに確認できます。

Unity

新規プロジェクトを作成し、android(もしくはiOS)をビルド対象にして、その他の設定を済ませてください。

アセット Bluetooth LE for iOS, tvOS, androidをインポートします。

Example>SimpleTest>SimpleTestシーンを開いてください。

ヒエラルキーのMain cameraを選択し、インスペクターの項目を設定します。Device Name以外は初期値を使っています。

  • Device Name : MyESP32
  • Service UUID : 2220
  • Subscrive Characteristic UUID : 2221
  • Write Characteristic UUID : 2222(今回は使わないのでHEXなら何でもよい)

SimpleTest.csを開いて以下の項目を編集します。具体的にはWriteCharacteristicを使わないように書き換えます。

  • 159行目 if文
if (_foundSubscribeID && _foundWriteID)
if (_foundSubscribeID)

もしくはWriteCharacteristicを使って評価してる部分を削除すればよいです。

最後に、スマートフォンをPCにデバッグモードで接続して、ビルドアンドランで書き込みましょう。

ESP32の準備が済んで電源がはいっているのであれば、起動次第すぐに見つけられて、数値がインクリメントされ続ける様子が見れるはずです。

まとめ

便利なアセットと便利なBTモジュール付きマイコンを使うことで、BLEでデータのやり取りができました。

notifyではデフォルトだと20バイトのデータが送れるそうです。今回は1バイトのみですが、任意バイトをおくって表示するなどしてみてはいかがでしょうか。

発展として、ESP32でセンサの値を読み取り、Unityに投げてUnity内のオブジェクトに反映させる、というのをこのあとやります。

補足

コントローラに相当するESP32側でセンサーやボタンの値を監視して、変化があった時だけ接続先の iOS,Android端末にデータを送る、という事を実現するためにBluetooth LEのnotifyを使います。 http://jellyware.jp/kurage/bluejelly/notify.html

参考文献

Unity

https://qiita.com/relzx/items/7f8e7817c9edd11c5023qiita.com

framesynthesis.jp

nn-hokuson.hatenablog.com

https://forum.unity.com/threads/build-failure-unable-to-retrieve-device-properties-in-unity-4-2-1.213178/

answers.unity.com

ESP32

yegang.hatenablog.com

BLE

jellyware.jp

謝辞

記事の内容をよくするためにご意見いただいたようてんさんとizmさんに感謝を申し上げます。