2021年07月29日 更新

Disconnectなど終了処理と状態遷移

どうも、クラゲです。
Web Bluetooth APIを超簡単に扱えるBlueJellyを使って今回は終了処理を行います。
また、最後にBlueJellyの状態遷移について説明します。
BlueJellyをサクッと使うだけなら、ブラウザをリロードすれば特に終了処理を気にする必要はありませんので、今回は読み飛ばしても大丈夫です。

【 必要なもの 】

Scan と同様

【 micro:bitの準備 】

Scan と同様

micro:bitが手元にない人は、HTML側のUUIDを変更すれば、他のBLEデバイスでも対応可能です

【 デモページとソースコード 】

主に接続と切断に関連する処理を実験できます。

WEB上で試せるデモページはこちら
BlueJelly Sample : Disconnect

ローカル環境で試したい方はこちらのGitHubからダウンロードし、disconnect.htmlを開いて実行してください。

ScanとConnect後に、Disconnect、Clear、Resetを選択するとデバイス情報と接続状態が変化するのが分かります。
また、エラーの場合はエラー表示が出るようにもなっています。
それではプログラムの解説に入ります。

【 プログラム解説(HTML) 】

前回のWriteからの変更点は以下の通りです。

  • テキストボックスとWriteボタンを削除
  • ScanとConnectボタンを復活
  • 新たなボタンとしてDisconnect, Clear, Resetを追加
<button id="scan" class="button">Scan</button>
<button id="connect" class="button">Connect</button>
<button id="disconnect" class="button">Disconnect</button>
<button id="clear" class="button">Clear</button>
<button id="reset" class="button">Reset</button>

【 プログラム解説(JavaScript) 】

フローはこんな感じです。
長くなるため、インスタンス生成とUUID登録は省略してますが、実際には必要ですのでご注意ください。

disconnect, clear, resetのそれぞれに対し処理が終わったら、onDisconnect, onClear, onResetが呼ばれます。

ble.onDisconnect = function() {
  document.getElementById('uuid_name').innerHTML = "Not Connected";
  document.getElementById('status').innerHTML = "disconnected";
}

ble.onClear = function() {
  document.getElementById('device_name').innerHTML = "No Device";
  document.getElementById('uuid_name').innerHTML = "cleared";
  document.getElementById('status').innerHTML = "cleared";
}

ble.onReset = function() {
  document.getElementById('device_name').innerHTML = "No Device";
  document.getElementById('uuid_name').innerHTML = "Not Connected";
  document.getElementById('status').innerHTML = "cleared";
}

それぞれボタンが押されたときの関数呼び出しを指定します。引数は不要です。

document.getElementById('disconnect').addEventListener('click', function() {
    ble.disconnect();
});

document.getElementById('clear').addEventListener('click', function() {
    ble.clear();
});

document.getElementById('reset').addEventListener('click', function() {
    ble.reset(); //reset is disconnect & clear
});

disconnectは接続状態を解除、clearはデバイス情報とUUID登録情報をクリアするという意味です。
resetはコメント文にも書いてありますが、disconnectとclearの両方を一気に行う関数です。

今回はもう一つ、コールバックを追加しています。
エラーがあったときにstatusにエラー表示をする関数です。
エラー内容は引数に文字列として受け取るので、そのまま表示します。

ble.onError = function(error){
  document.getElementById('status').innerHTML = "ERROR : " + error;
}

うまくいかない場合

特にmicro:bit以外を使っていてうまくいかない人は、BLEデバイスのUUIDとJavaScriptのUUIDが正しく合っているか確認してください。

状態遷移について

最後に状態遷移について図解します。
WebBluetoothAPIの接続状態は Initial State, State1, State2, State3 の4つに分けることができます(クラゲが勝手に命名しました)。それぞれの状態へ遷移させるアクションを青字と矢印で書いています。

HTML読み込み時はInitial State状態から始まり、scanボタンを押しデバイスを選択すると、State1状態に遷移します。
connectボタンを押すとState2状態に遷移し、ここでread,notify,writeが可能となります。
他のデバイスに切り替えたり、終了したい場合は、disconnectとclearを実行することでInitial Stateに戻ることできます。
disconnectとclearの順番はどちらが先でも大丈夫です。
逆にscanとconnectは順番があり、Initial Stateからいきなりconnectは出来ません。

BlueJellyでは、この状態を簡略化して2状態で扱うことが可能です。

これまで何度か説明していますが、BlueJellyのread,notify,writeについて、もしscanやconnectが行われていない場合は、先にscanとconnectを自動的に行います。
つまり、scanとconnectは使わなくても大丈夫だということです。
また、resetを使うことにより、disconnectとclearも使わなくても大丈夫になります。

まとめると、BlueJellyにおいては、read, notify, write, resetの4つさえ使えばBLE通信ができるということです。(notifyは実際にはstartNotifyとstopNotifyの2種類です)
究極的には、ブラウザのリロードを使えば reset も不要です。
いかがでしょうか? BlueJellyではとてもシンプルに気軽にBLEが扱えるのが分かったと思います。

以上、Disconnectなどの終了処理と状態遷移でした!