[Micro:bit] Bluetooth関連の調査

調査の目的

  1. Micro:bitをBlutooth通信で外部から制御する方法で何があるのか、何ができそうなのか知りたい
  2. Bluetooth?のジョイスティックコントローラの入力をMicro:bitに伝えたい
  3. Micro:bitでBluetooth経由の入力をイベント?として拾いたい

なぜジョイスティックなのか?

PCと接続できるのはわかっているし、それ相当のこと(例えばキーボード入力など)ができるのは想像がつく。が、子供が操作することを目的としているので、コントローラのほうが楽しそう。

開発環境と基本情報

Microsoftが提供しているWebブラウザで使用するブロックエディタ。ブロックコードとJavascriptを切りかえることができる。一度ロードしてキャッシュがあれば、オフラインでも使用できる。アカウント作成やログインが必要ない。とても優秀なエディタ。
Microsoft Block Editor

Micro:bitのボタン操作、Pin制御、LED制御などほとんどの制御が定義されている。
Micro:bitのblutoothプロファイル

Bluetoothについての記述
About Bluetooth

Bluetoothの基本的な知識

  • セントラルとペリフェラル
    USBのホストとクライアントデバイスの関係とほぼ同じ。セントラルがUSBホスト、ペリフェラルがクライアントというイメージ。
  • データの通信方式
    Bluetoothのすべてのサービスは,GATT(Generic ATTribute Profile)に基づいて作成される。GATTは入れ子になっており、その中のキャラクタリスティックと呼ばれる属性があり、アクセス方法が定義されてルール化されている。
    実際のデータのやり取りでは、このキャラクタリスティックに対して値を書いたり,その値を読んだりすることで行われる。"データを送信する"というのは、キャラクタリスティックに値を書き込んで送信することになる。"データを受信する"は、キャラクタリスティックの値を読み取る。
  • イベント
    このキャラクタリスティックが書き換えられて,値が変更された時にその通知を受け取れる仕組みをNotifyと呼ぶ。常にデータが書き換わったかを監視するのは省電力に反する為、書き換わったときのみこのNotifyによって通知することによって最低限の通信の留める仕組みになっている。
  • サービスやキャラクタリスティックはUUIDで識別される
    同時に沢山の機器と通信するため、サービスやキャラクタリスティックに固有のUUID(Universally Unique IDentifier)が発番されており、16バイトの値で定義されている。なおBluetooth SIGで公式に定義されているものは、先頭の4バイト(または2バイト)のみで識別可能。オリジナルのサービスなどは16バイトを使用するルールになっている。

BluetoothのBLE通信の流れ

  1. アドバタイズ(ペリフェラルからセントラル)
    ペリフェラル側がセントラルに認識してもらうため、データを定期的に送信し続けます。この動作をアドバタイジングという。データ長は31バイトと決まっている。サービスの種類やタイムアウト時間などが含まれている。このデータのことをペイロードと呼ぶ。
  2. セントラルがペリフェラルを検出する
  3. ペリフェラルがアドバタイジングを終了する
  4. ペリフェラルの調査
    セントラル側はペリフェラルがどのような通信をするデバイスなのかを調査する
  5. プロファイル情報の送信(ペリフェラルからセントラル)
    ペリフェラルは,自機がどんなサービスを持つデバイスなのを示すプロファイル情報をセントラル側に送信する
  6. データ要求(セントラルからペリフェラル)
    セントラル側がペリフェラル側にプロファイルに基づいたデータを送るよう要求する
  7. データ送信(ペリフェラルからセントラル)
    ペリフェラル側がデータを送信する。なお、送信するデータがどんなものかはUUIDを添えて送信される。
  8. 接続の切断(セントラル)
    セントラルが通信を終了する

ビーコン(Beacon)

一般的なBluetoothの通信は上記の1~8の流れで行うが、ほかにもビーコンという使い方がある。ビーコンは上記手順1のアドバタイズだけを繰り返し実行するもので,ペリフェラルが一方的にアドバタイジングをするだけの使い方をする。発信機やリモコンのような使い方になる。

現時点で使用できる操作

  • Bluetoothパッケージ

あらかじめ、エディタでBluetoothパッケージをインストールしておく。

Micro:bitに搭載されている各種センサーやGPIO制御を外部から行うための処理が一通りある感じ。Micro:bitをデバイスとして、スマホアプリやPCからの制御が想定できる。

microbit_bluetooth0
microbit_bluetooth

  • Deviceパッケージ

あらかじめ、エディタでdeviceパッケージをインストールしておく。

こちらはおそらくMicro:bitにデバイス接続されたBluetooth機器との通信イベントのパッケージと思われる。いろいろあったが、とりあえずゲームパットに関するものが以下になる。入力としては、A~B、1~4までの"押した"、"離した"のイベントのみ。

microbit_bluetooth1
microbit_bluetooth2

bluetooth接続先デバイスであるゲームパットボタンが押下された時のmicro:bit側のブロックコードのJavascriptが以下になる

devices.onGamepadButton(MesDpadButtonInfo.ADown, () => {
    pins.servoSetPulse(AnalogPin.P0, 1500)
})

onGamepadButtonイベントを追っかけてみる
Github : Microsoft/pxt-microbit
On Gamepad Button - Microsoft MakeCode

devices.tsファイルで同名メソッドがあるので、たぶんこれである。(.tsファイルってなんだ?TypeScript?)

//pxt-microbit/libs/devices/devices.ts
namespace devices {
    export function onGamepadButton(name: MesDpadButtonInfo, body: Action) {
        control.onEvent(DAL.MES_DPAD_CONTROLLER_ID, name, body);
    }
}
//pxt-microbit/sim/state/misc.ts
namespace pxsim.control {
    export function onEvent(id: number, evid: number, handler: RefAction) {
        pxtcore.registerWithDal(id, evid, handler)
    }
}
namespace pxsim.pxtcore {
    export function registerWithDal(id: number, evid: number, handler: RefAction) {
        board().bus.listen(id, evid, handler);
    }
}

ゲームパッドのボタンIDの定義?Bluetoothというキーワードが出てきた。MESEvents.hでイベントが定義されているようだ。

//pxt-microbit/libs/core/dal.d.ts
declare const enum DAL {
    // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MESEvents.h
    MES_DPAD_BUTTON_A_DOWN = 1,
    MES_DPAD_BUTTON_A_UP = 2,
    :
    MES_DPAD_BUTTON_1_DOWN = 9,
    MES_DPAD_BUTTON_1_UP = 10,
    :
}

MES events

上記のMESEvents.hを探すと、ランカスター大学のmicrobit関連のコードにたどり着く。

//https://github.com/lancaster-university/microbit-dal/blob/master/inc/bluetooth/MESEvents.h
#define MES_DPAD_CONTROLLER_ID              1104
#define MES_DPAD_BUTTON_A_DOWN              1
#define MES_DPAD_BUTTON_A_UP                2
:

BBC micro:bit Bluetooth Profile
That IoT Thing
Bluetooth Event Service

以下にアクセスすると、ラジコンバギー側のサンプルブロックコードが表示される。
Bluetooth controlled micro:bit buggy

Mobile Apps for micro:bit

専用のAndroidやiOSアプリを起動してMicro:bitとペアリングを済ませた状態で、ゲームパッドを操作することによって、MES_DPAD_CONTROLLER_IDのイベントをNotifyしていると思われる。
microbit_buggy

ほかにもMES_DPAD_CONTROLLER_IDあたりを検索すると、以下のようにMicro:bitとPCを繋いでいる人いることがわかった。新しいキーワードとしてWeb Bluetoothというのが出てくる。どうもChromeブラウザやSafariなどでブラウザ経由でBluetooth接続できるらしい。

Reveal.jsをMicro:bit(chibi:bit)でコントロールする。
Web Bluetooth API を使ってブラウザだけでMicro:bitとBLE通信してみる。
micro:bitとWebBluetoothで通信してみました

どうもNode.jsのライブラリであるnode-bbc-microbitを使用することで、Micro:bitをBluetoothでパソコンに簡単に繋ぐことができるようだ。

Github : sandeepmistry/node-bbc-microbit

いろいろ調べていくと、C/C++を利用してARMマイコンとしてプログラミングする内容にたどり着く。上記のdeviceパッケージもまだ"ベータ"版なので、いずれはブロックコードできると思われるが、ちょっと趣旨が異なるかもしれない。いずれにしてもちょっと敷居が高くなる。
The micro:bit runtime and mbed programming

Bluetooth Pairing