Genuino 101/Arduino 101で搭載されたBluetooth LE(以下BLE)の使い方をまとめておきます。
今回の通信イメージとしては、Genuino101をペリフェラル側としてアドバタイジングを開始します。スマホやPC等のセントラル側からアドバタイジングされたペリフェラルを見つけ出しBLE接続。ペリフェラルはセントラルと接続されたら処理を開始するといった感じです。CurieBLEライブラリには多くの関数が準備されてますがここでは一部を説明します。
BLEサービス、キャラクタリティクスの設定
はじめにライブラリのインクルード、ペリフェラルのインスタンス、Service、Characteristicの定義を行います。
#include "CurieBLE.h" BLEPeripheral blePeripheral; BLEService CurieBLEService("19B10010-E8F2-537E-4F6C-D104768A1214"); BLECharacteristic axisCharacteristic("19B10011-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite, 20);
サービスの設定は BLEService yourServiceName(“UUID”);自分でサービス名とUUIDを設定します。キャラクタリスティックはBLECharacteristic yourCharacteristicName(“UUID”, properties, maxLen);で設定します。キャラクタリスティック名とUUIDは自分で設定。第2引数でread/write/notifyを設定、ここではreadとwriteを設定してます。第3引数でbyte数を設定します。byte数は20byteまで。
characteristicはint型やfloat型など一般的な変数型のライブラリも用意されてます。
BLE初期化処理
setup()内で初期化設定を行います。
void setup() { blePeripheral.setLocalName("CurieBLE"); blePeripheral.setAdvertisedServiceUuid(CurieBLEService.uuid()); blePeripheral.addAttribute(CurieBLEService); blePeripheral.addAttribute(axisCharacteristic); blePeripheral.begin(); }
ローカル名を設定。ここで設定したローカル名がセントラル側でサービスとして表示されます。次にアドバタイジングするサービスとUUIDを設定。サービスとキャラクタリスティックをaddAttributeして、ペリフェラルのアドバタイジングを開始して初期化処理は完了です。
イベントハンドラで処理する場合は
yourCharacteristicName.setEventHandler(BLEWritten, exampleCharacteristicWritten); 等とイベントハンドラを設定しておき、callbackで処理する形となりますが、今回は説明を割愛します。
処理部分
loop内でのスケッチです。スマホやPC等とのBLE接続中はwhile()ループで通信処理する方法です。
void loop() { BLECentral central = blePeripheral.central(); if (central) { digitalWrite(13, HIGH); while (central.connected()) { "ここに処理を記述します" } digitalWrite(13, LOW); } }
スマホやPC等のセントラルとBLE接続されたら13pinLEDを点灯します。BLE接続中はwhile()内をループさせて、通信が切断されたら13pinLEDを消灯します。
データ送信のスケッチ例
while()内に記述するスケッチ例です。ここではカンマ区切りの文字配列の送信例となります。
char s[7]; char t[7]; char u[7]; char buf[20]; float pitch = 123.1; float roll = 10.12345; float yaw = -10; dtostrf(pitch, 1, 1, s); dtostrf(roll, 1, 1, t); dtostrf(yaw, 1, 1, u); sprintf(buf, "%s,%s,%s", s, t, u ); int bufSize = strlen(buf); axisCharacteristic.setValue((unsigned char*)buf, bufSize);
ごちゃごちゃ記述してますが、BLE送信しているのは最後の yourCharacteristicName.setValue((unsigned char*)buf, bufSize); 部分だけです。第1引数で送信するデータを、第2引数で送信データのbyte数(20byteまで)を指示します。
このスケッチ例では roll、pitch、yawの3つの値を少数第一位の桁に揃えて、カンマ区切り文字を配列buf[]へ格納してからcharacteristicにセットしてます。
データ受信のスケッチ例
同様にwhile()内のスケッチ例です。ここでは文字配列を受信した場合の処理となります。
if (axisCharacteristic.written()) { if (axisCharacteristic.value()) { for (int i = 0; i < 20; i++) { buf[i] = *(axisCharacteristic.value() + i); } Serial.println(buf); } }
受信したデータは yourCharacteristicName.Value(); から読み込みます。上記のスケッチでは受信した文字配列をbuf[]へ格納してから、シリアルポートへ出力してます。
送受信ともに文字配列の授受を前提として記述しましたが、characteristicにはint型やfloat型も用意されているため、そのまま数値を送信する場合は.setValueでデータを格納/読み込みだけすればO.Kです。
実際には、writtenだけでもイベントハンドラで処理した方が実用的かもしれません。CurieBLEライブラリのおかげでほとんどBLEの中身を知らなくても実装可能で、比較的簡単にスマホやPC等とのBLE無線通信が可能になると思います。今回は一部の関数を説明しましたが、他にも関数が多く準備されてますのでより複雑な処理も可能かと思います。
コメント