GY-521 (3軸加速度センサ/ジャイロ・モジュール) を Arduino で利用する方法

GY-521 は InvenSense 社の MPU-6050 を利用するためのブレイクアウト・ボード (センサーボード) です。

MPU-6050 は 3軸ジャイロと 3軸加速度センサ、及び DMP (デジタル・モーション・プロセッサ) を搭載していて、センサーの値を DMP が処理しモーション・トラッキングを実現しています。

MPU-6050 の動作電圧は 3.3V ですが GY-521 にはレギュレータが搭載されているので、5V でも利用可能です。

Arduino とのインターフェイスは I2C バスで利用可能です。

Arduino での利用

Jeff Rowberg 氏が作成した I2Cdevlib というライブラリを利用すると便利です。

» GitHub i2cdevlib

zip ファイルをダウンロードしたら展開して、その中の I2Cdev フォルダと MPU6050 フォルダを、Arduino/libraries フォルダにコピーします。 (Arduino IDE で ZIP の追加、としてもうまくいかないです)

GY-521 のボードをよく見ると、X 軸と Y 軸の方向が記載されています。

回転角度はそれぞれの軸の向きで右ネジの進む方向が正になります。

X 軸まわりと Y 軸まわりの動作を次の例で動かしながら確認しましょう。

ピッチとロールで LED を点灯

ここでは次のビデオのように、GY-521 をブレッドボードに取り付け、さらに LED を四方に配置して、ブレッドボードを傾けた方向の LED を点灯させてみます。

GY-521 と Arduino UNO R3 を利用しています。

GY-521 と LED は次の図のように配置します。

飛行機に例えると X 軸方向が機首の向いている方向になります。X 軸まわりの回転角がロール角で、Y 軸まわりがピッチ角となります。

ロール角、及び、ピッチ角をみて、30度より下がった時に下がった向きの LED を点灯させます。

I2Cdevlib を利用したコードは次の通りです。

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"

const int PIN_INTERRUPT = 2;
const int PIN_LED1 = 8;
const int PIN_LED2 = 9;
const int PIN_LED3 = 10;
const int PIN_LED4 = 11;

MPU6050 mpu;

bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint16_t fifoCount;
uint8_t fifoBuffer[64];

Quaternion q;
VectorFloat gravity;
float ypr[3];

volatile bool mpuInterrupt = false;

void dmpDataReady() {
  mpuInterrupt = true;
}

void setup() {

  Wire.begin();
  Wire.setClock(400000);

  mpu.initialize();
  pinMode(PIN_INTERRUPT, INPUT);

  while(!mpu.testConnection() ){
  }

  devStatus = mpu.dmpInitialize();

  if (devStatus == 0) {
    mpu.setDMPEnabled(true);
    attachInterrupt(
      digitalPinToInterrupt(PIN_INTERRUPT), 
      dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();
    dmpReady = true;
    packetSize = mpu.dmpGetFIFOPacketSize();
  }

  pinMode( PIN_LED1, OUTPUT);
  pinMode( PIN_LED2, OUTPUT);
  pinMode( PIN_LED3, OUTPUT);
  pinMode( PIN_LED4, OUTPUT);

  digitalWrite( PIN_LED1, LOW );
  digitalWrite( PIN_LED2, LOW );
  digitalWrite( PIN_LED3, LOW );
  digitalWrite( PIN_LED4, LOW );
  
}

void loop() {
  if (!dmpReady) {
    return;
  }

  while (!mpuInterrupt && fifoCount < packetSize) {
  }

  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();
  fifoCount = mpu.getFIFOCount();

  if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
    mpu.resetFIFO();
  } else if (mpuIntStatus & 0x02) {
    while (fifoCount < packetSize){
      fifoCount = mpu.getFIFOCount();
    }

    mpu.getFIFOBytes(fifoBuffer, packetSize);        
    fifoCount -= packetSize;

    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

    float pitch = ypr[1] * 180/M_PI;
    float roll = ypr[2] * 180/M_PI;
    
    // ROLL
    if( 30 < roll && roll < 150 ){
      digitalWrite( PIN_LED2, HIGH );
      digitalWrite( PIN_LED4, LOW );
    }
    else if( -150 < roll && roll < -30 ){
      digitalWrite( PIN_LED4, HIGH );
      digitalWrite( PIN_LED2, LOW );
    }
    else {
      digitalWrite( PIN_LED2, LOW );
      digitalWrite( PIN_LED4, LOW );
    }

    // PITCH
    if( 30 < pitch && pitch < 150 ){
      digitalWrite( PIN_LED3, HIGH );
      digitalWrite( PIN_LED1, LOW );
    }
    else if( -150 < pitch && pitch < -30 ){
      digitalWrite( PIN_LED1, HIGH );
      digitalWrite( PIN_LED3, LOW );
    }
    else {
      digitalWrite( PIN_LED1, LOW );
      digitalWrite( PIN_LED3, LOW );
    }

  }
}

配線は GY-521 は I2C インターフェイスで接続します。Arduino UNO の I2C インターフェイスは SDA が A4、SCL が A5 です。

また I2C なので、プルアップ抵抗として 10kΩ を SCL、SDA に接続しています。

ちなみに、I2C バスのアドレスは、AD0 が LOW で b1101000、HIGH で b1101001 です。

VCC は 5V に接続します。

GY-521 の INT (インタラプト) ピンは Arduino UNO の D2 に接続します。

LED 1 から 4 は Arduino の D8 から D11 に接続します。ここでは電流制限抵抗として 220Ω 接続しています。

以上で次のようになりました。

Arduino UNO にスケッチをアップロードすれば、動作確認できるはずです。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 基礎からの IoT 入門