BLE早わかり

非公式訳(原典: https://www.arduino.cc/en/Reference/CurieBLE

CurieBLEライブラリー

 

Arduino/Genuino 101とCurieBLEライブラリーとを組み合わせると、BLEの機能が使えるようになるため、スマートフォンタブレットなどのデバイスを相手にデータのやり取りができます。

 

BLE早わかり

Bluetooth 4.0は、普通のBluetooth(いわゆる「Bluetoothクラシック」)と、新たに追加されたBluetooth Low Energy(略してBluetooth LEまたはBLE)の2つから成ります。BLEは、低データレート用、低消費電力用に特化されていて、元々は、シンプルなコイン型リチウム電池で駆動できるように設計されました。

Bluetooth LEの無線機は、非同期シリアル通信(UART)を基本とする普通のBluetoothとは違って、地域(コミュニティ)の掲示板のような働きをします。Bluetooth LEの無線機に接続する各コンピューターは、掲示板を読む住人のようなものです。各無線機は、掲示板か閲覧者かいずれかの役割を果たします。掲示板(Bluetooth LEの世界では「peripheral」という)は、コミュニティに属しているすべての無線機に対してデータを掲示します。閲覧者(Blueooth LEの世界では「central」という)は、関心のある情報を掲示している掲示板のいずれかからデータを読み取ります。peripheralは、閲覧者の求めるデータを持っているわけですから、クライアントサーバーモデルでいえばサーバーのようなものです。同じように、centralは、peripheralの持っているデータを読み取るわけですから、クライアントサーバーモデルでいえばクライアントのようなものです。

【図】

peripheralは掲示板、centralは掲示板の閲覧者であると考えてください。centralは、サービスを閲覧してはデータを取得し、また次のサービスへと移動します。ひとつひとつの処理は数ミリ秒で済みますので、ひとつのperipheralのデータを複数のcentralで取得することができます。

peripheralに掲示されるデータはいくつかのserviceから成っていて、さらに各serviceはいくつかのcharacteristicに分かれています。serviceは掲示板に掲示された「貼り紙」、characteristicは、その貼り紙に書かれたひとつひとつの文章であると見なすことができます。peripheralは、データを更新する必要があるときにcharacteristicを更新するだけであり、そのデータをcentralが読む・読まないについては気にしません。centralは、peripheralに接続してから、必要な欄を読み取ります。読み書きが両方とも可能なcharacteristicもあり、その場合はperipheralとcentralとでデータの交換が可能です。

 

notify

Bluetooth LEには、データが変化したら知らせる「notify」というしくみが規定してあります。characteristicのnotifyが機能している状態でそのcharacteristicが変化すると、受信機が読み取りコマンドを発行しなくても、新しい値が自動的に受信機に送信されます。このしくみは、データを絶え間なく送信するのによく使われます(加速度計などのデータを送信する場合)。notifyに似た「indicate」というしくみもあります。indicateの場合は、プッシュされたデータの受信確認を受信機が送信します。

Bluetooth LEのクライアントサーバー構造は、notifyというしくみを備えていることから、一般に「publish-and-subscribe」モデルと呼ばれます。

 

characteristicを更新する

peripheralは、characteristicにいちじるしい変化の起きたときにそのcharacteristicを更新します。たとえば、スイッチがオフからオンに変化したときや、アナログセンサーの値がいちじるしく変化したときにcharacteristicが更新されるわけです。

characteristicは、変化したときだけでなく定期的に更新することもできますが、characteristicが変化していなければ、処理にかかる電力が無駄になります。

 

centralとperipheral

centralはクライアントです。peripheralを相手にデータの読み書きをします。peripheralはサーバーです。読み取り可能なcharacteristicとしてcentralに向けてセンサーの値を示します。また、読み書き可能なcharacteristicsをcentralに示してアクチュエーター(モーター)やライトなどを制御します。

 

service、characteristic、UUID

peripheraはいくつかのserviceを持っていて、そのserviceはいくつかのcharacteristicを持っています。独自のserviceを定義することもできるし、標準serviceを使うこともできます。

serviceには、「UUID」という番号が個別に付いています。UUIDというしくみはBlootooth以外にも使われています。標準serviceのUUIDは16ビットです。カスタムserviceのUUIDは128ビットです。serviceとcharacteristicの定義がどこまでできるのかは、使用するBLEデバイスとそのファームウェアとによって違ってきます。

 

serviceの設計パターン

characteristicの値はひとつあたり最長20バイトです。これは、serviceを設計するうえで鍵となる制約です。こうした制約がありますので、センサーやアクチュエーターのデータをどう保存するのが一番効果的であるのかを考えなければなりません。一番シンプルな設計パターンは、下の表のように、characteristicごとにセンサーまたはアクチュエーターの値をひとつずつASCII形式で保存することです。

characteristic

加速度計X

200

加速度計Y

134

加速度計Z

150

この方法は、メモリーの使用量が極端に増えるだけでなく、読み取るのにもかなりの時間がかかります。しかし開発とデバッギングにとっては一番シンプルです。

センサーまたはアクチュエーターに値が複数あるときは、下の表のように複数の値をひとつのcharacteristicにまとめてしまうことも可能です。

characteristic

モータースピード, 方向

150,1

加速度計X, Y, Z

200,133,150

このほうが効率的です。しかし20バイトの上限には気をつける必要があります。たとえば、上表の加速度計のcharacteristicはASCII形式で11バイトです。

 

read/write/notify/indicate

centralがcharacteristicに対して実行できるのは下の4つです。

● read: characteristicの現在の値を送信するようperipheralに要求することです。あまり頻繁に変化しないcharacteristic(設定やバージョン番号などに使われるcharacteristic)によく使われます。

● write: characteristicの値を変更することです。モーターのオン、オフを切り替えるようperipheralに命じるようなコマンドなどによく使われます。

● indicatenotify: centralが絶えず要求しなくてもcharacteristicの最新の値を連続して送信するよう、peripheralに要求することです。

 

advertisingとGAP

BLEデバイスは、General Advertising Profile(GAP)を使ってadvertisingを行うことにより、自分の存在を他のBLEデバイスに知らせることができます。advertisingパケットには、デバイス名などの情報のほか、当のデバイスの持っているサービスの一覧を含めることができます。

advertisingパケットはサイズに限界があります。advertisingパケットに含めることができるのは、128ビットのservice UUIDひとつだけです。デバイス名はあまり長くしないでください。さもないとadvertisingパケットに収まらなくなります。

advertisingされないserviceを設けることも可能です。こうしたserviceについても、centralはconnection/bondingプロセスを通じて知ることができます。ただし、advertisingされないserviceを使ってデバイスをdiscoverすることはできません。このことが問題にならない場合もあります。たとえば、カスタムserviceを持っているカスタムperipheralデバイスなどがそうであり、その場合でも、central側のアプリは、peripheral側にBattery Serviceなどのサービスのあることを知ることができます。

 

GATT

Bluetooth LEプロトコルは複数のレイヤー上で稼働します。そのなかにGeneral Attribute Profile(GATT)というレイヤーがあります。serviceとcharacteristicとを定義するレイヤーであり、serviceとcharacteristicとに対してread/write/notify/indicateという処理を実行するレイヤーです。GATTに関する資料を読んでいると、GATTはクライアントサーバーモデルのひとつであるという記述を目にすることがあるかもしれませんが、正確にいえば、必ずしもcentralとperipheralがクライアントとサーバーに相当するわけではありません。ただしほとんどの場合は、peripheralがGATTサーバーであり(serviceとcharacteristicとを掲示するから)、centralがGATTクライアントです。

------------------------ 以下略 ------------------------