Nicla Sense MEをデータ入力に使う①クオータニオンのデータをBLEで出力するペリフェラル

 Arduino.ccのNicla Sense MEボード(写真右)にはボッシュの各種センサが搭載されています。

  • BHI260AP(32ビットCPU)は6軸(Accelerometer;加速度、Gyroscope;ジャイロ)のIMUを搭載
  • BMP390は気圧センサ
  • BMM150はmagnetometer;磁気センサ
  • BME688は環境センサで、BMP280/BME280の系列にCO2が測れる

 ただし、BHI260APにBMP390とBMM150およびBME688がぶら下がっている形にみえます。なので、I2CやSPIバスをアクセスしてセンサを利用できません。
 Arduino IDEが対象とするCPUは、BLEモジュールのnRF52832(Cortex-M4)です。型番で検索すると、技適が取れています。

Arduino IDEの開発環境

 Adruinoのボードのように、USBケーブルをPCとつないで、Arduino IDEでスケッチを書く方法が用意されています。その開発ソフトは、次の2種類があります。

 ボードの発売当時、GitHub arduinoは半年ほど古い日付でした。GitHub arduino-librariesは更新頻度が高く、2021年11月16日には1.0.3になっていました。2日遅れで、GitHub arduinoも更新されました。

 それまで、GitHub arduinoの扱うセンサIDが古く、gasセンサのデータが読み出せませんでした。

(参考URL)https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BME688-Nicla-Sense-me-how-to-access-the-data/m-p/46319

そのほかの開発環境

 Arduino IDEで開発する方法は、Nicla standalone modeと呼ばれています。それ以外に、Control Nicla from an arduino board through eslovとControl Nicla from a PC - web server、Control Nicla from a PC - command line toolがあります。

 このボードは、Arduino.ccにはシリーズ化されるような記述があります。半年ほど前に、ボッシュが高校生のコンテストを行ったときのボードによく似ています。

 BHI260APは、新製品発表当時、数万円した記憶があって、このボードは、販促用なのかもしれません。

セットアップ

 GitHub arduinoを使います。

 ボードマネージャを開きます。

 検索欄にNiclaを入れ、インストールします。

 ツールー>ボードで、Nicla Sense MEを選択します。シリアルポートも設定します。

 Nicla Sense MEボードは、USBケーブルでPCとつなぎます。ほかのボードと同じく、USBハブ経由で認識します。しかし、筆者の2台のPCでは、アップロードに失敗しました。解決方法は、PCのUSB2.0の口に直接つなぎます。

 サンプル例から、Lチカを選択します。ほかのボードのようにBlinkは動作しません。

センサのサンプルを実行

 https://github.com/arduino/nicla-sense-me-fw/blob/main/Arduino_BHY2/examples/Standalone/Standalone.ino

を新規スケッチに張り込み、コンパイル、実行します。

 実行したときの様子です。
 Accelerometer(加速度)、Gyroscope(ジャイロ)、Temperature(温度)、gas(空気の汚れ度)、rotation(クオータニオン;四次元数)の値を表示しています。

クオータニオンのデータをBLEで出力

 クオータニオンのデータだけを出力するスケッチです。


#include "Arduino.h"
#include "Arduino_BHY2.h"

SensorQuaternion   quater(SENSOR_ID_RV);

void setup(){
  Serial.begin(115200);
  while(!Serial);

  BHY2.begin();
  quater.begin();
}

void loop(){
  static auto printTime = millis();

  // Update function should be continuously polled
  BHY2.update();
  delay(500);
  if (millis() - printTime >= 1000) {
    printTime = millis();
    Serial.println(String("Quaternion : x,y,z,w ") + String(quater.x()) + ", " +  String(quater.y()) + ", " + String(quater.z())+ ", "+ String(quater.w()));
  }
}

 出力例です。

 このスケッチにBLE部分を追加します。


#include "Arduino.h"
#include "Arduino_BHY2.h"
#include <ArduinoBLE.h>

SensorQuaternion   quater(SENSOR_ID_RV);

// BLE Service
#define BHI260_SERVICE1_UUID   "F000AA30-0451-4000-B000-000000000000"
BLEService Sensor_BHI260_Service1(BHI260_SERVICE1_UUID);

// BLE  Characteristic
#define BHI260_QuaterX_Characteristic_UUID      "F000AA5A-0451-4000-B000-000000000000"
#define BHI260_QuaterY_Characteristic_UUID      "F000AA5B-0451-4000-B000-000000000000"
#define BHI260_QuaterZ_Characteristic_UUID      "F000AA5C-0451-4000-B000-000000000000"
#define BHI260_QuaterW_Characteristic_UUID      "F000AA5D-0451-4000-B000-000000000000"
BLEFloatCharacteristic    BHI260_QuaternionX(BHI260_QuaterX_Characteristic_UUID, BLERead | BLENotify);
BLEFloatCharacteristic    BHI260_QuaternionY(BHI260_QuaterY_Characteristic_UUID, BLERead | BLENotify);
BLEFloatCharacteristic    BHI260_QuaternionZ(BHI260_QuaterZ_Characteristic_UUID, BLERead | BLENotify);
BLEFloatCharacteristic    BHI260_QuaternionW(BHI260_QuaterW_Characteristic_UUID, BLERead | BLENotify);

// BLE  Descriptor
#define BHI260_Quater_Descriptor_UUID       "2901"
BLEDescriptor   BHI260_Quater_Descriptor(BHI260_Quater_Descriptor_UUID, "Quaternion  x,y,z,w  IEEE754 binary32");

#define localNAME  "Nicla_BHI260"
#define DeviceNAME "NiclaBLE"

float previousMillis = 0;  // last time value was checked, in ms

void setup(){
  Serial.begin(115200);
  while(!Serial);

  BHY2.begin();
  quater.begin();

  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");
    while (1);
  }

  BLE.setLocalName(localNAME);
  BLE.setDeviceName(DeviceNAME);

  //// set the service
  BLE.setAdvertisedService(Sensor_BHI260_Service1);

  // add characteristic
  Sensor_BHI260_Service1.addCharacteristic(BHI260_QuaternionX);
  Sensor_BHI260_Service1.addCharacteristic(BHI260_QuaternionY);
  Sensor_BHI260_Service1.addCharacteristic(BHI260_QuaternionZ);
  Sensor_BHI260_Service1.addCharacteristic(BHI260_QuaternionW);
  
  // add descriptor
  BHI260_QuaternionX.addDescriptor(BHI260_Quater_Descriptor);

  // add service
  BLE.addService(Sensor_BHI260_Service1);

  // set initial value for this characteristic ; PASS

  // start advertising
  BLE.advertise();
  Serial.println("\nBluetooth device active, waiting for connections...");
}

void loop(){
  // wait for a BLE central
  BLEDevice central = BLE.central();

  // if a central is connected to the peripheral:
  if (central) {
    delay(100);
    Serial.print("\nConnected to central: ");
    // print the central's BT address:
    Serial.println(central.address());

    // check data every 200ms
    // while the central is connected:
    while (central.connected()) {
      long currentMillis = millis();
      // if 200ms have passed, check value:
      if (currentMillis - previousMillis >= 200) {
        previousMillis = currentMillis;
        updateValue();
        //delay(1000);
      }
    }
    // when the central disconnects
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
    goto brout;
  }
  brout: ;
}

void updateValue() {
  BHY2.update();
  delay(500);
  Serial.println(String("Quaternion : x,y,z,w ") + String(quater.x(),3) + ", " +  String(quater.y(),3) + ", " + String(quater.z(),3)+ ", "+ String(quater.w(),3));
  BHI260_QuaternionX.writeValue(quater.x());
  BHI260_QuaternionY.writeValue(quater.y());
  BHI260_QuaternionZ.writeValue(quater.z());
  BHI260_QuaternionW.writeValue(quater.w());
}

 RLS10で実行しているBLEセントラルの画面です。実数はIEEE 754 binary32のフォーマットで送られてきます。

前へ

Nano 33 BLE Senseをデータ入力に使う<BLE>⑭9軸IMU LSM9DS1<BLEセントラル その3>

次へ

Nicla Sense MEをデータ入力に使う②クオータニオンのデータをBLEで受け取るセントラル