ブラウザ(JavaScript)でマイクロビットとBLE!(2)

IoT

こんにちは、ECF Techブログ
担当 Michiです。

はじめに

今回はマイクロビットとブラウザ(JavaScript)を使ったBLE接続の第2弾です。前回はマイクロビット側でAまたはBボタンが押されたことをブラウザ側で検知するプログラムを紹介しました。

今回はブラウザからのアクションにより、マイクロビットのLEDを光らせるプログラミングをご紹介します。前回との大きな違いは前回がマイクロビットからの情報の読み取りであったのに対し、今回はマイクロビットへの情報の書き込みになる点です。

記事の概要と想定読者

本記事では動作が確認できた。というサンプルプログラムの提供がメインとなります。BLE(Bluetooth Low Energy)の基本的な内容については、こちら(当サイト記事)にまとめています。

また、サンプル内のコードにコメントを記載する形で説明をさせて頂いています。後半に一部解説を記載しておりますが、全体としてはJavaScriptの基本的なコードが読める方が対象になっております。

プログラムの内容

完成画面と操作

それでは早速行きましょう。完成すると、下のような画面ができます。

操作概要

  • 「接続」をクリックでマイクロビットと接続
  • マイクロビットのLED画面を模したチェックボックス
  • 「LED表示」をクリックでチェックボックスの並びと同じようにライトが光る
  • テキストボックスに文字列(半角英数字)を入力し、「文字列表示」をクリックするとその文字列を表示。最大20バイト文まで
  • 「BLE切断」をクリックでマイクロビットとのコネクションを切断

プログラムはこちらになります。

<!DOCTYPE html>

<html>
    <head>
        
    </head>
    <body>
        Bluetooth接続サンプル
        <input type="button" value="接続" onclick="pushStart()" /><br>
        <div id="matrixArea">
            <input type="checkbox" name="L0">
            <input type="checkbox" name="L0">
            <input type="checkbox" name="L0">
            <input type="checkbox" name="L0">
            <input type="checkbox" name="L0"><br>
            
            <input type="checkbox" name="L1">
            <input type="checkbox" name="L1">
            <input type="checkbox" name="L1">
            <input type="checkbox" name="L1">
            <input type="checkbox" name="L1"><br>
            
            <input type="checkbox" name="L2">
            <input type="checkbox" name="L2">
            <input type="checkbox" name="L2">
            <input type="checkbox" name="L2">
            <input type="checkbox" name="L2"><br>
            
            <input type="checkbox" name="L3">
            <input type="checkbox" name="L3">
            <input type="checkbox" name="L3">
            <input type="checkbox" name="L3">
            <input type="checkbox" name="L3"><br>        
            
            <input type="checkbox" name="L4">
            <input type="checkbox" name="L4">
            <input type="checkbox" name="L4">
            <input type="checkbox" name="L4">
            <input type="checkbox" name="L4"><br>

            <input type="button" value="LED表示" onclick="showMatrix()" /><br>
            <br>            
            <input type="text" name="message" /><br>
            <input type="button" value="文字列表示" onclick="showText()" /><br>
            <hr>
            <input type="button" value="BLE切断" onclick="disconnect()" /><br>
        </div>
        <div id="buttonB">
        </div>
        <script>
            let charaA, charaB, bitServer;
            //BLE接続を開始する
            function pushStart(){
                console.log("pushStart");
                //microbit LEDサービスのUUID
                let ledUuid =  "E95DD91D-251D-470A-A062-FA1922DFA9A8";
                let ledMatrixUuid = "E95D7B77-251D-470A-A062-FA1922DFA9A8";
                let ledTextUuid = "E95D93EE-251D-470A-A062-FA1922DFA9A8";
                //デバイスの取得
                navigator.bluetooth.requestDevice(
                    {acceptAllDevices:true,optionalServices:[ledUuid.toLowerCase()]}
                ).then(         //デバイス取得できたら
                    device => {
                        console.log('Connecting micro:bit');
                        return device.gatt.connect();
                    }
                ).then(         //接続できたら
                    server => {
                        bitServer = server;
                        console.log('Getting Service');
                        return server.getPrimaryService(ledUuid.toLowerCase());
                    }
                ).then(         //サービスが取得できたら
                    service => {
                        console.log('Getting Characteristics');
                        //2つのcharacteristicsの取得を待つ
                        return Promise.all([
                            //characteristicsの取得(XY指定用)
                            service.getCharacteristic(ledMatrixUuid.toLowerCase())
                            .then(chara => {
                                console.log("Getted matrix chara");
                                //停止できるようにグローバルに保持
                                charaA = chara;
                            }
                            ),
                            //characteristicsの取得(Text表示用)
                            service.getCharacteristic(ledTextUuid.toLowerCase())
                            .then(chara => {
                                console.log("Getted textLed chara");
                                //停止できるようにグローバルに保持
                                charaB = chara;
                            }
                            )
                        ]);
                    }
                )
                .catch(
                    error => {
                        //途中でエラー発生したらエラー出力
                        console.log('sorry Error!');
                        console.log(error.code);
                        console.log(error.message);
                        console.log(error.name);
                    }
                )
            }
            //5x5チェックによる表示
            function showMatrix(){
                //ArrayBufferオブジェクトを生成
                let buffer = new ArrayBuffer(5);
                //bufferを操作するためのDateViewを生成
                dataview = new DataView(buffer);
                //各チェックボックスを参照
                for( let i = 0; i < 5; i++){
                    //1行分のチェックボックスを取得
                    let checks = document.getElementsByName('L' + i);
                    //ビット演算用のフラグ
                    let factor = 0x10;
                    //ビット演算合計の保持
                    let value = 0;
                    //1行分のチェックボックスを1つ1つ確認
                    for( let v of checks){
                        //チェックボックスがONなら、factorを加算
                        if( v.checked ) value += factor;
                        //factorを1ビット右シフト(左0埋め)
                        factor = factor >>> 1;
                    }
                    //Dataviewを通して、bufferに値をセット
                    dataview.setUint8(i,value);
                }
                //characteristicsへのLED表示情報を書き込み
                charaA.writeValue(buffer);
            }
            //テキスト表示
            function showText(){
                var buffer = new TextEncoder().encode('hello');
                charaB.writeValue(buffer);
            }
            //BLE接続の切断
            function disconnect(){s
                if( bitServer ){
                    console.log('disconnected');
                    bitServer.disconnect();
                }
            }
        </script>
    </body>
</html>

解説

ポイントは108行目からのshowMatrixメソッドです。
Web Bluetoothでは接続している機器にデータを書き込む場合、コード内にあるwriteValueメソッドを使います。このwriteValueメソッドはArrayBufferオブジェクトのデータを受け取ることになっているのでそれを用意しています。

また、ArrayBufferの操作にはDataViewというオブジェクトが必要なので、その関連づけがされています。

このwriteValueメソッドで書き込むのは5バイトです。各バイトは上から順に各LEDと対応しており、下位5ビットの値に基づいて、LEDが光ります(下の図のとおり)。

showTextメソッドはシンプルで、ArrayBufferへ変換してくれるメソッドを呼び出すだけです。

マイクロビット側のプログラムはこちらになります。

動作確認

マイクロビットとブラウザをBLEでつなぐ方法については、こちらからご確認ください。

おわりに

本日はここまでとさせていただきます。最後までご覧いただきありがとうございました。

前回に引き続き、Web(JavaScript)とマイクロビットのBLE接続をご紹介させて頂きました。引き続き色んなサンプルを作っていければと思っていますので、ぜひまたご覧ください。


合同会社イー・シー・エフでは、子ども向けプログラミングなどの教育講座を実施しています。プログラミング教室の案内や教育教材の情報は、下記よりご確認ください。

ECFエデュケーション
キッズも大人も。沖縄からITのマナビを応援します
タイトルとURLをコピーしました