프로젝트

[버섯] 에어 마우스 만들기 기초 ( 아두이노와 MPU-6050 센서 사용 )

페이지 정보

작성자 버섯돌이 작성일17-01-05 19:27 조회42,090회 댓글0건

첨부파일

본문

 

 버섯돌이의 아두이노 기초

MPU-6050 센서로 간단한 에어 마우스 만들기

Created Date: 2016.10.27
Modified Date: 2016.12.30
revision 1.0

키워드 : 아두이노, 에어마우스, AirMouse, Air Mouse, MPU-6050, 자이로센서

들어가며..
안녕하세요 버섯돌이 유재성입니다.
원래는 아들하고 함께 즐길 장난감을 먼저 만들 예정이었지만...
에어 마우스에 대해 문의하는 분들도 계셔서 간단한 에어 마우스부터 먼저 만듭니다.^^;;
533a653de48e669913c248968b413e53_1483611

두 달전에 시작했었지만 32u4 기반의 아두이노가 없어서 잠시 중단했었으나..
최근에 아두이노가 도착해서 장난감도 만들 수 있고 올해가 가기 전에 정보도 공유할 수 있어서 다행이군요.^^
(ㅎㅎㅎ.. 하나둘씩 미루다 보면 다른 것 하느라 몇 년씩 방치되는 게 많아서^^;;)

본 강좌에서 부족한 부분은 구글링하시기 바라며 에어 마우스의 아주 간단한 구현 방법에 대해서 살펴보겠습니다.
 
MPU-6050같은 센서는 쿼드 콥터를 비롯하여 많이 사용되기 때문에 관련 자료가 엄청 많습니다.
개념만 본다면 상당히 간단할 수 있지만 원하는 용도로 사용할 정도로 이해하기에는 어려운 센서가 아닌가 싶네요.
저 또한 센서에 대해서 잘 모르기 때문에 센서에 대한 내용은 다른 강좌들을 참고 하시기 바랍니다.


주의사항..
에어 마우스의 구현은 몇 가지 방법을 생각할 수 있겠지만...
초보 분들을 고려해서 모든 기능을 아두이노로 구현한다고 가정하겠습니다.

아두이노로 마우스 기능을 구현하기 위해 아두이노의 마우스 라이브러리를 이용합니다.

https://www.arduino.cc/en/Reference/MouseKeyboard 

 

하지만, 이 라이브러리를 사용하기 위해서는 아래 조건을 만족해야 합니다.

These core libraries allow a 32u4 based boards or Due and Zero board to appear as a native Mouse and/or Keyboard to a connected computer.

 

ATmega32u4 칩셋은 USB 통신 기능을 지원하며 흔히 HID라고 부르는 키보드나 마우스 등의 기능을 지원합니다.

따라서, 칩셋이 ATmega32u4가 아닌 제품은 마우스 라이브러리를 사용할 수가 없습니다.-_-;;;

 

문제는, 아두이노 UNO / Nano / Pro / Pro mini의 경우 ATmega328 칩을 사용하기 때문에 사용이 불 가능합니다.

 

반면, ATmega32u4을 사용하는 제품은 오래된 제품 중에는 Arduino Leonardo 제품이 있었습니다.

https://www.arduino.cc/en/Main/ArduinoBoardLeonardo 

533a653de48e669913c248968b413e53_1483611
 


최신 제품군에는 Arduino MICRO가 ATmega32u4 칩셋을 사용하고 있습니다.

https://www.arduino.cc/en/Main/ArduinoBoardMicro 

533a653de48e669913c248968b413e53_1483611
 

레오나르도 보드의 소형화 버전으로 생각하시면 되겠습니다.

 

그 외의 ATmega32u4 칩셋을 사용하는 보드나 Due and Zero 보드 정도가 키보드와 마우스 라이브러리를 사용할 수 있는 것 같네요.

 

구글링 해 보면 편법으로 부트로더를 변경해서 우회할 수 있는 보드들도 있지만 이 글의 범위를 벗어나고 복잡하니 논외로 하겠습니다.

그럼에도 복잡함이나 위험을 무릅쓰고라도 기존 보드에 강제로 부트로더를 올리고 싶은 분들은 아래 사이트를 참고해 보세요.


사전 지식..
환경 구축에 따른 불 필요한 질문과 에러를 방지하기 위해 자이로 센서에 대한 사용법은 확실하게 숙지하시기 바랍니다.
도움이 될만한 링크와 강좌 몇 개를 검색해서 간단한 설명과 설치 방법이 나온 자료 중 한글 자료 먼저 찾아서 적어 드립니다만..
저도 내용을 일일이 학습할 여유는 없기 때문에 궁금한 부분은 해당 강좌 작성자에게 문의해주세요.^^

[Arduino Uno] MPU-6050 6축 자이로 가속도 센서 모듈 GY-521

GY-521 MPU 6050 모듈 사용하기
 
[아두이노] 6축 자이로/가속도 센서 MPU-6050 의 사용

MPU-6050 Accelerometer + Gyro - 아두이노 공식 가이드

http://playground.arduino.cc/Main/MPU-6050

 

ARDUINO MPU 6050 – BEST IMU SENSOR TUTORIAL

https://diyhacking.com/arduino-mpu-6050-imu-sensor-tutorial/ 

 

글을 보기 귀찮은 분들은 아래 두 영상에서 간단한 개념을 확인하시기 바랍니다.
MPU6050 First steps

Arduino UNO Tutorial : MPU6050 DMP Values


아래 영상은 개념적으로 좀 더 세부적인 설명을 담고 있을 것 같아서 추가했습니다.

Ep. 57 Arduino Accelerometer & Gyroscope Tutorial MPU-6050 6DOF Module

 

 

에어 마우스 (자이로스코프 마우스)..
에어 마우스라는 이름만 놓고 보면 구현 방법에 차이는 있겠지만... 여기에서는 자이로스코프 기반으로 제한해서
만들고자 하는 에어 마우스가 어떤 것인지 간단한 개념을 살펴보겠습니다.

에어 마우스(Air Mouse)란 자이로스코프 센서의 기울기에 따른 X,Y,Z 축의 변화를 감지해서 컴퓨터의 마우스를 제어합니다.
기성 제품의 경우 정밀도와 편의성 문제로 간단한 게임이나 프레젠테이션 및 리모컨 등에 주로 사용되며,
리모컨처럼 허공에서 마우스를 제어하기 때문에 에어 마우스 또는 자이로스코프 마우스라고 합니다.
제품명은 제조사와 용도에 따라 다양하니 자이로 센서로 제어한다는 것만 기억하면 될 것 같습니다.

이런 에어 마우스를 구현하기 위해서는 자이로 센서와 가속도 센서가 있는 제품을 이용해야합니다.
아마, 가성비로 많이 사용되는 센서 중 하나가 MPU-6050 센서라고 생각됩니다.

문제는.. 에어 마우스 기능을 구현하려면 센서의 값을 적분해서 속도와 위치를 계산해야 하는데
자이로스코프와 가속계 등의 원리에 대한 확실한 이해와 오차 보정 등에 대한 지식이 필요합니다.
하지만, 제가 이쪽과는 거리가 멀기 때문에 이 부분에 대해서는 각자 구글링하셔서 해결하시기 바랍니다.*^^*
주로 드론 계열의 강좌를 보시면 설명이 잘 나와 있을 거라 봅니다.

위의 "사전 지식"을 학습하셨으면 자이로센서 등의 데이터를 아두이노에서 가져오는 방법은 이미 아셨을 거라 봅니다.

이렇게 가져온 데이터를 아두이노에서 제공하는 Mouse 클래스를 이용해서 제어하면 에어 마우스가 됩니다.^^

 

 

에어 마우스 구현 컨셉..

MPU-6050 센서를 좌/우/앞/뒤로 기울였을 때 화면에서 마우스가 이동하려면 무엇이 필요할 까요?

아주 쉽게~ 생각하면... 마우스를 제어하는 방법과 센서를 제어하는 방법을 알아야겠지요?

 

아두이노에서 마우스를 제어하기 위해서는 Mouse 클래스를 이용합니다.
Mouse.begin() 과 Mouse.move()는 연결된 컴퓨터의 마우스를 제어하는 기능으로서 아래 문서를 참고 하세요.

간단히는 Mouse.begin()으로 마우스 제어의 시작을 알리고 Mouse.move()로 마우스를 특정 위치로 이동하는 역할을 합니다.
제일 중요한 부분은 Mouse.move()이며 상대 좌표라는 것입니다.

마우스는 특정 위치에서 특정 위치로 고속으로 이동하는 기능을 합니다.
따라서, 현재 위치를 파악할 수 있어야 하는데.. 저희는 위에서 자이로스코프 센서를 사용한다고 했습니다.
그중 가성비가 좋은 저렴한 MPU-6050 센서를 사용하며 MPU-6050은 각 축에 대한 가속도와 자이로 및 온도 센서입니다.

MPU-6050은 MEMS(Micro Electro Mechanical Systems)로서 자이로 3축과 가속도 3축의 총 6축 센서인데
순서대로 가속도 6바이트 + 온도 2바이트 + 자이로(X/Y/Z) 6바이트의 총 14바이트 정보를 출력합니다.
따라서, 센서 데이터 중 위치 제어에 필요한 자이로 정보를 이용해서 마우스의 위치를 제어하면 됩니다.

즉, 연결된 컴퓨터의 마우스 커서를 제어하기 위해 setup()에서 Mouse.begin()으로 시작하고,
자이로 센서의 데이터 값을 이용해서 센서 값이 변한 만큼 마우스의 위치를 Mouse.move()로 이동시키면 끝입니다.
Mouse.move()는 절대 좌표가 아닌 현재 마우스 커서 위치에서 지정된 좌표만큼 상대 좌표로 이동합니다.
(The motion onscreen is always relative to the cursor's current location.)
다만, 정밀하게 제어하려면 복잡한 공식들이 사용되겠으나~ 어렵고 저도 모르니 논외로 하겠습니다.*^^*


센서 처리..
처음에는 아들을 위해 아무 생각 없이 정품 아두이노 우노로 구현하려고 우노를 선택했었습니다.
자이로센서로는 동일하게 MPU-6050을 사용했으니 센서와 아두이노의 연결 방법 및 제어 소스를 알아야 합니다.

본 강좌에서는 필요가 없으나 우노는 보편적으로 많이 사용되는 모델이고 마우스 제어 부분만...

다른 프로그램의 도움을 받거나 원격 통신 등을 이용하면 우노로도 가능하기에 향후를 위해서 우노 정보도 함께 남겨 놓습니다.

 

먼저, MPU-6050과 연결하기 위해 우노의 I2C 핀을 확인해야 합니다.

Wire Library ( https://www.arduino.cc/en/Reference/Wire )를 보면 아두이노 우노의 경우 I2C가 A4 (SDA), A5 (SCL)로 되어있네요.

533a653de48e669913c248968b413e53_1483611


즉, 아두이노 우노를 사용한다면 I2C 통신에는 A4번(SDA) 핀과 A5번(SCL) 핀이 사용됩니다.

따라서, MPU-6050의 SCL에 아두이노의 A5번 핀과 연결하고, MPU-6050의 SDA 핀과 아두이노의 A4번 핀을 연결하면 됩니다.

하지만, 아두이노 우노는 32u4 기반의 보드가 아니라서 정상적인 방법으로는 Mouse 클래스를 사용할 수 없습니다.

구글링 해보면 정품 아두이노 우노의 경우 펌웨어를 수정해서 강제로 HID 기능을 사용할 수는 있습니다.

 

마우스 제어를 위해 Leonardo 같은 32u4 기반의 보드를 사용해야 하는데...

저는 Micro 보드를 구매했으며 아래 URL에서 Micro 보드에 대한 정보를 확인할 수 있습니다.

https://www.arduino.cc/en/Main/ArduinoBoardMicro 

533a653de48e669913c248968b413e53_1483611
 

 

Micro 보드는 MPU-6050의 SCL과 아두이노의 3번 핀과 연결하고, MPU-6050의 SDA 핀과 아두이노의 2번 핀을 연결하면 됩니다.

 

이제 보드 연결 방법은 알았으니 MPU-6050 센서에서 자이로 값을 얻는 방법을 알아야 합니다.

가장 쉬운 방법은 아두이노 튜토리얼 사이트에서 MPU-6050 센서를 선택합니다.

http://playground.arduino.cc/Main/MPU-6050

533a653de48e669913c248968b413e53_1483611
 

목차에서 "Code" 부분을 클릭합니다.

 

아주 간단한 코드면 충분하므로 Code 영역에서 "Short example sketch" 링크를 클릭합니다.
533a653de48e669913c248968b413e53_1483611


우측 하단의 "[Get Code]"를 선택합니다.
533a653de48e669913c248968b413e53_1483611
 

 

최종 URL은 아래와 같습니다.

 

저는 URL에 있는 소스 코드를 복사 후 통신 속도를 9600에서 115200으로 수정했습니다.

소스 파일은 본 글에 mpu-6050.ino 파일로 첨부했습니다.

 // MPU-6050 Short Example Sketch

// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(115200);
}
void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

 

IDE 환경에서 보드를 "Arduino Micro"를 선택하고 업로드해서 실행합니다.

533a653de48e669913c248968b413e53_1483611
 

 

와우~ MPU-6050 센서에서 원하는 값을 손쉽게 추출할 수 있게 되었습니다.*^^*V

실행 결과를 보면 순서대로 가속도(X,Y,Z)와 온도 및 자이로(X,Y,Z) 값을 확인할 수 있으며,

이 소스를 기준으로 원하는 센서 값을 이용해서 PC의 마우스를 제어하면 되겠습니다.

 

 

마우스 제어..

마우스를 제어하기 위해서는 setup()에 Mouse.begin()을 추가합니다.

그리고 loop()에서 Mouse.move()를 이용해서 마우스의 위치를 이동시키면 됩니다.

 

문제는 센서에서 읽어들인 자이로 값을 그대로 사용하면 안 되기 때문에 필터 등을 구현해야 합니다만....

이 분야와는 담을 쌓아서 그런지 사칙 연산도 힘들다 보니 드론 강좌 등을 아무리 봐도 머리에 안 들어오는 관계로...

저는 예전에 답변했었던 질문의 소스에서 사용된 공식을 그대로 적용했습니다.

복잡한 연산 필요 없이 아래 빨간색으로 표시한 2줄의 연산이면 끝입니다.^^

int16_t gyroX, gyroZ;

int Sensitivity = 300;

 

gyroX = GyX / Sensitivity / 1.1 * -1;

gyroZ = GyZ / Sensitivity * -1;

 

GyX와 GyZ는 센서에서 읽어 들인 값이며 실제 사용할 보정된 값이 gyroX와 gyroZ 입니다.

이 값을 Mouse.move 메서드를 이용해서 위치를 제어하면 끝입니다.

Mouse.move(gyroZ, gyroX);

 

간단하죠? *^^*

보정된 값은 자이로만 이용하며 정교한 공식이 아니라서 흔들림이 있고 시간이 지날수록 누적 오차가 생기기 마련입니다.

하지만, 제가 만들 작품에는 드론처럼 정밀한 제어가 필요하지 않고 단순하게 아들하고 게임을 즐기면 되기에 충분합니다.*^^*

만약, 보다 정밀한 제어가 필요한 분들은 온라인상의 훌륭한 강좌들을 참고하시기 바랍니다.*^^*

 

기존 소스에 마우스 제어 코드를 추가한 소스이며 파일로 첨부했습니다.

[AirMouseBasic.ino]

533a653de48e669913c248968b413e53_1483612
 

 

 

저는 충분하지만 정밀한 제어를 원하시면 저도 모르니 구글링하세요.^^;;;

주로 드론(콥터) 관련 강좌가 설명이 자세하니 드론이나 에어 마우스 강좌 등을 살펴보시면 도움이 되리라 봅니다.

 

참고로, jrowberg의 i2cdev 라이브러리에 있는 MPU6050의 DMP 예제의 경우에는 필터가 적용된 값이라..

출력된 값을 그대로 적용해 보았는데 방향만 반대로 보정해주면 부드럽게 움직이더군요.

대신 가만히 놔둬도 서서히~ 움직입니다.*^^*
역시나 라이브러리 소스나 예제 소스를 자세히 살펴보지 않고 잠깐 적용만 해 봤기에 전혀~ 모릅니다~

 

테스트..

MPU-6050 센서의 경우 자이로 센서라서 방향이 상당히 중요하며 온도도 센서 값에 영향을 미칩니다.

보통은 온도와 가속도 값 등을 활용해서 보정해야 하지만...

이번 프로젝트에서는 상온이라면 모두 무시한 상태로 자이로 값만 사용해도 됩니다.^^

대신 설치 방향은 주의해야 합니다.

533a653de48e669913c248968b413e53_1483611
 

센서 하단을 잘 보시면 X와 Y 방향 표시가 있는데 Y 표시가 있는 저 방향이 앞을 향하고 있어야 합니다.

즉, 사진과 동일한 방향이 마우스의 앞쪽 방향입니다.

 

각자 사용하시는 아두이노 보드에 맞게 결선 후 첨부한 소스를 실행하면 되겠습니다.

아래는 간단한 동작 영상입니다.

 

아쉽게도 3D 프린터 사용 정지~ 명령을 하달 받아서 예쁜 케이스가 없군요.^^;;;

각자 예쁘게 꾸미시고 필요하다면 Mouse 클래스를 살펴보셔서 버튼 기능 등도 구현하시기 바랍니다.

 

 

구매 정보..

제가 구매했던 Micro 제품입니다.

$3.05 - http://s.click.aliexpress.com/e/iqVFiYf2f

!!!!New Pro Micro ATmega32U4 5V/16MHz Module with 2 row pin header For Leonardo best quality

533a653de48e669913c248968b413e53_1483611
 

최저가를 찾아 보니 조금 더 저렴한 제품도 보이네요.

$2.95 - http://s.click.aliexpress.com/e/VZjiMBu

New Pro Micro for arduino ATmega32U4 5V/16MHz Module with 2 row pin header For Leonardo in stock . best quality

533a653de48e669913c248968b413e53_1483611
 

 

$2.94 - http://s.click.aliexpress.com/e/QVjiIIQ

New Pro Micro for arduino ATmega32U4 5V/16MHz Module with 2 row pin header For Leonardo in stock . best quality

533a653de48e669913c248968b413e53_1483611
 

 

MPU-6050 센서입니다.

$1.25 - http://s.click.aliexpress.com/e/FUvjAqF

Free Shipping GY-521 MPU-6050 MPU6050 Module 3 Axis Gyroscope + Accelerometer Module for MPU 6050

533a653de48e669913c248968b413e53_1483611 

 

$1.26 - http://s.click.aliexpress.com/e/FufQVRf

FREE SHIPPING 1PCS GY-521 MPU-6050 MPU6050 Module 3 Axis analog gyro sensors+ 3 Axis Accelerometer Module (GY-521)

533a653de48e669913c248968b413e53_1483612
 

 

마치며..

아주 간단하지만... 손쉽게 구현할 수 있는 에어 마우스에 대해서 살펴봤습니다.

 

MPU-6050 센서는 다양하게 활용되니 고속으로 DMP 값을 직접 읽어 들이고..

화려한 GUI에서 테스트 등을 하고 싶은 분들은 본문에 소개한 유튜브 영상과 아래 글을 참고하세요.

https://diyhacking.com/arduino-mpu-6050-imu-sensor-tutorial/ 

 

제가 구현하려는 목적에는 복잡한 개념이 필요 없어서 다른 자료들을 살펴보지는 않았으나...

단순하게 생각해도 에어 마우스를 구현하는 방법은 많으며 오래된 개념이라 다양한 자료들이 있을 테니 찾아 보시기 바랍니다.^^;;

유사 기능에 관심이 있던 분들이나 아이와 함께 놀고 싶은 분들에게 도움이 되었길 바랍니다.^^;;

제가 만들려고 했었던 장난감은 마우스 클릭 기능 하나만 더 들어가며 외형을 제외하면 에어 마우스와 동일합니다.

그동안 마우스 클릭 기능은 스스로 학습하시라고 숙제로 남겨 놓고~ 장난감(?)은 따로 포스팅하겠습니다.^^;;

 

본문 수정 시 가급적 공유한 곳의 글 들도 함께 수정하려고 노력합니다만 누락되는 경우가 많습니다.^^;;;

특히 영상이 첨부된 글의 경우 수정이 어려워서 수정된 위치가 다양하면 블로그 글만 수정하므로

작성한지 오래된 강좌는 가급적 원본 글도 함께 참고 하시기 바랍니다.

 

 

[참고자료]
[목차] 버섯돌이와 함께하는 아두이노(Arduino) 기초 목차

MPU-6050 Accelerometer + Gyro

Mouse.begin() 함수


Mouse.move() 함수

https://www.arduino.cc/en/Reference/MouseMove

 

KalmanFilter 소스 - TKJElectronics

https://github.com/TKJElectronics/KalmanFilter 

 

[버섯][QnA] MPU-6050 자이로 센서를 이용한 에어 마우스 소스 분석

[영상] MPU6050 First steps


[영상] Arduino UNO Tutorial : MPU6050 DMP Values

[영상] Arduino DIY: MPU 6050 Tutorial - Arduino Uno [Gyro&Accelero](3D Teapot Demo)

[영상] Ep. 57 Arduino Accelerometer & Gyroscope Tutorial MPU-6050 6DOF Module

GY-521 MPU 6050 모듈 사용하기

[Arduino Uno] MPU-6050 6축 자이로 가속도 센서 모듈 GY-521

[아두이노] 6축 자이로/가속도 센서 MP

댓글목록

등록된 댓글이 없습니다.


모바일 버전으로 보기