Web Bluetoothを使ったIoTアプリ入門
このサンプルはBasic Kit スタートガイドで紹介したものと同様です。ソースコードを読みながら、動作を理解していきましょう。
※本ウェブサイトに記載している会社名、商品名は、各社の商標または登録商標です。
はじめに
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ブラウザ上であればどの環境においても同様に動作します。
ポイント
- Web Bluetoothライブラリを使うと、Bluetooth接続するソフトをWebアプリで記述できる。
- Webアプリであればブラウザが動く機器であれば同じソースコードが動く。
- 表やグラフ等のGUIはHTMLとCSSでラクラク開発
用意するもの
- Leafony Basic Kit
- Windows1、 Mac2、 Linux3のどれかのPC (開発用)
- Android4、 iPhone5、 iPad5のスマートフォンまたはタブレット (テスト用 なくても良い)
- Google Chrome (バージョン70.0.3526.0以降)
- Arduino IDE
サンプルアプリのソースコード
あらかじめどちらもダウンロードしてください。
-
Arduino スケッチ Arduino IDE 1.8.7、Arduino AVR Boards 1.6.23で動作検証済み。6
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 |
リーフの組み立て
下図のようにリーフを組み立てましょう。
ピンアサイン
各リーフのピンアサインは下図を参考
実行方法
- Arduino IDEで4-Sensors_BLE.inoを書き込む。Arduino IDE 1.8.7、Arduino AVR Boards 1.6.23で動作検証済み。6
- ダウンロードしたWeb Bluetooth アプリの
index.html
をGoogle Chromeで開く。
Webアプリの使い方の詳細はBasic Kit クイックスタートガイドを参考
データの送信
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.temp
やstate.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.ino
のmy_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.html
とapp.js
とleafony.js
の3つのファイルで構成されています。
index.html
はボタンや表の配置を行ったり、他2つのjavascriptのファイルを読み込むだけの単純なものです。
app.js
はボタンが押されたときの処理などメインの処理が記述されています。
leafony.js
はWeb Bluetoothを使ってLeafonyと接続するための具体的な処理がかかれています。
Web Bluetoothの注意点
2022年9月時点ではWeb Bluetoothは以下の点に注意しなければいけません。
- iPhoneのChromeでは動作しません。Bluefyという有料のアプリを使えば利用可能です。
- Web Bluetoothの開発状況と対応ブラウザについてはimplementation-status.mdで確認できます。
参考
LeafonyとWeb Bluetoothでラクラク!クロスプラットフォームIoT開発入門
-
Windows 10 version 1703以降 ↩︎
-
OS X Yosemite以降 ↩︎
-
Kernel 3.19+ and BlueZ 5.41+ installed. ↩︎
-
Android 6.0 Marshmallow以降 ↩︎
-
iPhoneまたはiPadには Bluefyのアプリが必要です。iPhone、iPad版のChromeではWeb Bluetoothが実装されていないためです。 ↩︎
-
動作しない場合はArduino IDE 1.8.7、Arduino AVR Boards 1.6.23で書き込みを行ってください。古いバージョンのArduino IDEダウンロードとArduino AVR Boardsの変更方法については Arduino IDE のバージョン参照。 ↩︎