0
2

More than 3 years have passed since last update.

#UIFlow の BLE UART を使った #M5Stack_Core2 ( #M5Stack )からブラウザへのデータ送信とグラフ化

Last updated at Posted at 2021-01-20

これまで、UIFlow の BLE UART を試して以下の記事を書いてきました。

この記事は、上記で試してきた流れと、以下の記事で使ったグラフ化とを組み合わせた内容になります。

●【JavaScript 2020】 MQTT で受信したデータを Smoothie Charts(smoothie.js)以外でリアルタイムにグラフ化: Chart.js とプラグインを利用 - Qiita
 https://qiita.com/youtoy/items/252f255c9d794bf3d964

概要

まず、今回試した内容が動作している様子をご覧ください。
M5Stack Core2 のタッチスクリーン上に触れると、その x座標か y座標の値を取得し(どちらを取得するかは、Bボタン押下で変更できる仕組みあり)、それが BLE経由でブラウザに送られます。ブラウザ側では、受け取った値を使ってリアルタイムにグラフを描いています。

プログラム

M5Stack Core2 で動作している UIFlow のプログラムと、ブラウザ側で動いている HTML+JavaScript のソースをそれぞれ記載します。

UIFlow

UIFlow側は、以下のような仕組みにしてます。

UIFlowのプログラム.jpeg

  • 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

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2