概要
BLE通信の概要を、M5StickCでBLE MIDIコントローラーを作ってみよう(1)のソースをベースに説明していきます。
*誤解を招くようなことも記載していきますが、分かりやすさを優先しました。
具体的なプログラムの説明の前に、まずBLEって、どういうもの?、ということを説明していきます。
BLEとは?
BLEは、Bluetooth Low Energyの略ですが、物理層こそある程度Bluetoothと共通点はあるものの(詳細略)、上位レイヤーは、大きく異なります。
WibreeからBLEへ
もともと、BLEは、Nokia社中心となって開発したWibreeと呼ばれる通信規格でした。その規格がBluetooth SIGへ移管されて統合された際に、名称がWibreeからBluetooth Low Energyへ変更されました。
従来のBluetoothとの違い
スマートフォン時代になって、大きくBluetooth機器が普及したため、もうそういう声は、全く聞かれなくなりましたが、Bluetoothは、Wi-Fiと比較して、失敗した規格と言われていました。その理由は、用途の融通の利かなさからです。従来のBluetoothは、下記のような用途以外使ってはいけない、という厳格な規格となっています。
- 音楽再生/音楽再生制御
- ヘッドセット
- マウス/キーボード
- シリアル通信
上記の用途は、デスクトップPCが業務や日常の中心だった時代には、無線にする理由がなかったんですね。BLEの開発当時は、ちょうどそんな時代背景だったため、BLEはどんな用途でも使えるよう設計されました。BLEは、名前の通り、低消費電力性が特長ですが、従来のBluetoothとの最大の違いは、このなんでも使えることにあります。
この記事で説明するBLE用途
この記事では、M5StackなどのBLEの搭載された機器(以降、「BLE周辺機器」と呼ぶこととします)を、スマートフォンと繋いで遊ぶ、です。
スマートフォンとの接続まで
接続までの基本的な手順は下記の通りです。
- BLE周辺機器は「自分は、こんな機能を持ってますよ?」という電波を発信し続ける。(Advertising)
- スマートフォンが、BLE周辺機器を探す。
- スマートフォンが、1の電波を見つけたら接続を試みる。
- BLE周辺機器がそれに応答し、接続完了。
この手順を細かく規定してあるのがBLEの「GAP」になります。
接続までのソース解説
//BLE MIDIのサービス
const char *SERVICE_UUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700";
//BLE関連関数
// サーバーのコールバック関数
class cbServer: public BLEServerCallbacks {
void onConnect(BLEServer *pServer) {
isConnected = true;
};
void onDisconnect(BLEServer *pServer) {
isConnected = false;
}
};
void setup()
{
// BLE初期化
BLEDevice::init(DEVICE_NAME);
// サーバーの作成
BLEServer *pServer = BLEDevice::createServer();
// コールバック関数の設定
pServer->setCallbacks(new cbServer());
//アドバタイジングの開始
pServer->getAdvertising()->addServiceUUID(SERVICE_UUID);
pServer->getAdvertising()->start();
}
この部分が「1. BLE周辺機器は「自分は、こんな機能を持ってますよ?」という電波を発信し続ける。」のソースになります。この例では、「BLE MIDI機能(Service)を私は使えますよ」と宣伝しています。BLE MIDI機能であることを示しているのが、"03B80E5A-EDE8-4B33-A751-6CE34EC4C700"という固有値(UUID)です。
(この固有値は、今はMIDI.orgで定められるようになりましたが、もともとは、Appleが独自に定めたものになります。なので、BLE MIDI機器がApple製品が先行しているのは、当然といえば当然ですね。)
スマートフォン接続後
スマートフォン接続後、BLEでできることは3つです。
- BLE周辺機器から情報をスマホに送る(Notify, Indicate)
- スマホからBLE周辺機器の情報を読み取る(Read)
- スマホからBLE周辺機器の情報を送る(Write)
この手順を細かく規定してあるのがBLEの「GATT」になります。
接続語のソース解説
//BLE MIDIのサービスとキャラクタラスティック
const char *SERVICE_UUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700";
const char *CHAR_UUID = "7772E5DB-3868-4112-A1A9-F2669D106BF3";
//BLE MIDIデータ
unsigned char buff[] = {0x80, 0x80, 0xB0, 0x01, 0x64};
//BLE MIDIのCCデータを送信
void notifyCC(int ccNum, int value)
{
//元情報にデータを入れておく
cc[ccNum] = value;
//valueをCC(ccNum)のデータにする
buff[2] = 0xb0;
buff[3] = ccNum;
buff[4] = value;
//MIDIデータをNotify
pCharacteristic->setValue(buff, 5);
pCharacteristic->notify();
}
void setup(){
// BLE初期化
BLEDevice::init(DEVICE_NAME);
// サービスの作成
BLEService *pService = pServer->createService(SERVICE_UUID);
// キャラクタリスティックの作成
pCharacteristic = pService->createCharacteristic(
CHAR_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY
);
// サービスの開始
pService->start();
}
void loop() {
if (isConnected)
{
//センサ等の値をintXに入力(省略)
notifyCC(7, intX);
// 少し休ませる
delay(10);
}
}
*分かりやすくするため、スマートフォンとの接続後は、10msごとにBLE MIDI信号を送るソースに書き換えています。
接続後は、接続前に宣伝(Advertising)した機能(Service)の情報(Charactrastics)を、送受信していきます。今回のソースは、一方的にスマートフォンにBLE MIDI信号を送る(Notify)ものになります。情報(Charactarastics)が機能のどういう情報なのか?、というのを表す固有値(UUID)が、"7772E5DB-3868-4112-A1A9-F2669D106BF3"で、これも、MIDI.orgで定められた「MIDI信号」の値になります。
終わりに
BLE機器を作ろうとすると、
- Central/Peripheral
- Server/Client
- GAP
- Advertise
- GATT
- UUID
- Service
- Charastrastics
- Descriotion(BLE MIDIに必要ないこともあり、今回説明は省略しました。)
あたりの馴染みのない言葉の連発が挫折ポイントになるのではないか?、と感じ、今回の記事は、上記の言葉がどういうものなのか?、というのを意識して投稿しました。
BLE機器の作成のもう一つの挫折ポイントは、基本的になんでもできるが故、何も決まていないので、スマホと接続するBLE周辺機器を作成しようとすると、スマホのアプリも作らなければならないことです。その点、BLE MIDIは、フリーソフトも含め、対応しているiPhone Appが沢山あり、わざわざアプリを自分で作る必要がないので、BLE周辺機器の作成の入門にはもってこいのアプリケーションと言えるでしょう。
参考図書
Bluetooth Low Energyをはじめよう/オライリー
今、市販されている、多分、唯一のBLEの本です。かなり低いレイヤからBLEのことが細かく書かれています。その分、かなり読み込むのが難しい本ではありますが、これが読めれば、多分、後はBLuetoothの公式文章さえあれば、何でもBLE機器は作れるのではないかな?、と思います。この記事でBLEに興味を持ち、更に細かく情報を知りたい方にはオススメの本です。