Web Bluetoothを使ったIoTアプリ入門

このサンプルはBasic Kit スタートガイドで紹介したものと同様です。ソースコードを読みながら、動作を理解していきましょう。

webbluetooth.png

はじめに

Leafonyは省電力で小型なIoTデバイスの開発を簡単に行えるように、それぞれのリーフが省電力な設計になっています。 バッテリで長時間動作するため、様々な場所に設置してセンサで定点観測を行うことも可能です。

では、センサで測定した温度や湿度、照度のようなデータはどのようにして集められるのでしょうか。 一般的にWi-FiやBluetooth、LoRaといった無線通信が用いられるでしょう。 Leafonyでは無線通信規格の中でも省電力なBluetoothを搭載したリーフが存在します。

Basic Kitは省電力なセンサを複数搭載した4-Sensorリーフと、省電力なBluetooth規格であるBluetooth LE (以下、BLE)を搭載したBLEリーフを使った長時間バッテリ駆動のIoTセンサの開発を簡単に行えるキットです。

それでは、Leafonyが送るBLEを受信するためにはどうすれば良いでしょうか。 PCやスマホ・タブレットには色々な環境があります。Windowsが動くPC、MacOSが動くPC、Android、iPhoneなど、身近なものでも非常に沢山の環境が存在します。 これらの環境でBluetoothを使うためには、それぞれの環境に合わせたプログラミング言語で開発するのが普通です。PCであればC言語やPythonなどの言語を使って開発できますが、AndroidやiPhoneであれば、Android StudioやXcode等を使ってまた別のプログラミング言語でソフトを作る必要があります。

多くの人が様々な環境で使うものを簡単に開発するにはどうすれば良いでしょうか。 今回のサンプルアプリでは一つの方法として、Bluetoothの通信を行いデータを画面に表示するためにWebブラウザを使うことにしました。

使用する言語はHTMLとJava Scriptです。この2つの言語で記述したプログラムが、Webブラウザ上であればどの環境においても同様に動作します。

用意するもの

  • Leafony Basic Kit
  • Windows1、 Mac2、 Linux3のどれかのPC (開発用)
  • Android4、 iPhone5、 iPad5のスマートフォンまたはタブレット (テスト用 なくても良い)
  • Google Chrome (バージョン70.0.3526.0以降)
  • Arduino IDE

サンプルアプリのソースコード

あらかじめどちらもダウンロードしてください。

Leafonyの構成

このサンプルでは下記のリーフ構成で試せます。

Type Name Q’ty
AZ62 Connector Cover 1
AI01 4-Sensors 1
AZ01 USB 1
AP01 AVR MCU 1
AC02 BLE Sugar 1
AV01 CR2032 1
- CR2032 coin cell battery 1
- M2*18mm screw 2

リーフの組み立て

下図のようにリーフを組み立てましょう。

ピンアサイン

各リーフのピンアサインは下図を参考

実行方法

  1. Arduino IDEで4-Sensors_BLE.inoを書き込む
  2. ダウンロードしたWeb Bluetooth アプリindex.htmlをGoogle Chromeで開く
    Webアプリの使い方の詳細はBasic Kit クイックスタートガイドを参考

basic_android

データの送信

BLEでデータを送受信する方法を見てみましょう。

Leafony側

4-Sensors_BLE.inoの1020行目付近でBluetoothで送信するテキストデータを生成しています。 このテキストを変えることで任意のデータを送信可能です。

sendLen = sprintf(sendData, "%04s,%04s,%04s,%04s,%04s,%01s\n", temp, humid, light, tilt, battVolt, pips)

上記では<温度>,<湿度>,<照度>,<傾き>,<電池電圧>,<サイコロ>のようにカンマ区切りのデータを送信しています。

実際にこのテキストデータを送信しているのは下記の部分です。(1085行目付近)

ble112.ble_cmd_gatt_server_send_characteristic_notification( 1, 0x000C, sendLen, (const uint8 *)sendData );

Webアプリ側

Webアプリ側ではleafony.jsにデータ受信時の処理が書かれています。

leafony.jsの75行目の記述で、データを受信した時に呼び出される関数を指定します。 ここではhandleData()という関数が呼び出されます。

char.read.addEventListener( 'characteristicvaluechanged', handleData );

handleData()関数もleafony.jsに記述されています。
BLEで受信したデータはevent.target.valueに含まれています。
一旦dataという変数に値をコピーした後に、受信データをutf-8でデコードし、改行コード(\r\n)を取り除いてから、カンマ,で区切って配列にしています。
これらのデータはstateという変数に任意の名前をつけて保存しています。(state.tempstate.humidなど)

Leafony側で送るデータを変更した際は、handleData()関数を修正することでデコードすることが可能です。

    /**
     * Characteristicの値が変化した時に呼び出される関数
     * @param {*} event
     */
    function handleData( event ) {
        // 受信したデータの文字コードを変換して、カンマでデータを分けている
        // このサンプルではLeafonyは
        // 温度,湿度,傾き,電池の電圧
        // のようにカンマ区切りのテキストを送信している。
        let data = event.target.value;
        let decoder = new TextDecoder( 'utf-8' );
        data = decoder.decode( data );
        data = data.replace( /\r?\n/g, '' );
        data = data.split( ',' );

        state.devn = deviceName;
        state.unin = uniqueName;
        state.temp = data[0];
        state.humd = data[1];
        state.illm = data[2];
        state.tilt = data[3];
        state.batt = data[4];
        state.dice = data[5];
        // ここで updateTable() が実行されている
        onStateChangeCallback( state );

        // 省略
    }

データの受信

Webアプリ側

Webアプリの画面で「LED+」「LED-」ボタンを押すと、LeafonyのLEDの点滅スピードを変えることができます。
ボタン押された時の処理はapp.jsの下記の部分に記述されています。

buttonLedPls.addEventListener ( 'click', function () {

    console.log( 'LED Plus Button Clicked' );
    leafony.sendCommand( 'PLS' );

});

leafony.sendCommand( '文字列' );で任意の文字列をLeafonyに送信しています。

Leafony側

Webアプリ側から送信された文字列をLeafonyが受信したとき、4-Sensors.inomy_evt_gatt_server_attribute_value()関数が呼び出されます。
デコードされた文字列はrcv_dataという変数にコピーされ、その文字列の内容に応じた処理をしています。

void my_evt_gatt_server_attribute_value( const struct ble_msg_gatt_server_attribute_value_evt_t *msg ) {
    uint16 attribute = (uint16)msg -> attribute;
    uint16 offset = 0;
    uint8 value_len = msg -> value.len;

    uint8 value_data[20];
    String rcv_data;
    rcv_data = "";
    for (uint8_t i = 0; i < value_len; i++) {
        rcv_data += (char)(msg -> value.data[i]);
    }

    // 中略

    if( rcv_data.indexOf("SND") == 0 ){
        bBLEsendData = true;
        iToggle = 8;
    } else if( rcv_data.indexOf("STP") == 0 ){
        bBLEsendData = false;
        bLCDchange = true;
        lcd_view_sts = 1;
    } else if(rcv_data.indexOf("PLS") == 0){
      if(iToggle < 16){
        iToggle += 2;
      }
    } else if(rcv_data.indexOf("MNS") == 0){
      if(iToggle > 2){
        iToggle -= 2;
      }
    }
}

上記の部分を修正することで簡単にデータの送受信を行うことができます。

仕組み

  • PeripheralとCentral
  • アドバタイズ
  • GATT
  • Characteristic

Webアプリ側

index.htmlapp.jsleafony.jsの3つのファイルで構成されています。

index.htmlはボタンや表の配置を行ったり、他2つのjavascriptのファイルを読み込むだけの単純なものです。
app.jsはボタンが押されたときの処理などメインの処理が記述されています。
leafony.jsはWeb Bluetoothを使ってLeafonyと接続するための具体的な処理がかかれています。

Web Bluetoothの注意点

2020年6月時点ではWeb Bluetoothは以下の点に注意しなければいけません。

  • iPhoneのChromeでは動作しません。WebBLEという有料のアプリを使えば利用可能です。
  • Web Bluetoothの開発状況と対応ブラウザについてはimplementation-status.mdで確認できます。

参考

https://qiita.com/s_nkg/items/bdb235388eaeb567b54d


  1. Windows 10 version 1703以降 ↩︎

  2. OS X Yosemite以降 ↩︎

  3. Kernel 3.19+ and BlueZ 5.41+ installed. ↩︎

  4. Android 6.0 Marshmallow以降 ↩︎

  5. iPhoneまたはiPadの場合は WebBLE(有料)が必要です。iPhone、iPad版のChromeではWeb Bluetoothが実装されていないためです。 ↩︎


最終更新 September 16, 2020