はじめに
昨年、アドベントカレンダーの記事を書く中で、いくつか BLE関連の内容(以下のもの)を試しました。
【2019年のアドベントカレンダー用に書いた記事(BLE関連のものを抜粋)】
- 新デバイスと新機能:obniz Board 1Y と obniz-noble(2019/12/18)
- 新しい obniz で obniz-noble を試す(2019/12/22)
- #obniz と micro:bit で obniz-noble を使った BLE通信 (26記事目)
- micro:bit で BLE + UART による文字列の送受信(29記事目)
- micro:bit と #obniz で BLE + UART を試そうとした話と Mac用ツール(30記事目)
そして、micro:bit と BLE利用の組み合わせが中途半端になっている部分があったため、その続きを試していった内容になります。
Web Bluetooth API で試す内容
上記の記事 5)の最後に、「Web Bluetooth API を使った内容は、micro:bit との連携を行った事例のサンプルがけっこう見つかった」と書いていました。
今回はサンプルが多く見つかっていた、Web Bluetooth API を使った ブラウザ(Chrome)と micro:bit との間でのテキストデータのやりとりを試してみます。
Web Bluetooth API のブラウザの対応状況(2020/1/1 時点)
まずは、記事執筆時点(2020/1/1 時点)で Web Bluetooth API が利用可能なブラウザについて、以下のページで確認してみます。
●Can I use... Support tables for HTML5, CSS3, etc
https://caniuse.com/
Web Bluetooth API の対応状況は、以下のようになっており、とりあえず Chrome を使っておくのが良さそうでした。
Web Bluetooth API を利用するための準備とお試し
いくつか見つかっていたサンプルのうち、まずは以下を試してみました。
内容は「ブラウザ上から micro:bit にテキストデータを送信し、micro:bit上の LED にテキストを表示させる」というものです。
●Web Bluetooth API を使ってブラウザだけでMicro:bitとBLE通信してみる。
https://shimz.me/blog/microbit/5456
GitHub Pages を利用したオンライン上での環境準備
これを試すための環境準備の方法はいくつかありますが、まずはブラウザ上での操作のみで GitHub Pages を利用し、Web Bluetooth API を動作させるための環境を準備してみようと思います。
環境を GitHub上で準備するにあたり、既存のリポジトリを利用することも可能ですが、今回は専用のリポジトリを作成する手順で進めることにします。
▼ I) GitHub にログインし、https://github.com/new にアクセス。
▼ II) Repository name を設定し、Public のリポジトリを新規作成する(自分の場合は「API_Test」という名称にしました)。
▼ III) 作成したリポジトリのページの右上から「create new file」を選択。
▼ IV) 作成するファイル名を以下に入力する。
※ 自分の場合は、以下のとおり「WebBluetoothAPI/test01.html」としました
▼ V) 「<> Edit new file」の下に上記の参考ページとして書いた記事のソースコードを書き(+ 少し書きかえをして)、以下の画像で示されたページ下部で「Git のコミットメッセージ」を書くなどして、「Commit new file」を押す。
▼ VI) リポジトリのページ右上の「Settings」を選択。
▼ VII) 以下の「Select source」で None 以外を選び(※ 自分が今回行った内容では「master branch」を選択)び、
選択後に以下のような表示になっていれば OK。
上記の V)の部分で書きかえを行ったのは、元記事のソースの 41行目「{name: "BBC micro:bit [vaget]"}」の部分です。この「vaget」となっている部分は、micro:bit のデバイスごとに固有で決まる部分のため、自身が利用している micro:bit を検索できるようにするために書きかえが必要です。
自分のデバイスの固有の情報に書きかえても良いですが、以下の別の記事を見ると、上記のデバイス固有の情報を含めないやり方もあったため、それを採用しました。
●micro:bitとWebBluetoothで通信してみました - Qiita
https://qiita.com/yokmama/items/5522fabfb5b9623278e2
具体的には、以下のような指定をします(文字列のプレフィックスのみをマッチさせる方法です)。
filters: [{
namePrefix: 'BBC micro:bit',
}],
このやり方で、以下の動画のようにブラウザから micro:bit へのテキスト送信が行えることが確認できました。
Web Bluetooth API を使った、Chrome と micro:bit の通信!
— you (@youtoy) January 1, 2020
ペアリング後に、テキストデータをブラウザから送信し、そのデータを micro:bit の LED に表示できたことを確認。 pic.twitter.com/BUHw9Udikh
なお、ブラウザ側のソースコードは以下になります(参照元のソース、ほぼそのままですが)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Web Bluetooth API のテスト</title>
</head>
<body>
<button id="connect">接続</button>
<button id="disconnect">切断</button>
<input id="message" value="hello" />
<button id="send">送信</button>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script>
<script>
// 情報元: https://shimz.me/blog/microbit/5456
var bluetoothDevice;
var characteristic;
//micro:bit BLE UUID
var LED_SERVICE_UUID = 'e95dd91d-251d-470a-a062-fa1922dfa9a8';
var LED_TEXT_CHARACTERISTIC_UUID = 'e95d93ee-251d-470a-a062-fa1922dfa9a8';
//ボタンイベントリスナー
d3.select("#connect").on("click", connect);
d3.select("#disconnect").on("click", disconnect);
d3.select("#send").on("click", sendMessage);
//micro:bitに接続する
function connect() {
let options = {};
//options.acceptAllDevices = true;
options.filters = [
{services: [LED_SERVICE_UUID]},
{namePrefix: "BBC micro:bit"}
];
navigator.bluetooth.requestDevice(options)
.then(device => {
bluetoothDevice = device;
console.log("device", device);
return device.gatt.connect();
})
.then(server =>{
console.log("server", server)
return server.getPrimaryService(LED_SERVICE_UUID);
})
.then(service => {
console.log("service", service)
return service.getCharacteristic(LED_TEXT_CHARACTERISTIC_UUID)
})
.then(chara => {
console.log("characteristic", chara)
alert("BLE接続が完了しました。");
characteristic = chara;
})
.catch(error => {
console.log(error);
});
}
//LEDに表示するメッセージを送信
function sendMessage() {
if (!bluetoothDevice || !bluetoothDevice.gatt.connected || !characteristic) return ;
var text = document.querySelector("#message").value;
var arrayBuffe = new TextEncoder().encode(text);
characteristic.writeValue(arrayBuffe);
}
//BLE切断処理
function disconnect() {
if (!bluetoothDevice || !bluetoothDevice.gatt.connected) return ;
bluetoothDevice.gatt.disconnect();
alert("BLE接続を切断しました。")
}
</script>
</body>
</html>
ローカル環境でのサーバ準備
ここまでは、オンライン上で環境を準備しましたが、ローカルの PC上でも環境を準備して試してみようと思います。
Python を利用
Web Bluetooth API に関して情報を調べてみると、「SSL通信が必須」と書かれたページがたくさん出てくるものの、「SSL通信なしで利用できた」という情報もありました。
まずは、簡易な方法でサーバを準備してみます。
以下のページに色々な言語でのやり方が書かれていたため、これを利用しようと思います。
●ワンライナーWebサーバを集めてみた - Qiita
https://qiita.com/sudahiroshi/items/e74d61d939f18779970d
いくつかある中の「Python3.x編」を試したところ、SSL通信なしで Web Bluetooth API を用いた通信を試すことができました。
$ python -m http.server 8000
node.js の light-server を利用(※ npx を利用)
今回、SSL通信なしに上記が試すことができましたが、SSL通信を利用できる環境も準備してみます。
「node.js の light-server」を利用した以下のコマンドで証明書を自動生成できる、といった記載があり、これを試すことにしました(http2 での通信になったりはしますが)。
$ light-server -s . --http2
light-server is listening at https://0.0.0.0:4000
serving static dir: .
今回は、上記をそのまま実行してみるのではなく、「npx」を使ってみました。
npx を利用したことで、light-server が事前に準備されていない環境で、今回の実行時のみ一時的に light-server を利用可能な状態になりました(※ 以下を停止させた後は、light-server が準備されていなかった状態に戻ります)。
$ npx light-server -s . --http2
npx: 88個のパッケージを8.196秒でインストールしました。
light-server is listening at https://0.0.0.0:4000
serving static dir: .
これで、https://localhost:4000/(ファイル名).html
にアクセスすると、「自己署名証明書」を利用した形になるため、当然、以下のような警告はでます。
さらに先へ進むと、警告は残りつつも以下のとおりページを開くことができました。
おわりに
今回は、micro:bit の「Bluetooth LEDサービス」のみを利用しましたが、他にもいくつも利用可能なものがあるため、今後はそれらも試してみようと思います。