Arduino IDEを使って、M5Capsuleに実装されているIMUモジュール「BMI270」入力を行いました。ただし、Arduino IDEでM5Capsuleへのスケッチ書き込みが上手く実行できなくなりました。→ 2024/11/02 スケッチ書き込み手順が確認できました。

M5Capsuleの仕様を次に示します。「M5Capsule」を参照します。

M5Capsuleを次に示します。

開発環境の構築

M5Capsuleのプログラム開発はArduino IDEを使用します。詳細については、「M5AtomS3R Program Compilation & Upload」を参照します。

  1. メニュー「ファイル」 →「 環境設定」 を選択し、「追加のボードマネージャのURL 」次のURLを設定します。
  2. https://static-cdn.m5stack.com/resource/arduino/package_m5stack_index.json
    

  3. サイドバーで開発ボードマネージャを選択し、「M5Stack」を検索してインストールをクリックします。
  4. インストールが済むと、ボードリストから「M5Capsule」が選択できるようになります。
  5. メニューから「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理」を開き、次のように「M5Capsule」 をインストールします。

IMU入力プログラムの作成

次の手順でスケッチ例からIMUモジュール「BMI270」の入力プログラムを作成します。

スケッチ例では、出力が液晶パネルへのグラフィック表示となっており、シリアルモニターへのテキスト表示に変更しました。

  1. プログラムは次のスケッチ例「imu」をベースに作成します。

作成したIMU入力プログラム「capsule_imu.ino」を次に示します。

capsule_imu.ino

// Include this to enable the M5 global instance.
#include <M5Unified.h>

const char* name = "00";

static constexpr const uint8_t calib_value = 64;
static uint8_t calib_countdown = 0;
static int prev_xpos[18];

char prnname[256];

void updateCalibration(uint32_t c, bool clear = false) {
  calib_countdown = c;

  if (c == 0) {
    clear = true;
  }

  if (clear) {
    memset(prev_xpos, 0, sizeof(prev_xpos));
    //dsp.fillScreen(TFT_BLACK);

    if (c) {  // Start calibration.
      M5.Imu.setCalibration(calib_value, calib_value, calib_value);
      // ※ The actual calibration operation is performed each time during M5.Imu.update.
      //
      // There are three arguments, which can be specified in the order of Accelerometer, gyro, and geomagnetic.
      // If you want to calibrate only the Accelerometer, do the following.
      // M5.Imu.setCalibration(100, 0, 0);
      //
      // If you want to calibrate only the gyro, do the following.
      // M5.Imu.setCalibration(0, 100, 0);
      //
      // If you want to calibrate only the geomagnetism, do the following.
      // M5.Imu.setCalibration(0, 0, 100);
    } else {  // Stop calibration. (Continue calibration only for the geomagnetic sensor)
      M5.Imu.setCalibration(0, 0, calib_value);

      // If you want to stop all calibration, write this.
      // M5.Imu.setCalibration(0, 0, 0);

      // save calibration values.
      M5.Imu.saveOffsetToNVS();
    }
  }

  auto backcolor = (c == 0) ? TFT_BLACK : TFT_BLUE;
  /*
  dsp.fillRect(rect_text_area.x, rect_text_area.y, rect_text_area.w, rect_text_area.h, backcolor);

  if (c)
  {
    dsp.setCursor(rect_text_area.x + 2, rect_text_area.y + 1);
    dsp.setTextColor(TFT_WHITE, TFT_BLUE);
    dsp.printf("Countdown:%d ", c);
  }
  */
}

void startCalibration(void) {
  updateCalibration(10, true);
}

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

  // put your setup code here, to run once:
  auto cfg = M5.config();

  M5.begin(cfg);

  switch (M5.Imu.getType()) {
    case m5::imu_none: name = "not found"; break;
    case m5::imu_sh200q: name = "sh200q"; break;
    case m5::imu_mpu6050: name = "mpu6050"; break;
    case m5::imu_mpu6886: name = "mpu6886"; break;
    case m5::imu_mpu9250: name = "mpu9250"; break;
    case m5::imu_bmi270: name = "bmi270"; break;
    default: name = "unknown"; break;
  };

  M5_LOGI("imu:%s", name);
}

void loop() {


  sprintf(prnname, "imu:%s", name);
  //Serial.println(prnname);

  //delay(1000);

  static uint32_t frame_count = 0;
  static uint32_t prev_sec = 0;

  // To update the IMU value, use M5.Imu.update.
  // If a new value is obtained, the return value is non-zero.
  auto imu_update = M5.Imu.update();
  if (imu_update) {
    // Obtain data on the current value of the IMU.
    auto data = M5.Imu.getImuData();
    //drawGraph(rect_graph_area, data);
    /*
    // The data obtained by getImuData can be used as follows.
    data.accel.x;      // accel x-axis value.
    data.accel.y;      // accel y-axis value.
    data.accel.z;      // accel z-axis value.
    data.accel.value;  // accel 3values array [0]=x / [1]=y / [2]=z.

    data.gyro.x;      // gyro x-axis value.
    data.gyro.y;      // gyro y-axis value.
    data.gyro.z;      // gyro z-axis value.
    data.gyro.value;  // gyro 3values array [0]=x / [1]=y / [2]=z.

    data.mag.x;       // mag x-axis value.
    data.mag.y;       // mag y-axis value.
    data.mag.z;       // mag z-axis value.
    data.mag.value;   // mag 3values array [0]=x / [1]=y / [2]=z.

    data.value;       // all sensor 9values array [0~2]=accel / [3~5]=gyro / [6~8]=mag

    M5_LOGV("ax:%f  ay:%f  az:%f", data.accel.x, data.accel.y, data.accel.z);
    M5_LOGV("gx:%f  gy:%f  gz:%f", data.gyro.x , data.gyro.y , data.gyro.z );
    M5_LOGV("mx:%f  my:%f  mz:%f", data.mag.x  , data.mag.y  , data.mag.z  );
//*/

    M5_LOGV("ax:%f  ay:%f  az:%f", data.accel.x, data.accel.y, data.accel.z);
    sprintf(prnname, "ax:%f  ay:%f  az:%f", data.accel.x, data.accel.y, data.accel.z);
    Serial.println(prnname);

    M5_LOGV("gx:%f  gy:%f  gz:%f", data.gyro.x, data.gyro.y, data.gyro.z);
    sprintf(prnname, "gx:%f  gy:%f  gz:%f", data.gyro.x, data.gyro.y, data.gyro.z);
    Serial.println(prnname);

    M5_LOGV("mx:%f  my:%f  mz:%f", data.mag.x, data.mag.y, data.mag.z);
    sprintf(prnname, "mx:%f  my:%f  mz:%f", data.mag.x, data.mag.y, data.mag.z);
    Serial.println(prnname);


    ++frame_count;
  } else {
    M5.update();

    // Calibration is initiated when a button or screen is clicked.
    if (M5.BtnA.wasClicked() || M5.BtnPWR.wasClicked() || M5.Touch.getDetail().wasClicked()) {
      startCalibration();
    }
  }

  int32_t sec = millis() / 1000;
  if (prev_sec != sec) {
    prev_sec = sec;
    M5_LOGI("sec:%d  frame:%d", sec, frame_count);
    frame_count = 0;

    if (calib_countdown) {
      updateCalibration(calib_countdown - 1);
    }

    if ((sec & 7) == 0) {  // prevent WDT.
      vTaskDelay(1);
    }
  }
}

プログラムの書き込み・実行(スケッチ書き込み失敗編)

次のように、エラーメッセージ「A fatal error occured: No serial data received.」が発生するようになりました。スケッチを変更していく過程で、最初はうまくいったArduino IDEでM5Capsuleへのスケッチ書き込みが、上手く実行できなくなりました。

EN,IO0ボタンを使ったような書き込み手順が必要なのかもしれません(参照:M5Stamp Pico MateでLチカ・ボタン入力)。

【 スケッチの書き込み 】
スケッチの書き込みは、書き込みモードで起動します。「BTN 0」と書かれたボタンを押下しながら電源を投入、または「GPIO0」とGNDをショートさせた状態で電源を投入します。この状態でArduino IDEから書き込みの指示を行います。

ダウンロードモードへの切り替え

スケッチ書き込みのためにダウンロードモードに入る必要があります。電源を入れる前に M5Capsule の G00(ステッカーのBTN0の位置) ボタンを押し続け、USB ケーブルを接続してダウンロードモードに入ります。

プログラムの書き込み・実行(スケッチ書き込み成功編)

作成したIMU入力プログラム「capsule_imu.ino」を実行すると、次のようにシリアルモニタにIMUモジュール「BMI270」からのセンサー情報が表示されます。