MPU 6050 관성 측정 장치 – IMU (Inertial Measurement Unit)

관성 측정 장치 (IMU)

관성 측정 장치는 움직이는 물체의 관성을 측정하여 전기적 신호로 출력을 내보내는 장치 입니다. 관성을 측정하여 물체가 어느 방향으로 움직이는지를 알 수 있습니다. B-ROBOT은 바퀴가 두 개 뿐이라 넘어지지 않고 주행 하려면 관성 측정 장치를 사용해서 움직임을 측정하여 자동으로 제어해야만 합니다. 그렇기 때문에 2바퀴 로봇이나 드론 같이 자동으로 자세를 보정해야 하는 시스템에서 관성 측정 장치는 필수 입니다.

일반적으로 관성 측정 장치는  이동관성을 측정하는 가속도계와 회전관성을 측정 하는 자이로계 그리고 방위각을 측정하는 자기력계로 이루어져 있습니다. B-ROBOT에서 사용 할 관성 측정 장치 센서 모듈 이름이  MPU 6050 입니다. 이 칩이 회전 하거나 움직이면 전기 신호를 내보내고 이 값을 읽어 칩이 탑재된 로봇의 움직임을 알 수 있습니다.

mpu6050_operation

MPU 6050 센서 모듈

반조립 상품, 마이콤(AVR, PIC, STM32), 아두이노(Arduino) 등에서 사용가능한 3축자이로 센서와3축 가속도 센서가 하나로 통합된 MPU6050 칩을 사용한 센서 모듈 입니다. 게임 및 가상 현실 입력 장치, GPS 네비게이션, 로봇 시스템 등에 유용하게 사용할 수 있습니다. 이 모듈은 자기력계는 측정이 되지 않습니다. 아두이노에 MPU6050 모듈을 연결하는 방법 및 테스트 코드는 구글에서 쉽게 찾아 볼 수 있습니다. 센서 모듈 가격도 저렴 하데 디바이스마트에서 2,700원에 구입 할 수 있습니다.

1247052

구입하면 ‘ㄱ’ 자 핀헤더와 1자 핀헤더도 같이 보내 줍니다.  인두를 사용하여 원하는 핀헤더를 인두를 사용하여 납땜하시면 됩니다.

아두이노와 결선 방법

모듈내의 MPU-6050 IC 는 3.3 V에 동작 하지만 내부에 3.3 V LDO 가 포함 되기 때문에  공급전압은 3.0 V ~ 5.0 V 를 모듈의 VCC 와 GND핀에 에 넣어 줄 수 있습니다. 센서값은 I2C 버스 인터페이스를 사용하여 모듈의  SDA와 SCL핀을 사용하여 가속도값 3개와 자이로값 3개를 읽어 올 수 있습니다.  INT 핀은 아두이노 인터럽트 핀과 연결하여 인터럽트를 사용하여 센서값을 읽을 때 사용 됩니다.

아래 결선 이미지는 diyhacking.com 에서 참조 하였습니다. 이 페이지에 영어로 되어 있지만 IMU 6050 센서를 아두이노에서 테스트 하는 방법이 상세하게 기술 되어 있으니 참고 바랍니다.  B-ROBOT에서는 이 사이트에서 사용된 라이브러리를 사용 하지만 여기서는 간단한 예제로 동작을 테스트 하겠습니다.

예제 코드

디바이스마트에서 제공하는 예제 코드를  받아 압축을 풀고 Arduino 폴더에 넣어 줍니다. zip 으로 다시 압축한 파일도 첨부 하였습니다.

~/Arduino/MPU6050$ tree
.
├── Examples
│   └── MPU6050_raw
│       └── MPU6050_raw.ino
├── I2Cdev.cpp
├── I2Cdev.h
├── MPU6050.cpp
└── MPU6050.h



 MPU6050_raw.ino파일을 로드 후 컴파일 하고 "툴" 메뉴의 "시리얼 모니터" 창을 열어 보드레이트를 38400으로 설정 후 업로드 하면 아래와 같이 센서값이 출력되는 것을 확인 할 수 있습니다. 모듈을 움직이면 센서값이 변경됩니다. 이 예제는 인터럽트를 사용하지 않아 INT 핀은 연결하지 않아도 됩니다.  각 라인에서 앞에 3값이 이동 관성값이고 뒤 3개가 회전 관성값 입니다.

mpu6050_run

다음은 예제 소스  MPU6050_raw.ino 입니다.

// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class
// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
//     2011-10-07 – initial release
/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#include “Wire.h”
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include “I2Cdev.h”
#include “MPU6050.h”
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
int16_t ax, ay, az;
int16_t gx, gy, gz;
#define LED_PIN 13
bool blinkState = false;
void setup() {
// join I2C bus (I2Cdev library doesn’t do this automatically)
Wire.begin();
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it’s really up to you depending on your project)
Serial.begin(38400);
// initialize device
Serial.println(“Initializing I2C devices…”);
accelgyro.initialize();
// verify connection
Serial.println(“Testing device connections…”);
Serial.println(accelgyro.testConnection() ? “MPU6050 connection successful” : “MPU6050 connection failed”);
// configure Arduino LED for
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// these methods (and a few others) are also available
//accelgyro.getAcceleration(&ax, &ay, &az);
//accelgyro.getRotation(&gx, &gy, &gz);
// display tab-separated accel/gyro x/y/z values
Serial.print(“a/g:\t”);
Serial.print(ax); Serial.print(“\t”);
Serial.print(ay); Serial.print(“\t”);
Serial.print(az); Serial.print(“\t”);
Serial.print(gx); Serial.print(“\t”);
Serial.print(gy); Serial.print(“\t”);
Serial.println(gz);
// blink LED to indicate activity
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
}