見出し画像

LEGO Marioをセンサとして利用したい(2)

今回は、前回に引き続きBLEの基礎知識を整理します。まずは、BLEのデータ通信について勉強していきたいと思います。

この記事の内容は未完です。BLE予備知識ゼロ、もちろんLEGO Wireless Protocolの知識もゼロ、電子工作は趣味レベルの自分が、レゴマリオでセンサの値を読み取るまでの現在進行系のログです。

前回のおさらい

前回の記事では、LEGO MarioがBLEでいうペリフェラルとして動作し、セントラルとLEGO Wireless Protocolを通じてお話ししてることを知識として仕入れ、実際にBLEでPCと接続するところまでやりました。

BLEの通信のお作法

BLEはGATTという通信のお作法に則ってデータをやり取りをするそうです(ざっくり)。正確な情報については以下の記事が詳しいです。

抑えるべきは以下の点かと思われます。

- ペリフェラル(センサー側)は1つ以上のサービスを持っている
- 1つのサービスには1つ以上のキャラクタリスティックを持っている
- すべてのサービスおよびキャラクタリスティックにはUUIDを持つ
- キャラスタリックはValueとPropertyを持っている
- PropertyはRead, Write, Notifyなど可能な操作が列挙されている

言葉だけではイメージがつきにくいかもしれないですが、階層構造(ツリー構造)になっているだけで大変簡単です。SNMPのMIB/OIDに近いですし、PCのフォルダ/ファイルの関係とほぼ同様です。1点、BLEに特殊性があるとしたらNotifyがあるということでしょうか。BLEではNotifyすると(Subscribeすると)、キャラクタリスティックのValueが逐一データを受け取ることができます。これは、例えばX秒ごとに温度センサの値を読みにいく、といった処理ではなく、温度が変わったらペリフェラル側からセントラルに値が変わったことや新しい値を通知することができるというものです。イベントリスナ/ディスパッチャみたいなものですね!

ということで、早速レゴマリオを例にこの概念を腑に落としていきます。
前回も利用した、Bluetooth Explorerの右側に注目します。

画像1

ここから分かることとして、

LEGO Marioには2つのサービスがある(0000~~とFF00~~)
前者のサービスには1つのキャラクタリスティック、後者には3つのキャラクタリスティックがある
一番下のキャラクタリスティック以外Write/WriteWithoutResponse/Notifyが可能

さて、ここで各キャラクタリスティックにReadが無いことについて戸惑います。勝手な個人的なイメージで、レゴマリオの各種センサーに対応するキャラクタリスティックがそれぞれ存在すると勝手に思っていたからです。

試しに各キャラクタリスティックについてNotifyをしてみますが、マリオを触れど、赤いブロックに乗せど、一向にValueが変化することはありません。

おお…神よ…。

LEGO Wireless Protocolの登場

ここで、登場するのがLEGO Wireless Protocolです。

LEGOの製品は、このプロトコルに則ったメッセージを[00001624 -1212-EFDE-1623-785FEABCD123]のキャラクタリスティックを通じてやり取りするようで、レゴマリオも同様だというそうです。※@oobaさんのTweetより

ということで、プロトコルのドキュメントを読んでみます……。が、知識ゼロ分野の英語、実装例サンプルなし、という現代のぬるま湯に浸かりつつあった私では理解が進むのに1日くらい時間を要しました…。

その中で、理解の一助どころか百助くらいになったのが、やはり@oobaさん。以下のリポジトリに含まれるソースコードのおかげもあり、少しずつ自分もLEGO  Wireless Protocolを話すことが可能になってきました。

Hello, LEGO Wireless Protocol!

では、ドキュメントを見ながら、LEGO Wirelss Protocol(LWP)の世界へ一歩を踏み出してみます。百聞は一見に如かずという言葉の通りだと思いますので、とにかくまずはLWPでキャラクタリスティックを通してデータをやり取りする感じを掴んでみたいと思います。

Bluetooth Explorerで以下を実行します。

1) LEGO Marioに接続
2) 00001624 -1212-EFDE-1623-785FEABCD123のキャラクタリスティックを選択し、右下のReg Notifyを押す(Notifyの開始)
3) 下のテキストボックスに「0500010105」を入力
4) データの種類をUTF-8ではなくRawに変更し、Writeを押す

画像2

キャラクタリスティックのValueが【0x13000101064c45474f204d6172696f20202020】に変わっていれば成功です。キャラクタリスティックに特定のデータをWriteした結果、何かしらの値が返ってきました。

返ってきたこの値、実はデータ部はASCIIコードになっています。なので、Hex => ASCIIをしてあげます。この手の変換サイトがたくさんありますし、 例えばブラウザの開発者ツールなど、javascript環境でデコードしてみます。

console.log( String.fromCharCode(...[0x13,0x00,0x01,0x01,0x06,0x4c,0x45,0x47,0x4f,0x20,0x4d,0x61,0x72,0x69,0x6f,0x20,0x20,0x20,0x20]) );

画像3

すると、「LEGO Mario」の文字が!

データの詳しい意味は置いておいて、LEGO Marioとはじめてお話ができました。あとは、センサの値を取得するためのメッセージを調べればセンサ値が取得できるものと思われます…!

次回は、より踏み込み、LWPについて詳しく理解していこうと思います。

(その3 - LEGO Wireless Protocolの基本を理解する - へ続く)


この記事が気に入ったらサポートをしてみませんか?