CodeSandbox で BLE 接続アプリのテンプレートを作ってみました
最近 CodeSandbox を利用し始めたのですが、「Web Bluetooth も使えるかな?」と試してみたところ使えるようでしたので、 BLE 接続を簡単に試せるようなテンプレート(BleEz)を作成してみました。
これを利用すれば、ウェブブラウザだけでも以下のような簡易モニターを短時間で作成できるようになるのでないかと思います。
2020-09-25 追記: テンプレートにライセンスファイル等を追加しました。
利用例 (micro:bit の傾きをモニターする)
今回は、傾きの情報を通知するコードを micro:bit へ書き込み、それに接続できるモニタアプリを作成してみます (ボタンが一瞬カクンと下がりますが、これは不具合です。。。)。
前提となる知識
- BLE 接続で利用される GATT やサービスなどについてはとくに記述はしないので、事前にネット上の検索などで調べておいてください。
- micro:bit で BLE を利用する方法についてもとく記述はしないので、これも事前に調べておいてください。
- CodeSandbox については、 私自身も数日前から利用を始めたので大した知識はないのですが、今回の用途ならそれほど躓くことはないと思います。 なお、少し試すだけならサインインしなくても実行できるようです 。
- テンプレートでは React + Typescript + Materila UI を使っていますが、いくつかの定数と関数を1つ変更するだけなので簡単な Javascript が書ければ大丈夫です。
micro:bit のコードを書き込む
MakeCode Editor でプロジェクトを作成し以下のコードを書き込みます。
GitHub にも https://github.com/hankei6km/microbit-ble-test として書き出してはあるのですがインポートするとブロックが表示されなくなるので、スクリーンショットを掲載しておきます。
接続するための定義を決める
今回は、micro:bit 側で Bluetooth UART サービス(Nordic UART Service) を利用しているので、接続するための定義は自動的に以下の値に決まります。
- 名前のプレフィックス:
BBC micro:bit
- サービスの UUID:
6e400001-b5a3-f393-e0a9-e50e24dcca9e
- キャラクタリスティックの UUID:
6e400002-b5a3-f393-e0a9-e50e24dcca9e
- デコーダー: 受信したバイナリデータを「文字列⇒数値」と順番に変換する処理を記述します。(具体的な記述は後で出てきます)
表示の定義を決める
画面上部に表示されるゲージ関連の定義です。 とくに決まりはないので、センサーの出力範囲などからお好みの値にしてください。
- ゲージのラベル:
Micro:Bit 傾き
- ゲージの最小値:
-180
- ゲージの最大値:
180
モニターを作成する
- ブラウザーで https://codesandbox.io/s/bleez-nuy3c を開きます。
- 右上の Fork をクリックし、処理が完了するまで少し待ちます(完了するとブラウザの右下に通知が出ます)。
- 左側のファイルエクスプローラーから
src/App.tsx
を開きます(通常は初期状態で開かれています)。 App.tsx
のnamePrefix
等を、先に決めておいた定義へ変更します(以下のコードをコピーすればそのまま使えます)。const namePrefix: string = "BBC micro:bit"; // const namePrefix: string = ""; const serviceId: string = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; const characteristicId: string = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"; const decoder: (dataValue: DataView) => number = (dataValue) => { const t = new Array(dataValue.byteLength) .fill(0) .map((v, i) => dataValue.getUint8(i)); return parseInt(String.fromCharCode.apply(null, t), 10); }; const gaugeLabel: string = "Micro:Bit 傾き"; const gaugeMin: number = -180; const gaugeMax: number = 180;
- 変更が完了すると右側の Browser ペインの表示が更新されます。
モニターを動かしてみる
- Sandbox 内では Web Bluetooth は動作しないので、Browser ペインに表示されれている URL を別のタブや BLE 対応のデバイスで開きます(最近の Android スマートフォンなら大体動くと思います)。
- 「CONNETCT」をクリックすると micro:bit と接続できます。なお、Android などでは位置情報の利用を確認されますが、システム側の仕様なので回避することはできないようです。
完成品
完成したモニターアプリは micro:bit ble test - CodeSandbox に保存してあります。
デコーダーについて
受信データを変換するデコーダー(decoder
)について補足です。
今回の例では、通知される値が文字列であるため、受信したバイナリデータを「まず文字列として扱い、さらに数値に変換する」という少し複雑な処理になっています。 ですが、通知される値が数値であれば「型」「オフセット」「レゾリューション」などを元に簡単に記述することができます。
たとえば、「符号ありの16bit」「オフセットは2」「レゾリューションは100(受信した数値は100で割る)」の場合の decoder
は以下のようになります。
const decoder: (dataValue: DataView) => number = (dataValue) =>
dataValue.getInt16(2) / 100;
既知の問題点
- 表示がガタつくことがある: ゲージと数値の表示の位置を雑に決めてしまったので、その影響で表示の更新時にガタつくことがあります。
- ブラウザの画面をバックグラウンドに回したり、スリープさせると値が通知されず、ブラウザがアクティブになった時点でまとめて通知される: これは最近のスマートフォンではバッテリーやセキュリティの対策としてこのような仕様になっているようです (最近といいつつ、記憶が正しければ webOS の最初のバージョンアップの頃からですが :-)。
機能追加
テンプレートには簡易的な機能しかないため、機能を追加したくなるかと思います。
リアルタイムなグラフやログの機能を追加したいといった場合には、 ゲージの表示使っている ApexCharts.js にはグラフ内のデータを CSV としてダウンロードできる 機能があるので、 専用 UI を作成することなく比較簡単な変更で対応できるのでないかと思います。
デプロイ
最終的にウェブアプリとして使うならどこかにデプロイしておく方が良いかと思いますが、その辺はまだ試していません。 試すことができたら追記したいと思います。
まとめ
BLE は GATT の仕様によって、ちょっとしたセンサーの値を受け取るような用途の場合、元になるソースコードさえあればサービスの UUID 等を変更するだけで対応できる場面も多いように思えます。 しかし、ソースコードを実際にビルドして利用するには開発環境を用意する必要があり、その手間がネックになっているのではと感じています。
今回、CodeSandbox とテンプレートを利用することで環境構築などの煩雑さを回避できることがわかったので、 このようなクラウド系の IDE をうまく利用できれば BLE 接続のモニターアプリ等も手軽に作成できるようになるのでないかと思います。
なお、もう少し突っ込んで CodeSandbox を調べたいというときは 、以下のページが参考になります。
- 君は2クリックでVue appを立ち上げたことがあるか!!<CodeSandboxを世の中に広めなければと思った件> - Studio Andy
- CodeSandbox : Playground 感覚な GitHub も使える Desktop PWAs 対応までしてるいいやつ - kondoumh のブログ