これまで、UIFlow の BLE UART を試して以下の記事を書いてきました。
- #UIFlow の BLE UART を使った文字のやりとりを #M5Stack_Core2 で試してみた( #M5Stack ) - Qiita
- 【JavaScript 2020】 #UIFlow の BLE UART を使ったブラウザから #M5Stack_Core2 ( #M5Stack )への文字の送信 - Qiita
- #UIFlow の BLE UART を使った #M5Stack_Core2 ( #M5Stack )とブラウザとの双方向無線通信 - Qiita
この記事は、上記で試してきた流れと、以下の記事で使ったグラフ化とを組み合わせた内容になります。
●【JavaScript 2020】 MQTT で受信したデータを Smoothie Charts(smoothie.js)以外でリアルタイムにグラフ化: Chart.js とプラグインを利用 - Qiita
https://qiita.com/youtoy/items/252f255c9d794bf3d964
概要
まず、今回試した内容が動作している様子をご覧ください。
M5Stack Core2 のタッチスクリーン上に触れると、その x座標か y座標の値を取得し(どちらを取得するかは、Bボタン押下で変更できる仕組みあり)、それが BLE経由でブラウザに送られます。ブラウザ側では、受け取った値を使ってリアルタイムにグラフを描いています。
#UIFlow の BLE UART を引き続きお試し。#M5Stack_Core2 の画面上でタッチされた座標を BLE でブラウザに送り、リアルタイムにグラフとして描画してみた。
— you (@youtoy) January 20, 2021
送る値を途中で 、x座標にするか y座標にするか、入れ替えてます。#M5Stack pic.twitter.com/wHvN4vdoB8
プログラム
M5Stack Core2 で動作している UIFlow のプログラムと、ブラウザ側で動いている HTML+JavaScript のソースをそれぞれ記載します。
UIFlow
UIFlow側は、以下のような仕組みにしてます。
- Aボタン押下 ⇒ 300ミリ秒間隔で動くタイマーを開始
- Bボタン押下 ⇒ 取得する値(タッチスクリーン上で触れられた位置の座標)を x/y のどちらにするか切り替え
- Cボタン押下 ⇒ タイマーを止める
- タイマーの処理 ⇒ タッチスクリーン上で触れられた位置の座標 x/y を BLE で送信しつつ、画面上にも表示
タイマーの処理の最後のブロック、「テキストに変換する」を入れないとうまく動かなかったので入れたものです。
その1つ上のブロック、画面のラベルでの表示のほうはそれが不要だったのですが、テキストのプログラムに切り替えてそれぞれを見てみると、画面表示のほうはテキストに変換する処理が裏で入ってました。
HTML+JavaScript
ブラウザ側の処理(BLE関連の処理やグラフ描画の処理)は以下のように実装しています。
利用する際には、こちらを HTMLファイルにしてブラウザで開き、最初に画面上の「接続」ボタンを押してペアリングから始めてください。その後は、M5Stack Core2側を操作していく流れです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>UIFlow と BLE</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment-with-locales.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming@1.8.0/dist/chartjs-plugin-streaming.min.js"></script>
</head>
<body>
<h1>UIFlow と BLE + グラフ描画</h1>
<button onclick="onStartButtonClick()">接続</button>
<br />
<canvas id="myChart"></canvas>
<script>
const UUID_1 = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
const UUID_2 = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"; // Write、今回は使わない
const UUID_3 = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"; // Notify
let bluetoothDevice;
let characteristic;
async function onStartButtonClick() {
try {
console.log("Requesting Bluetooth Device...");
const device = await navigator.bluetooth.requestDevice({
filters: [{ namePrefix: "m5ble" }],
optionalServices: [UUID_1],
});
console.log("Connecting to GATT Server...");
const server = await device.gatt.connect();
console.log("Getting Service...");
const service = await server.getPrimaryService(UUID_1);
console.log("Getting Characteristic...");
characteristic = await service.getCharacteristic(UUID_3);
await characteristic.startNotifications();
console.log("> Notifications started");
characteristic.addEventListener(
"characteristicvaluechanged",
handleNotifications
);
} catch (error) {
console.log("Argh! " + error);
}
}
const ctx = document.getElementById("myChart").getContext("2d");
let chart = new Chart(ctx, {
type: "line",
data: {
datasets: [
{
data: [],
},
{
data: [],
},
],
},
options: {
scales: {
xAxes: [
{
type: "realtime",
realtime: {
delay: 200,
},
},
],
},
},
});
async function handleNotifications(event) {
if (characteristic) {
try {
const value = event.target.value;
const inputValue = new TextDecoder().decode(value);
console.log(inputValue);
chart.data.datasets[0].data.push({
x: Date.now(),
y: inputValue,
});
chart.update({
preservation: true,
});
} catch (error) {
console.log("Argh! " + error);
}
}
}
</script>
</body>
</html>
グラフ描画まわりの処理の説明は、記事の上のほうでも掲載した以下の記事のほうをご覧ください。
●【JavaScript 2020】 MQTT で受信したデータを Smoothie Charts(smoothie.js)以外でリアルタイムにグラフ化: Chart.js とプラグインを利用 - Qiita
https://qiita.com/youtoy/items/252f255c9d794bf3d964