【micro:bit 2019】micro:bit と #obniz で BLE ＋ UART を試そうとした話と Mac用ツール（30記事目）

この記事は 12/31 に執筆して、後から 「[micro:bit Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/microbit)」の 13日目 へと登録した記事です。

今年のアドベントカレンダー用に書いた記事の 30記事目で、micro:bit Advent Calendar に登録した記事としては 11記事目になります。

## はじめに

micro:bit と Androidアプリとの間で、BLE ＋ UART での文字列の送受信を試した記事を書きました。

●【micro:bit 2019】micro:bit で BLE ＋ UART による文字列の送受信（29記事目） - Qiita
　https://qiita.com/youtoy/items/46502b9bd17fad16d427

今回は Androidアプリとの間ではなく、obniz との間での通信を試してみようと思います。

## onbiz でのデバイス検索を試す

まずは、公式ドキュメントを見つつ、デバイスのスキャンから試してみようと思います。

●BLE: セントラル-ペリフェラルを探す | obniz js SDK の基礎 | obniz
　https://obniz.io/ja/lessons/obnizjs/lessons_obnizjs_ble_central_search

以下の記載のとおり、条件付での検索もできるようですが、まずは条件なしでの検索を試してみます。

> **条件付き検索**
> すべての検索以外にも以下の指定が可能です。
>
　・advertisementに含まれるUUIDを指定して検索
　・名前(localName)を指定して検索
　・タイムアウトを30秒から変更
　・同一のデバイスでも新しいadvertisementを受け取ったら通知。

[obniz のコンソール](https://obniz.io/ja/console)から、プログラムを書いていきます。
なお、「OBNIZ_ID_HERE」の部分にはご自身の obniz の ID を、「BBC micro:bit [?????]」の部分には、ご自身の micro:bit のローカルネームを設定してください。

```javascript
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://unpkg.com/obniz@3.1.0/obniz.js" crossorigin="anonymous"></script>
  </head>
  <body>
    <h3 class="text-center">BLE</h3>
    <script>
      var obniz = new Obniz("OBNIZ_ID_HERE");
      obniz.onconnect = async function () {
        await obniz.ble.initWait();

        var target = {
          localName: "BBC micro:bit [?????]"
        };

        obniz.ble.scan.onfind = function(peripheral){
          console.log(peripheral.localName)
          console.log(peripheral)
        };
        obniz.ble.scan.onfinish = function(peripheral){
          console.log("scan timeout!")
        };
        obniz.ble.scan.start(target);
      };
    </script>
  </body>
</html>
```
micro:bit のプログラムは、[上でリンクを記載していた記事](https://qiita.com/youtoy/items/46502b9bd17fad16d427)と同じものを用いました（ブロックのうち、半分くらいは不要なものですが・・・）。
<img width="459" alt="Microsoft_MakeCode_for_micro_bit_BLE_UART_MC.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5768419b-bebc-5bc5-4305-28f2f33d566a.jpeg">

そして、上記の obniz のプログラムを実行したところ、以下のとおりコンソールに micro:bit を検索した結果が表示されました。
<img width="389" alt="obniz_-_developer_s_console.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/43fa1f66-c08a-77d1-1840-44e26b7f359b.jpeg">
ちなみに、上記の obniz のプログラム中の「target」で localName をしなかった場合は、端末の周囲に複数の BLE で通信しているデバイスがある場合、それらが全て検出されることになります。
（とりあえずは target を指定しないで、周囲のデバイスの検索をしてみるのも良いかもしれません）

## onbiz との間で BLE通信（ボタンサービスを試す）

UART でのデータ送受信を試す前に、ひとまず micro:bit との間のやりとりを何か試してみようと思いました（いきなり BLE ＋ UART を試そうとして、うまくいかなかった流れがあり・・・）。
以下が分かりやすかったので、こちらの内容を進めました。

●【BLE初心者必見】obniz BLEでmicro:bitの加速度センサーとボタンの状態を取得する方法 - Qiita
　https://qiita.com/Google_Homer/items/7b8ad409d8575c5647d1

micro:bit側は、上記の記事の内容をベースにしたものを作りました（上記の記事のもの、そのままでも大丈夫です）。

また obniz側も変更を加えたものを用い、変更後のプログラムの全体は以下となりました。
なお、「OBNIZ_ID_HERE」の部分にはご自身の obniz の ID を、「BBC micro:bit [?????]」の部分には、ご自身の micro:bit のローカルネームを設定してください。

```javascript
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://unpkg.com/obniz@3.1.0/obniz.js" crossorigin="anonymous"></script>
  </head>
  <body>
    <h3 class="text-center">BLE 2</h3>
    <script>
      var obniz = new Obniz("OBNIZ_ID_HERE");

      //ボタンサービス
      const UUID_BUTTON_SERVICE                    = "E95D9882251D470AA062FA1922DFA9A8";
      const UUID_BUTTON_A_SERVICE_CHARACTERISTICS  = "E95DDA90251D470AA062FA1922DFA9A8";

      var target = {
        localName: "BBC micro:bit [?????]"
      };

      obniz.onconnect = async function () {
        await obniz.ble.initWait();

        var peripheral = await obniz.ble.scan.startOneWait(target);
        if(peripheral){
          console.log("found");

          var connected = await peripheral.connectWait();
          if(connected){
            console.log("connected");

            obniz.repeat( async function(){
              //ボタン取得 0:OFF 1:単押し 2:長押し
              var A = await peripheral.getService(UUID_BUTTON_SERVICE).getCharacteristic(UUID_BUTTON_A_SERVICE_CHARACTERISTICS).readWait();

              //取得データ表示
              obniz.display.clear();      
              obniz.display.print("ボタン A:"+A);
              console.log("ボタン A:"+A);
            },500)

          }else{
            obniz.display.clear();
            obniz.display.print("micro:bit Connect Error"); 
          }
        }
      };
    </script>
  </body>
</html>

```

上記を動作させたところ、micro:bit のボタンの状態を、コンソール上や obniz のディスプレイ上に表示させることができました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> と micro:bit で BLE。<a href="https://twitter.com/google_homer_?ref_src=twsrc%5Etfw">@google_homer_</a> さんの Qiita の記事にあった、ボタンサービスをお試し。 <a href="https://t.co/sct2ZWm03u">pic.twitter.com/sct2ZWm03u</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1211992737366458368?ref_src=twsrc%5Etfw">December 31, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## onbiz との間で BLE ＋ UART

それでは、obniz と micro:bit との間で、BLE ＋ UART の通信を試していきたいと思います。
上で試したボタンサービスに関する内容では、「getService と getCharacteristic」で指定していたものがボタンに関するものを使っているため、この部分は置きかえが必要です。

UART を使う場合の情報を探してみていて、以下のサイトがでてきました。

●Bluetooth Developer Studio - Profile Report
　https://lancaster-university.github.io/microbit-docs/resources/bluetooth/bluetooth_profile.html

ここから UART 関連の情報を抜粋してみます。

> **UART SERVICE**
　UUID： 6E400001B5A3F393E0A9E50E24DCCA9E
>
**UART SERVICE - CHARACTERISTICS**
　・TX Characteristic
　　UUID： 6E400002B5A3F393E0A9E50E24DCCA9E
　・RX Characteristic
　　UUID： 6E400003B5A3F393E0A9E50E24DCCA9E

ひとまず、「TX と RX のうち RX のほう」をを試してみることにします。

### micro:bit のプログラム

micro:bit 側のプログラムを、前に記事を書いたときのものから少し変えて、以下のようにしてみました。

<img width="612" alt="Microsoft_MakeCode_for_micro_bit_001.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5ef1d9ce-87f8-c9be-7386-55456369298d.jpeg">

意図通りの動作をしているか、Androidアプリでデータを受信して確認してみて、以下のとおり加速度のデータを取得できていました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">micro:bit の加速度のデータを、BLE でAndroidスマホに送ってみた。<br><br>加速度計サービスを使う方法でなく、加速度の値を UARTサービスで送信。 <a href="https://t.co/MSyHRHyof9">pic.twitter.com/MSyHRHyof9</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1212002779721371650?ref_src=twsrc%5Etfw">December 31, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### obniz のプログラム

上記のプログラムの

```javascript
  //ボタンサービス
  const UUID_BUTTON_SERVICE                    = "E95D9882251D470AA062FA1922DFA9A8";
  const UUID_BUTTON_A_SERVICE_CHARACTERISTICS  = "E95DDA90251D470AA062FA1922DFA9A8";
```

　↓

```javascript
  // UARTサービス
  const UUID_UART_SERVICE                    = "6E400001B5A3F393E0A9E50E24DCCA9E";
  const UUID_UART_SERVICE_CHARACTERISTICS_R  = "6E400003B5A3F393E0A9E50E24DCCA9E";
```

とりあえず、これで動かしてみました。
そして、以下のエラーが・・・（やはり、どんな形でデータが来るのかや、どのようにデータを取得すれば良いのかを、きちんと見ないとダメでした・・・）。
<img width="505" alt="obniz_-_developer_s_console001.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/0bd284c9-d1f8-f03c-71af-e059553e1ae7.jpeg">

## 情報を色々調べてみる

ここで、BLE 周りの情報をあらためて調べて見ました。
その中で「Mac上でデータを便利に見られたりしないかな」と思って調べた、解析に使えそうなツールを記載しておこうと思います。

### Mac上で BLE の情報を解析

こちらは、Mac上 で BLE の情報を見るツールの話になります。
「Apple製のツール Bluetooth Explorer」が良い感じらしいです。以下の 2つの記事の情報をまとめると、2019/12/31時点でこのツールを導入するには、
　Xcode のメニューの「 [Xcode] > [Open Developer Tool] > [More Developer Tools...] 」を選択 ⇒ 起動したブラウザのページからログイン ⇒ Additional Tools for Xcode をダウンロード
という手順を踏めば良さそうでした。

●Apple製開発ツール「Bluetooth Explorer」でBLEデバイスのGATT仕様を確認する - Qiita
　https://qiita.com/shu223/items/46dabad41cf2eed67d13

●Xcode8以降でHardware IO Tools を使う方法は Additional Toolsをインストールすればいい - Qiita
　https://qiita.com/rd0501/items/f3e3094f79c2ace3b193

以下が、ダウンロードページのキャプチャ画像です。
<img width="506" alt="More_Software_Downloads_-_Apple_Developer.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2305afb5-40dd-fb69-1ab4-2cae5973df80.jpeg">

そして、このツールをダウンロードして、実際に使ってみました。
使い方は上記のページに書かれたとおり、「Bluetooth Explorer のメニューの [Devices] > [Low Energy Devices] で起動」という流れで、以下のとおりデバイスのリスト等を閲覧することができました。

<img width="421" alt="Low_Energy_Devices.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6aed63c0-ad9d-d245-886b-b113cc287715.jpeg">

良い感じに情報を閲覧できそうで、別途、いろいろ機能を試してみようと思います。

## おわりに

micro:bit と obniz の間での、BLE ＋ UART を使ったデータ送受信は途中までとなりましたが、その過程で BLE に関する色々な情報やツールの情報などが得られて良かったです。
引き続き、着実に BLE活用を進められればと思います。

## 追記

以下、今回の続きを進めるのに使いそうな情報。

- Apple製「Bluetooth Explorer」でBLEデバイスを操作する - Qiita
    - https://qiita.com/te20/items/694df215de1a189a0e09
- 【BLEを使う】GATT（Generic Attribute Profile）概要 - 叶鋼は午前1時に計算をする
    - http://yegang.hatenablog.com/entry/2014/08/09/195246

あと、Python での利用とかも調べてみようかな。

- PythonからBLEを制御するライブラリの調査 - masato-ka's diary
    - http://masato-ka.hatenablog.com/entry/2017/09/10/153555
- Raspberry Pi で bluepy を使ってmicro:bitをコントロール - Qiita
    - https://qiita.com/FiveOne/items/ea04b74271da0f382ed6 
- Raspberry pi と watchXでBLE通信 - Qiita
    - https://qiita.com/tom_S/items/eab1a31e6d5da80e831b

あとは、micro:bit との連携のサンプルがけっこう見つかる気がする Web Bluetooth API とかも試してみるかな。

- Web Bluetooth API を使ってブラウザだけでMicro:bitとBLE通信してみる。 – GUNMA GIS GEEK
    - https://shimz.me/blog/microbit/5456
- micro:bitとWebBluetoothで通信してみました - Qiita
    - https://qiita.com/yokmama/items/5522fabfb5b9623278e2 
- micro:bitのLEDをWeb Bluetooth APIで制御してみる - Androidのメモとか
    - https://relativelayout.hatenablog.com/entry/2018/02/02/224914 
- Web Bluetooth APIを使って体温計のデータをブラウザでBLE経由で受信してみた - Qiita
    - https://qiita.com/megadreams14/items/02f524540896449944cd