【Arduino】加速度センサ MPU9250の使い方&測定レンジ設定

こんにちは!今回は加速度+ジャイロ+方位が取れる高精度センサであるMPU-9250の使い方をご紹介します。データ取得や測定レンジ変更など基本的な使い方と使用レビューをしようと思います。

なおセンサの詳しい仕様はこちらのデータシートを参照すれば分かります。この記事はデータシートを見るのが面倒な時のための備忘録的記事です。

この記事は自分で色々試行錯誤した結果でもあるので、間違っている箇所があればぜひご指摘ください。

目次

  • 用意するもの
  • 配線時の注意点
  • データの取得
  • 測定レンジ、内部LPFの設定

用意するもの

  • MPU-9250
    今回使用するセンサです
  • Arduino nano
    たまたま手元にあったnanoを使いましたが、Arduino Unoやラズパイなど、I2CまたはSPI通信が使えるなら何でもOKだと思います。今回はArduino系でI2Cを使う想定でサンプルコードをご紹介します。

配線時の注意

配線はデータシートの通りですが、必要最小限でこれだけになります。ポイントは左下と右下のピンで、左下はアドレス選択ピンで3.3VかGNDどちらに接続してもいいですが通信する時のアドレスが異なります。

左下ピンスレーブアドレス
LOW(0V)0x68
HIGH(3.3V)0x69

右下はI2Cの場合3.3Vに接続します。

最小構成での配線

データの取得

I2C通信するライブラリはArduinoならばWire.hが使えます。MPU-9250のデータ読み込みはデバイスアドレスを指定して、メモリアドレスを書き込んだあと、メモリを読み出すことで取得します。

加速度、ジャイロの値を取得するサンプルコードをご紹介します。データは16ビットで、上位8ビットと下位8ビットに分かれているので、データの読み込みを2回行い結合する関数i2c_read2を用意しています。この関数に読みたいメモリアドレスを入力するだけで、データを取得することが出来ます。

#include <Wire.h>

#define DEVICE_ADDRESS 0x69
#define MPU_WAKE_UP1 0x6B
#define MPU_WAKE_UP2 0x37
#define X_a 0x3B
#define Y_a 0x3D
#define Z_a 0x3F
#define X_g 0x43
#define Y_g 0x45
#define Z_g 0x47

#define ACC_RESOLUTION 32768.0
#define GYR_RESOLUTION 32768.0
#define ACC_RANGE 2.0//[m/s/s]
#define GYR_RANGE 250//[deg/s]

//メモリアドレスから2バイト読み込んで整数に直します。データはビッグエンディアンです。
short i2c_read2(char memory_address){
  //先頭アドレスの読み込み。16bitのshort型に格納。
  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.write(memory_address);
  Wire.endTransmission(false);

  Wire.requestFrom(DEVICE_ADDRESS,1);
  short d1 = Wire.read();
  Wire.endTransmission(true);

  //次のアドレスの読み込み。16bitのshort型に格納。
  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.write(memory_address + 0x1);
  Wire.endTransmission(false);

  Wire.requestFrom(DEVICE_ADDRESS,1);
  short d2 = Wire.read();
  Wire.endTransmission(true);

  //一つ目のデータを8ビットシフト。
  d1 <<=8;

  //2つのデータを結合して返す。
  return d1 | d2;
}

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



void loop() {
  float acc_x = i2c_read2(X_a)/ACC_RESOLUTION * ACC_RANGE;
  float acc_y = i2c_read2(Y_a)/ACC_RESOLUTION * ACC_RANGE;
  float gyro  = i2c_read2(Z_g)/GYR_RESOLUTION * GYR_RANGE;

  Serial.println(acc_x);

  delay(10);
}

測定レンジと内部LPFの設定

このセンサは測定レンジが加速度は±2G~±16G、ジャイロは±250deg/s~±2000deg/sまで設定可能です。設定は特定のメモリアドレスにデータを書き込むことで行います。

メモリアドレスに値を書き込む関数i2c_writeを用意しました。

//メモリアドレスに値を書き込む
void i2c_write(char address, char value){
  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.write(address);
  Wire.write(value);
  Wire.endTransmission(true);
}

これを使って、次のような感じに設定を行います。メモリアドレス26~29が設定値を書き込むアドレスです。

i2c_write(26, 0b00000110);//角加速度LPF設定(Bandwidth:5Hz Delay:33.48ms)
i2c_write(27, 0b00000000);//角加速度レンジ設定([0b000??000] 00:250dps 01:500dps 10:1000dps 11:2000dps)
i2c_write(28, 0b00000000);//加速度レンジ設定([0b000??000] 00:2g 01:4g 10:8g 11:16g)
i2c_write(29, 0b00000110);//加速度LPF設定(Bandwidth:5Hz Delay:66.96ms)

結果を見てみる

X軸とY軸の加速度をプロットしてみました。縦軸が加速度[G]で横軸が時刻です。いい感じに取れてると思います!

加速度をプロットしたグラフ。縦軸が加速度[G]、横軸が時間。青がX軸、赤がY軸。

この例ではLPF設定をカットオフ周波数5Hzに設定したので、かなり強いフィルターがかかっています。それでも手で振ったくらいの加速度は問題なく表示されます。電動歯ブラシを当ててみたところ、殆ど値が変化しませんでした。ここまで強いフィルターが必要な状況はそう無いと思いますが、必要に応じて調整するのがいいと思います。

今回は以上です。

コメントを残す

メールアドレスが公開されることはありません。