【BLE初心者必見】obniz BLEでmicro:bitの加速度センサーとボタンの状態を取得する方法


■簡単すぎるぞBLE

BLEの事は全くわからないんだけど、obnizとmicro:bitでBLEしてみたい方に強くお勧めしたい内容です。BLE、やってみたら実はLチカとさほどかわらないほど簡単だったので、これからBLEを始める方のハードルも下がればうれしいなと思い投稿しました。micro:bitから情報を取得してobnizに表示するBLEサンプルプログラムの作成方法を解説します。obnizとmicro:bitの基本操作については知っている事を前提で説明していきます。

■紹介するプログラムの概要

micro:bitの加速度センサーの値とボタンの状態をBLE通信を使って取得して、obnizに表示するプログラムです。BLEは親子関係で通信するので、両方のプログラムをつくります。micro:bit側は「ペリフェラル」と呼ばれる子供モードで動作するようなので、obniz側は「セントラル」と呼ばれる親のモードでプログラムします。micro:bit側はBLEの知識はほとんど不要です。obniz側のセントラルも予想に反してscan→connect→readWaitという3つの簡単な手順を踏むだけです。micro:bit側はブロックで、obniz側はHTML JavaScriptでそれぞれプログラミングします。

■プログラム動作のデモ動画

まずは、デモ動画から。
micro:bitを左右(X)、前後(Y)、表裏(Z)に傾けたたり、左ボンタ(A)、右ボタン(B)を押したりしています。この各動作と、obnizのDisplayに表示された数値の対応を見て下さい。
https://youtu.be/bF-WuW8rL68

■プログラム作成の大まかな手順

プログラム本体以外に、ほんの少し設定なんかも必要です。おおむね下記手順です。
【micro:bit側】
 ・拡張機能のbleutooth機能を有効にする
 ・No pairingモードに変更する
 ・micro:bit側のプログラムをつくる
 ・micro:bitのBLEデバイス名を調べる
【obniz側】
 ・obniz側のプログラムをつくる

■順詳細手順

【micro:bit側】拡張機能のbluetooth機能を有効にする

下記手順で拡張機能のbletoothを有効にします。

(参考情報)
まぎらわしいのですが、micro:bitのBluetooth機能には「無線」と「bluetooth」の2つがあるようです。「無線」はmicro:bit間でのみ通信する機能、「bluetooth」はobnizのような一般的な機器とBLE通信する機能のようです。2つ同時には使えないので、ブロックメニュー自体を入れ替えて使う形になっているようです。

【micro:bit側】No Pairingモードに変更する

これはよくわからないのですが、下記のように設定する必要があるようです。
設定歯車でプロジェクトの設定に入り、No pairingを設定して下さい。

【micro:bit側】micro:bit側のプログラムをつくる

しゃれにならないほど簡単です。bluetoothブロックの「加速度計サービス」「ボタンサービス」起動するようにするだけです。動作確認しやすいように接続/切断でLED表示するようにもしましたが、何ならこの部分すら不要です。obniz側では、この2つのサービスとやり取りをしてデータを取得することになります。このサービスは相手が動いていないとエラーになるというものではなく、話しかけられたら答えるという仕組みのようで単独で動作します。

【micro:bit側】micro:bitのBLEデバイス名を調べる

つくったmicro:bit側のブロックプログラムを起動して、スマホのBluetooth設定画面なんかでスキャンします。何となくmicro:bitという文字を含む機器から当たりをつけてます。私のmicro:bitは"BBC micro:bit [pevov]"という名前でした。これを、次に説明するobniz側のプログラムに設定します。

【obniz側】obniz側のプログラムをつくる

micro:bitから加速度X/Y/Zの値と、ボタンA/Bの状態を取得して表示します。BLEセントラルは、scan→connect→readWaitという流れが基本のようです。加速度はバイナリで返されるので普通の数値に変換しています。

下記2箇所を自分用に設定すれば動くはずです。
 ・const MICROBIT = { localName: "BBC micro:bit [pevov]" }
 ・new Obniz("XXXX-XXXX")

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/[email protected]/obniz.js" crossorigin="anonymous"></script>
</head>
<body>
obniz micro:bit_BLE_repeat_SAMPLE
<script>

//各サービスのUUIDは下記サイトで確認できる(全micro:bit共通)
//https://lancaster-university.github.io/microbit-docs/resources/bluetooth/bluetooth_profile.html
//加速度計サービス
const UUID_ACCELEROMETER_SERVICE                  = "E95D0753251D470AA062FA1922DFA9A8";
const UUID_ACCELEROMETER_SERVICE_CHARACTERISTICS  = "E95DCA4B251D470AA062FA1922DFA9A8";
//ボタンサービス
const UUID_Button_Service                         = "E95D9882251D470AA062FA1922DFA9A8";
const UUID_Button_A_Service_CHARACTERISTICS       = "E95DDA90251D470AA062FA1922DFA9A8";
const UUID_Button_B_Service_CHARACTERISTICS       = "E95DDA91251D470AA062FA1922DFA9A8";

//自分のmicro:bitのBLEの名前  
const MICROBIT = { localName: "BBC micro:bit [pevov]" };

var obniz = new Obniz("XXXX-XXXX");
obniz.onconnect = async function () {

   var peripheral = await obniz.ble.scan.startOneWait(MICROBIT);
   var connected = await peripheral.connectWait();
   if ( connected ){  
      obniz.repeat( async function(){

         //加速度取得 各-1000ぐらい~+1000ぐらいの範囲
         var data = await peripheral.getService(UUID_ACCELEROMETER_SERVICE).getCharacteristic(UUID_ACCELEROMETER_SERVICE_CHARACTERISTICS).readWait();   
         //バイナリの加速度を数値に変換(符号付き・2バイト・リトルエイディアン)
         var X = (data[1]*256)+data[0];if (X & 0x8000) X=-((X-1)^0xffff);
         var Y = (data[3]*256)+data[2];if (Y & 0x8000) Y=-((Y-1)^0xffff); 
         var Z = (data[5]*256)+data[4];if (Z & 0x8000) Z=-((Z-1)^0xffff); 

         //ボタン取得 0:OFF 1:単押し 2:長押し
         var A = await peripheral.getService(UUID_Button_Service).getCharacteristic(UUID_Button_A_Service_CHARACTERISTICS).readWait();
         var B = await peripheral.getService(UUID_Button_Service).getCharacteristic(UUID_Button_B_Service_CHARACTERISTICS).readWait();

         //取得データ表示
         obniz.display.clear();
         obniz.display.print("加速度 X:"+X);
         obniz.display.print("    Y:"+Y);
         obniz.display.print("    Z:"+Z);        
         obniz.display.print("ボタン A:"+A+" B:"+B);         
      },10)

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

■まとめ

BLE、やってみたらとてもハードルが低かったです(奥は深いのかもしれないが)。これで、ボタン電池でも駆動できる無線接続の加速度センサーを、たったの2000円で手に入れたことになります。obnizとmicro:bitをBLEで連携させる事で、ますますobnizで面白いことができそうです。

■Appendix

今回micro:bitから加速度とボタンのサービスを取得しましたが、その他にも地磁気センサーやLED表示状態なんかも取得できるようです。これらの情報にアクセスするにはUUIDと呼ばれる長い16進のような情報が必要です。[こちら]のサイトに情報が載っていますので参考にして下さい。