[매드] 아두이노 강좌 - 32. GY-521 모듈 동작

안녕하세요~~ 매드 입니다.

하.. 이것저것 잡다한거 다 하다보니 정말 시간가는줄도 모르겠고 정신 없네요.
일주일에 한번씩하는 이 강좌도 힘겹네요(ㅠㅠ)...

머 어쩌겠습니다. 제가 선택한걸 ㅋㅋㅋ 제가 알고 있는 모든 정보와 자료 기술들을 함께 공유하는 날까지!!! (후후.. 저도 계속 공부할꺼니까 죽을때까지 할지도... )

해야되는 일은 안하고 블로깅질 하고 있네요 ㅋㅋㅋ

이번 시간에는 지난 시간에 '와이비녀'님 께서 요즘 드론에 빠져계신다고 하셨는데 ㅎㅎ 이런 드론에 핵심 부품으로 사용되고 있는 6축 가속도,자이로 센서에 대해서 다뤄보도록 하겠습니다.


32-1. GY-521 or MPU-6050 모듈

<GY-521(출처:구글사진)>

우리가 보통 자세 제어에 사용하는 센서를 3축, 6축, 9축 이런식으로 많이 부르게되는데 이는 차원이라고 생각하시면 됩니다.

예를들면 가속도를 측정할 수 있는 센서가 있는데 x축 y축만 측정가능하다면 2축, x, y, z 3차원 공간을 측정할 수 있다면 3축이 되는 것이죠. 그런데 어떻게 9축까지 가능하냐구요?

가속도를 측정할 수 있는 센서 뿐만 아니라 자이로센서, 지자기센서까지 포함하여 각 3축씩 합쳐서 9축이 가능한 것 입니다.

그럼 나눠서 간단히 설명해보면 가속도는 단어 그대로 가속도를 측정하는 것이니까 다들 알고 계시겠죠? ㅎㅎ
자이로센서가 있는데 이는 좀 생소할 수 있으나 한마디로하면 '각'속도 센서가 되겠습니다. 지자기 센서는 우리가 잘 알고 있는 동서남북을 알 수 있는 센서 이지요.

이런 각각의 가속도, 자이로, 지자기 센서들은 장점과 단점들이 있는데 이 세가지가 서로 합쳐져서 서로의 단점을 보완하고 측정 정밀도를 강화하게 됩니다! 신기하죠?

이외에도 각종 디지털 알고리즘을 통해 더 정밀하게 계산식을 구할 수 있게 되는 것이죠.

우리가 시중에 나와있는 많은 드론들만 봐도 1~2만원짜리부터 몇백만원 하는 것들까지 다양한 가격대의 드론들이 있는데 이는 실제로 사용한 하드웨어 부품들은 비슷하더라도 내부적으로 사용된 알고리즘이 다르기 때문에 저 정밀한 움직임이 가능한 것입니다.

남들이 연구해 놓은 것을 낼름 가져가고 싶지만 (ㅠㅠ) 사실은 그냥 공개해줘도 사용할려면 어느정도 공부를 해야한다는 반전이 있죠 ... ㅎㅎ

이정도면 센서에대해서 대략적인 설명이 되었을려나요?~ ㅎㅎ 우리는 일단 써보는게 중요하니까요!


32-2. GY-521 or MPU-6050 모듈 연결

<GY-521 연결(출처:구글사진)>

가뜩이나 이해하기 어려운것 같았던 센서이지만 하드웨어 연결은 i2c 통신을 사용하기 때문에 이렇게나 간단합니다. (ㅠㅠ)

기존에 사용하던 것과 동일하니 아마 여러분들도 연결하시는데는 문제 없으시겠죠!



32-3. 펌웨어

펌웨어는 I2Cdev and MPU6050 라이브러리가 반드시 있어야 하네요~
설치하는 것은 영상의 끝부분(10분전쯤?)을 보시면 될 것 같습니다.

// 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:
//      2013-05-08 - added multiple output formats
//                 - added seamless Fastwire support
//      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.
===============================================
*/

// 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"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

// 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;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high

int16_t ax, ay, az;
int16_t gx, gy, gz;



// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO


#define LED_PIN 13
bool blinkState = false;

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // 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(9600);

    // 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");

    // use the code below to change accel/gyro offset values
    /*
    Serial.println("Updating internal sensor offsets...");
    // -76 -2359 1688 0 0 0
    Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
    Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
    Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
    Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
    Serial.print("\n");
    accelgyro.setXGyroOffset(220);
    accelgyro.setYGyroOffset(76);
    accelgyro.setZGyroOffset(-85);
    Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
    Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
    Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
    Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
    Serial.print("\n");
    */

    // 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);

    #ifdef OUTPUT_READABLE_ACCELGYRO
        // 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);
    #endif

    #ifdef OUTPUT_BINARY_ACCELGYRO
        Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
        Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
        Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
        Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
        Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
        Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
    #endif

    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
}



이제 중급강좌를 끝내고!! 할만큼 했으니 고급강좌로 넘어가 보도록 하겠습니다.
기존에 진행했던 초중급 강좌를 잘 따라오신 분들이라면 충분히 문제 없이 따라오시리라 믿습니다. ㅎㅎ

고급강좌는 생활하면서 불편했던 것들을 중심으로 하나씩 하나씩 응용하는 제품들을 만들어 보도록 하겠습니다.

어떻게 진행해야 할지는 모르겠네요... 흠.. 진행하면서 코딩도 해야하나 ㅡ.,ㅡ; 요건 차근차근 생각해보도록할께요! >.< 그럼 다음주에 봐요~

댓글 쓰기

2 댓글

  1. 이런 모듈이 따로 있군요...신기하네요...

    답글삭제
    답글
    1. 네! ㅎㅎ 드론에서 이 모듈 많이 사용하더라구요 ㅎㅎ

      삭제