初めてのBLE (7) micro:bitでペリフェラル④温度キャラをArduinoセントラルで受け取る
前回、BLEのUARTサービスで送受信できることを確認しました。ペリフェラルはmicro:bitです。ここではセントラルにNANO 33 BLE Senseを用い、ArduinoBLEライブラリを使って温度データを取り出します。今回は、characteristics(キャラ)の温度データです。次回UARTの温度データを扱います。
●セントラルでperipheralExplorerを動かす
サンプル・スケッチのperipheralExplorerは、アドバタイズしているペリフェラルを見つけます。オリジナルのスケッチではlocalName()がLEDを見つけると、その中にあるService-Characteristics(キャラ)をすべて表示します。キャラは例えば温度のValueを含んでいれば、そのデータも表示します。
最初に、localName() == "BBC micro:bit [gavag]"とします。これで、ほかのBLEデバイスは無視できます。
explorerPeripheral(peripheral);で、表示された内容です。
ここで必要なのは、
- 温度のサービスUUID=E95D9250-251D-470A-A062-FA1922DFA9A8
- UARTのサービスUUID=6e400001-b5a3-f393-e0a9-e50e24dcca9e
の二つです。温度を取り出します。exploreService()を次のように温度と一致したら、キャラを出力するように変更します。
void exploreService(BLEService service) { // print the UUID of the service if (String(service.uuid()) == "e95d6100-251d-470a-a062-fa1922dfa9a8"){ Serial.print("Service "); Serial.println(service.uuid()); // loop the characteristics of the service and explore each for (int i = 0; i < service.characteristicCount(); i++) { Serial.print(String(i)+" "); BLECharacteristic characteristic = service.characteristic(i); exploreCharacteristic(characteristic); } } }
実行結果です。
キャラUUID=e95d9250-251d-470a-a062-fa1922dfa9a8のValueがほしいので、絞ります。
#include void setup() { Serial.begin(9600); while (!Serial); // begin initialization if (!BLE.begin()) { Serial.println("starting BLE failed!"); while (1); } Serial.println("BLE Central - Peripheral Explorer"); // start scanning for peripherals BLE.scan(); } void loop() { // check if a peripheral has been discovered BLEDevice peripheral = BLE.available(); delay(2000); if (peripheral.localName() == "BBC micro:bit [gavag]") { Serial.print("\nFound address = "); Serial.print(peripheral.address()); Serial.print(" localName = '"); Serial.print(peripheral.localName()); Serial.print("' "); Serial.print(peripheral.advertisedServiceUuid()); Serial.println(); // stop scanning BLE.stopScan(); explorerPeripheral(peripheral); // peripheral disconnected, we are done while (1) { // do nothing } } } void explorerPeripheral(BLEDevice peripheral) { // connect to the peripheral Serial.print("Connecting ... "); if (peripheral.connect()) { Serial.println("Connected"); } else { Serial.println("Failed to connect!"); return; } // discover peripheral attributes // Serial.println("Discovering attributes ..."); if (peripheral.discoverAttributes()) { // Serial.println("Attributes discovered"); } else { Serial.println("Attribute discovery failed!"); peripheral.disconnect(); return; } Serial.print("Device name: "); Serial.println(peripheral.deviceName()); Serial.println(); // loop the services of the peripheral and explore each for (int i = 0; i < peripheral.serviceCount(); i++) { BLEService service = peripheral.service(i); exploreService(service); } Serial.println(); // we are done exploring, disconnect Serial.print("Disconnecting ..."); peripheral.disconnect(); Serial.println("Disconnected"); } void exploreService(BLEService service) { // print the UUID of the service if (String(service.uuid()) == "e95d6100-251d-470a-a062-fa1922dfa9a8"){ Serial.print("Service "); Serial.println(service.uuid()); // loop the characteristics of the service and explore each for (int i = 0; i < service.characteristicCount(); i++) { // Serial.print(String(i)+" "); BLECharacteristic characteristic = service.characteristic(i); exploreCharacteristic(characteristic); } } } void exploreCharacteristic(BLECharacteristic characteristic) { if (String(characteristic.uuid()) == "e95d9250-251d-470a-a062-fa1922dfa9a8"){ // check if the characteristic is readable if (characteristic.canRead()) { // read the characteristic value characteristic.read(); if (characteristic.valueLength() > 0) { // print out the value of the characteristic Serial.print("value 0x"); printData(characteristic.value(), characteristic.valueLength()); } } Serial.println(); // loop the descriptors of the characteristic and explore each for (int i = 0; i < characteristic.descriptorCount(); i++) { BLEDescriptor descriptor = characteristic.descriptor(i); exploreDescriptor(descriptor); } } } void exploreDescriptor(BLEDescriptor descriptor) { // print the UUID of the descriptor Serial.print("\t\tDescriptor "); Serial.print(descriptor.uuid()); // read the descriptor value descriptor.read(); // print out the value of the descriptor Serial.print(", value 0x"); printData(descriptor.value(), descriptor.valueLength()); Serial.println(*descriptor.value(),HEX); } void printData(const unsigned char data[], int length) { for (int i = 0; i < length; i++) { unsigned char b = data[i]; if (b < 16) { Serial.print("0"); } Serial.print(b, HEX); } }
実行結果です。温度データが取り出せました。