初めての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);
}
}
実行結果です。温度データが取り出せました。