見出し画像

LEGO Marioをセンサとして利用したい(3) - LEGO Wireless Protocolことはじめ

今回は、前回送ったコマンドとその結果をLEGO Wireless Protocol(LWP)の仕様書を見ながらデコードし、LWPへの理解をより深めていきたいと思います。

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

前回のおさらい

前回の記事では、LEGO Marioで利用されているBLEのデータ通信について理解を深め、おおよそのデータのやり取りに見当をつけ、実際に意味の理解を無視してレゴマリオのAdvertising NameであるLEGO Marioという文字列をレゴマリオ本体から取得するところまでをやりました。

あらためてLEGO Wireless Protocolとは

LEGO Wireless Protocolとは何か。ドキュメントの冒頭部を引用します。

The LEGO Bluetooth 3.X Hub Profile consists of a single Bluetooth LE GATT service. The service allows users to read info about the LEGO Hub (name, battery level, etc.) and to interact with any sensors and motors connected to it.

すなわち、LWPを使うことで、ユーザがLEGO Hubの名前やバッテリーレベルなど各種情報を取得したり、備えているセンサやモータを利用することができます。

 0x0500010105が意味するもの

ここで、前回キャラクタリスティックにWriteした以下のバイト列【0x0500010105】の意味をLWPのドキュメントを読みながらデコードしていきます。※以下、0xで始まる数列はすべて16進数(Hex)です。

わかりやすいよう、1byteごとに区切りましょう。(4bitが2の4乗=16すなわち0から15 <=> 0からfを表現しているので8bitである1byteは16進数でいうと2桁です)

05 00 01 01 05

まず、先頭3byteですが、これはCommon Message Headerと呼ばれ、すべてのメッセージに共通になります。1byte目はメッセージ全体の長さ(byte数)、2byte目は常に0x00、3byte目はMessage Typeとなります。

Message Typeには、Hub PropertyやPort Information Requestなどそれぞれ指定するための値が割り当てられています。今回つかったのはHub(=デバイス)の情報に関することを示す0x01 = Hub Propertiesになります。その他、Port(=実際にデータをやり取りする口)へのリクエストにあたる0x21, 0x41などは今後使う予定になりそうです。

画像1

ここまでの先頭3byteでデバイスの情報に関する5byteのメッセージであることを確認することができました。続いて、4byte目をみてみます。4byte目以降のデータについては、3byte目のMessage Typeによってそれぞれ異なります。今回は、Hub Propertiesに関する4byte目以降についてドキュメントを確認します。すると…

画像2

とあります。これで、4byte目がHub Propertiesの中で具体的にフォーカスするPropery、5byte目がそのPropertyに対するOperationであることがわかります。ちなみに6byte目以降はデータ部にあたり、レゴマリオからの返事や、何かをセットする命令(イメージ的にはSetter Method)の"何か"を表現するために使いますので、今回のように取得をお願いする命令(イメージ的にはGetter Method)では通常使いません。

では、4byte目、Propetyの0x01が何か。ドキュメントにある通り「0x01 = Advertising Name」を指します。そして、Operationの0x01は「0x05 = Request Update (Downstream)」と書かれています。

ちなみに、Downstream/Downというのはセントラルからレゴ側への流れ、Upstream/Upはその逆になります。また、Propertyに対するRequest Updateというのは、Valueの更新依頼というイメージが近く、Propertyを更新するというイメージとは異なります。よって、

05 00 01 01 05

は次のような意味をもつ命令であったことがわかります。
すなわち、キャラクタリスティックのValueをHubPropetiesのAdvertisingNameでUpdateして欲しい、という命令です。

無理やり、モダンな命令に翻訳してみたら以下のような感じでしょうか。

//例えば
Charactaristic.value.set( HubProperties.AdvertisingName )

//他にも
HubProperties.getAdvertisingName()

以上で【0x0500010105】が意味したものを理解することができました。

もし同じようにLWPに対する知識がゼロだけど、触ってみたい!という方は、是非この流れを、この記事だけでなくLWPのドキュメントを追いながら体験していただきたいと思います。

画像3

送られてきたデータを解読する

ここまでLWPを理解することが出来たら、書き換えられたValue【0x13000101064c45474f204d6172696f20202020】が意味するものもドキュメントを追いながら容易に解読できるかと思います。

それでは早速いってみましょう。例によって、見やすさの為に1byteごとに区切ります。

13 00 01 01 06 4c 45 47 4f 20 4d 61 72 69 6f 20 20 20 20

先頭3byteはCommon  Message Headerであることは全てのメッセージで共通ですので、まずはそこに注目します。するとこのメッセージが18byteでHub Propertiesに関することがわかります。また、4byte目は0x01ですので先程同様Advertising Nameに関することだとわかります。そして、5byte目、Operationは0x06であり、Update (Upstream)であることが分かります。

ここまでで、先程の命令によってUpdateした内容であることがわかります。6byte目以降がPayload・実データになるため、【4c 45 47 4f 20 4d 61 72 69 6f 20 20 20 20】が実際のAdvertising Nameであることが分かります。

どうでもいいですが、ASCII表では空白は0x20、Aは0x41、aは0x61です。なので自力でエンコードしても「LEGO Mario    」であることがわかります。

バッテリーレベルを取得する例

同様に、バッテリーレベルを取得してみましょう。それと思わしき、Battery Voltage[%]は先程と同じくHub Propertiesの中にあります。対応するPropertyは0x06です。同様にRequest Update(0x05)を行いますので、送るべき命令は

0500010605

となります。そうすると、自分の手元には次のような値が返ってきました。

0x060001060649

これを解読すると、Hub Properties(0x01)のBattery Voltage(0x06)のUpdate(0x06)で内容は0x49 = 73[%]であることがわかります。 (Maxは0x64 = 100)

画像4

以上で、LEGO Wireless Protocolの基本についての理解は完了です。

次回予告

次回はいよいよ、Hub Propertiesではなくセンサのデータが入ってくるであろうPortに対するデータを取得について手を動かしながら試していきます。

そこである程度の見通しがついたら、今回はWeb Bluetoothもしくはnoble(noble-mac)を使ってサンプルプログラムを組んでいこうと思います。


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