🪐

【連載②】宇宙を目指す小さなIMU試作の記録:MPU6050を使って加速度・ジャイロをArduinoで読み取る

に公開

はじめに

MPU6050は定番の6軸IMUセンサーです。ここではArduinoを使ってその生データを取得します。
本記事では、ArduinoとMPU6050という組み合わせを使って、加速度と角速度(ジャイロ)のデータをリアルタイムで取得する基本的な方法を紹介します。

MPU6050は、**3軸加速度センサーと3軸ジャイロセンサーを1つのチップに搭載した、6軸IMU(慣性計測ユニット)**です。安価で入手しやすく、ライブラリやサンプルも豊富なことから、電子工作・ロボット・ドローン・姿勢推定の入門に最適なセンサーです。

本連載は、「IMUモジュールを使って宇宙空間でも応用可能な姿勢推定を目指す」という最終ゴールに向けて、ステップバイステップで技術を積み上げていきます。その最初の実践として、まずはMPU6050からセンサーデータを“吸い出す”ところからスタートします。

この記事でできるようになること

  • MPU6050のI²C接続方法が理解できる
  • Arduinoスケッチで加速度・ジャイロデータを取得できる
  • シリアルモニターで生データをリアルタイムに確認できる
  • 今後のデータ補正や可視化のための土台がつくれる

センサーを使って動きや姿勢を“数値”として捉えるという技術の第一歩を、一緒に踏み出してみましょう。

配線図

実際に繋いでみた(強引ですが)

Arduinoコード

今回は、MPU6050に用意されている内部レジスタから、加速度・ジャイロの生データをライブラリを使わずに直接取得する方法を紹介します。

MPU6050は、I²C接続で制御され、各種センサーデータは内部レジスタに格納されています。
たとえば、加速度データは以下のようなアドレスに2バイト(16ビット)ずつ格納されています。

データ レジスタ 説明
Accel X 0x3B, 0x3C 16ビット signed
Accel Y 0x3D, 0x3E
Accel Z 0x3F, 0x40
Gyro X 0x43, 0x44
Gyro Y 0x45, 0x46
Gyro Z 0x47, 0x48

スケーリングについて

  • 加速度:±2gレンジ → スケーリング係数 = 16384 LSB/g
  • ジャイロ:±250°/sレンジ → スケーリング係数 = 131 LSB/°/s

これらを使って、g単位や°/s単位の実用的な値に換算して出力します。


スケッチコード

sketch_accel_gyro_monitor.ino

#include <Wire.h>

#define MPU_ADDR 0x68           // MPU6050のI²Cアドレス(AD0がGNDのとき)
#define ACCEL_SCALE 16384.0     // ±2g設定時のスケーリング係数
#define GYRO_SCALE 131.0        // ±250dps設定時のスケーリング係数

void setup() {
  Serial.begin(9600);
  Wire.begin();

  // MPU6050をスリープ解除(PWR_MGMT_1 = 0x00)
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x6B); // PWR_MGMT_1
  Wire.write(0x00); // スリープ解除
  Wire.endTransmission();

  delay(100); // 初期化待機

  Serial.println("AccelX[g],AccelY[g],AccelZ[g],GyroX[dps],GyroY[dps],GyroZ[dps]");
}

void loop() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B); // センサーデータの先頭アドレス
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_ADDR, 14);

  if (Wire.available() == 14) {
    int16_t ax_raw = Wire.read() << 8 | Wire.read();
    int16_t ay_raw = Wire.read() << 8 | Wire.read();
    int16_t az_raw = Wire.read() << 8 | Wire.read();
    Wire.read(); Wire.read(); // 温度レジスタ(未使用)
    int16_t gx_raw = Wire.read() << 8 | Wire.read();
    int16_t gy_raw = Wire.read() << 8 | Wire.read();
    int16_t gz_raw = Wire.read() << 8 | Wire.read();

    // スケーリング処理
    float ax = ax_raw / ACCEL_SCALE;
    float ay = ay_raw / ACCEL_SCALE;
    float az = az_raw / ACCEL_SCALE;
    float gx = gx_raw / GYRO_SCALE;
    float gy = gy_raw / GYRO_SCALE;
    float gz = gz_raw / GYRO_SCALE;

    // CSV形式で出力
    Serial.print(ax, 2); Serial.print(",");
    Serial.print(ay, 2); Serial.print(",");
    Serial.print(az, 2); Serial.print(",");
    Serial.print(gx, 2); Serial.print(",");
    Serial.print(gy, 2); Serial.print(",");
    Serial.println(gz, 2);
  } else {
    Serial.println("データ取得失敗 ❌");
  }

  delay(500); // 0.5秒間隔で更新
}

結果

シリアルモニターにセンサーのデータが出力されていることを確認。

参考資料:MPU-6050の公式ドキュメント

これらの資料では、MPU-6050の構造、電気仕様、I²Cアドレス体系、各レジスタの役割などが詳しく解説されています。
レジスタベースで直接制御する方には必携です!

Discussion