【連載②】宇宙を目指す小さな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-6000/6050 Product Specification(データシート)
https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf -
📙 MPU-6000/6050 Register Map and Descriptions
https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf
これらの資料では、MPU-6050の構造、電気仕様、I²Cアドレス体系、各レジスタの役割などが詳しく解説されています。
レジスタベースで直接制御する方には必携です!
Discussion