ICM-20948 + Raspberry Pi Pico -> PCで3Dのキューブを回転表示

IMUセンサーICM-20948とRaspberry Pi Pico(Arduino) を使って、PCで3Dのキューブを回転表示させてみました。

以前、MPU6050でやったものの、ICM-20948版です。
MPU6050 + Raspberry Pi Pico(Arduino) -> PCで3Dのキューブを回転表示

ICM-20948は「SparkFun 9DoF IMU Breakout – ICM-20948」ボードを使用しています。せんごくネット通販で購入しました。
ICM-20948は電源電圧は1.71V~3.6Vですが、I/O電圧が1.71V~1.95Vとなっており、Picoなど3.3Vで使用するにはI/O電圧の変換が必要です。このボードはI/O電圧の変換を行ってくれるので使いやすいです。

姿勢推定はMPU6050の時と同じくMadgwickAHRSフィルターを使用していますが、ICM-20948では加速度・ジャイロに加えて磁気を追加しています。
MPU6050は加速度3軸・ジャイロ3軸の6軸ですが、ICM-20948は磁気3軸が追加されて9軸となります。(加えて温度も取れます)

PC側のプログラムは前回と同じです。
https://github.com/ponta1/MPU6050/blob/main/MPU6050.py

Pico側のプログラムは以下になります。Arduino環境(earlephilhower版)です。
SparkFun 9DoF IMU Breakout – ICM 20948 – Arduino Libraryを使用しているので、あらかじめインストールしてください。

// SparkFun 9DoF IMU Breakout - ICM-20948 から値を取得する
// 接続  Pico               ICM-20948
//       Pin3  GND       -> GND
//       Pin36 3V3(OUT)  -> VCC(3.3)
//       Pin21 GP16      -> SDA
//       Pin22 GP17      -> SCL
// ライブラリ
//   SparkFun 9DoF IMU Breakout - ICM 20948 - Arduino Library
//     ver 1.2.13

#include "Wire.h"
#include "ICM_20948.h" 
#include "MadgwickAHRS.h"
#include "RPi_Pico_TimerInterrupt.h"

Madgwick MadgwickFilter;

#define TIMER_INTERVAL_US  20000L // 20ms=50Hz
//#define TIMER_INTERVAL_US  10000L // 10ms=100Hz

// Init RPI_PICO_Timer
RPI_PICO_Timer ITimer(1);

float roll  = 0;
float pitch = 0;
float yaw   = 0;

// The value of the last bit of the I2C address.
// On the SparkFun 9DoF IMU breakout the default is 1, and when the ADR jumper is closed the value becomes 0
#define AD0_VAL 1
ICM_20948_I2C myICM;

int led = 1;

bool TimerHandler(struct repeating_timer *t)
{
  if (myICM.dataReady()) {
    myICM.getAGMT();

    // 加速度(mg)
    float acc_x = myICM.accX() / 16384.0;
    float acc_y = myICM.accY() / 16384.0;
    float acc_z = myICM.accZ() / 16384.0;

    // 角速度(度/s)
    float gyro_x = myICM.gyrX();
    float gyro_y = myICM.gyrY();
    float gyro_z = myICM.gyrZ();

    // 磁気(uT)
    float mag_x = myICM.magX();
    float mag_y = myICM.magY();
    float mag_z = myICM.magZ();

    //Madgwickフィルターを用いて、PRY(pitch, roll, yaw)を計算
    MadgwickFilter.update(gyro_x, gyro_y, gyro_z, acc_x, acc_y, acc_z, mag_x, mag_y, mag_z);

    //PRYの計算結果を取得する
    roll  = MadgwickFilter.getRoll();
    pitch = MadgwickFilter.getPitch();
    yaw   = MadgwickFilter.getYaw();
  }
  else {
    Serial.println("Waiting for data");
  }

  return true;
}

void setup() {
  Serial.begin(115200);
  while (!Serial){};
  Serial.println("START---");

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, led);

  Wire.setSDA(16);       //I2C0 SDA
  Wire.setSCL(17);       //I2C0 SCL
  Wire.setClock(400000);
  Wire.begin();

  bool initialized = false;
  while (!initialized) {
    myICM.begin(Wire, AD0_VAL);

    Serial.print(F("Initialization of the sensor returned: "));
    Serial.println(myICM.statusString());
    if (myICM.status != ICM_20948_Stat_Ok) {
      Serial.println("Trying again...");
      delay(500);
    }
    else {
      initialized = true;
    }
  }

  MadgwickFilter.begin(1000000 / TIMER_INTERVAL_US); //Hz
  //MadgwickFilter.setGain(1.0);  // これを利用するにはMadgwickFilterのソース修正が必要 [参考] https://blog2.studiok-i.net/2489.html

  ITimer.attachInterruptInterval(TIMER_INTERVAL_US, TimerHandler);

  delay(100);
}

void loop() {
  led ^= 1;
  digitalWrite(LED_BUILTIN, led);

  Serial.print(roll); Serial.print(",");
  Serial.print(pitch); Serial.print(",");
  Serial.println(yaw);

  delay(20);
}
本格派対局将棋 ぴよ将棋
本格派対局将棋アプリ ぴよ将棋
[Android] [iOS]

かわいい「ひよこ」と対局する将棋アプリ。かわいいけどAIは本格派!
対局後の検討機能や棋譜管理機能も充実!棋譜解析機能も搭載!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です