初めての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);
  }
}

実行結果です。温度データが取り出せました。

前へ

初めてのBLE (6) micro:bitでペリフェラル③UARTサービス

次へ

初めてのBLE (8) micro:bitでペリフェラル⑤UART温度をArduinoセントラルで受け取る