WebBluetoothでNefry BTと繋げてディスプレイ表示させてみたのでまとめます。
作ったデモ
- ブラウザ -> Nefry BTに表示
環境
- Nefry BTライブラリ v1.4.1
- Google Chrome v71 (macOS)
- Vue.js
1.4.1が重要で、内部でESP32のライブラリが1系にアップデートされています。
1.4.0と比べるとBLEが格段に安定します。
ブラウザ側(HTML + Vue.js)
html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<button id="connect" @click="init">{{bleStatus}}</button>
<input v-model="message" placeholder="edit me" v-on:keyup="write">
<p>Message is: {{ message }}</p>
</div>
<script src="https://jp.vuejs.org/js/vue.min.js"></script>
<script src="app.js"></script>
</body>
</html>
キー入力があるたびにBLEを発火させたいのでv-on:keyup
を指定します。
JavaScript
SERVICE_UUID
とCHARACTERISTIC_UUID
にジェネレータや自身で取得したUUIDを記載します。
app.js
'use strict';
var app = new Vue({
el: '#app',
data: {
SERVICE_UUID: 'サービスUUIDを記載',
CHARACTERISTIC_UUID: 'キャラクタリスティックUUIDを記載',
characteristic: {},
message: '',
bleStatus: 'Nefry BTと接続する'
},
methods: {
init: async function(){
try {
const device = await navigator.bluetooth.requestDevice({
acceptAllDevices: false,
filters: [{namePrefix: 'Nefry'}], // 'Nefry'というデバイス名でフィルタリング
optionalServices: [this.SERVICE_UUID] // 使用したいServiceを登録しておく
});
const server = await device.gatt.connect();
const service = await server.getPrimaryService(this.SERVICE_UUID); //サービスに接続
this.characteristic = await service.getCharacteristic(this.CHARACTERISTIC_UUID); //キャラクタリスティックに接続
alert('接続しました。');
this.bleStatus = 'Nefry BTと接続されています。';
} catch (error) {
console.log('エラー',error);
}
},
write: function(){
try {
const text = this.message;
const arrayBuffe = new TextEncoder().encode(text);
this.characteristic.writeValue(arrayBuffe);
} catch (error) {
console.log(error);
alert('先にデバイスと接続してください。');
}
}
}
});
DOM周りのコードがないのでシンプルにかけますね。
NefryBT(Arduino)側コード
こちらも先ほど取得/生成したUUIDをSERVICE_UUID
とCHARACTERISTIC_UUID
に記載します。
nefrybt.ino
#include <Nefry.h>
#include <NefryDisplay.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
// from https://www.uuidgenerator.net/
#define SERVICE_UUID "サービスUUIDを記載"
#define CHARACTERISTIC_UUID "キャラクタリスティックUUIDを記載"
//3行目だけにPrint
void nfDisplay3Print(String mes){
NefryDisplay.print("");
NefryDisplay.print("");
NefryDisplay.print(mes);
}
// コールバック
// ブラウザ側からwriteValue()されたら実行
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
// シリアルにデバッグ出力(受信した文字列)
String message = "";
if (value.length() > 0) {
Nefry.print("Received: ");
// 1文字ずつ取得
for (int i = 0; i < value.length(); i++) {
Nefry.print(value[i]);
message += String(value[i]);
}
}
Nefry.println((char)value[0]);
nfDisplay3Print(message);
}
};
void setup() {
Nefry.disableWifi();
Nefry.setLed(0, 0, 0);
NefryDisplay.setTitle("from Web Bluetooth");
BLEDevice::init("NefryBT WebBluetooth test");
Nefry.println("NefryBT WebBluetooth test");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("Merry X'mas!");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop() {
Nefry.ndelay(1000); // 待ちループ
}
所感
WebBluetoothもだんだん使えるようになってきているし、NefryBTのBLEがすごく安定するようになったのでNefry BTに入力できる専用サイトみたいなものを作れそうですね。
Wi-Fi設定をBLE経由で書き込み出来るようになる「Nefry BT専用Webページ」てきなものを作れないか考えています。
対応できたら楽しそうですね!