/** <드론도전기> 에 있는 글은 드론 직접 제작에 도전하고, 시행착오를 겪은 글들의 모음입니다.
만약 드론을 직접 만들고 성공한 글을 확인하고 싶으시면 <how to, 아두이노드론> 카테고리를 방문해 주세요:) **/
아두이노 자이로 센서(MPU-6050)제어
우리는 드론의 균형을 맞추기 전에 드론이 자기 현재의 상태를 인식할 수 있도록 MPU 6050이라는 자이로 센서를 이용하기로 했다.
위의 사진이 MPU 6050이다. 기본적으로는 6축으로 자이로센서와 가속도 센서가 있다. 자이로 센서는 XYZ축의 회전을 측정하는 센서이고 가속도 센서는 XYZ축의 움직임을 측정하는 센서이다.
이 값들을 이용하여 드론의 균형을 맞출 것이다.
MPU 6050 연결
MPU 6050은 I2C라는 통신방식을 이용하여 아두이노 본채랑 통신을 한다. 오늘 사용할 우노(UNO)같은 경우 A4(SDA) A5(SCL)을 이용한다. 다른 보드의 경우 아래와 같다.
VCC를 5V에 연결하고 GND는 GND에 연결해주고 SCL와 SDA를 사용하는 보드에 맞게 연결을 해주면 된다.
코딩
우리가 사용한 코딩은 그냥 자이로센서를 이용해서 나온 원시 값(RAW)한 값을 받아오는 것이다. 어차피 추후에 PID를 이용하기 위해서 이 값들을 이용해주기 때문에 굳이 오늘은 안했다. 코딩은 아래와 같다.
#include<Wire.h>
const int MPU=0x68;//MPU6050 I2C주소
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void get6050();// get 6050();이라는 함수 선언.
void setup()
{
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0);//MPU6050 을 동작 대기 모드로 변경
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop()
{
get6050();//센서값 갱신
//받아온 센서값을 출력합니다.
Serial.print(AcX);
Serial.print(" ");
Serial.print(AcY);
Serial.print(" ");
Serial.print(AcZ);
Serial.print(" ");
Serial.print(GyX);
Serial.print(" ");
Serial.print(GyY);
Serial.print(" ");
Serial.print(GyZ);
Serial.println();
delay(80);
}
void get6050(){
Wire.beginTransmission(MPU);//MPU6050 호출
Wire.write(0x3B);//AcX 레지스터 위치 요청
Wire.endTransmission(false);
Wire.requestFrom(MPU,14,true);//14byte의 데이터를 요청
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)& OX42(TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read(); //0X43 (GYRO_XOUT_H)& 0X44(GYRO_XOUT_H)
GyY=Wire.read()<<8|Wire.read(); //0X45 (GYRO_YOUT_H)& 0X46(GYRO_YOUT_H)
GyZ=Wire.read()<<8|Wire.read();//0X47 (GYRO_ZOUT_H)& 0X48(GYRO_ZOUT_H)
}
#include<wire.h>는 I2C를 이용하기 위한 라이브러리이다. 여기서 나오는 함수는 아래와 같다.
Wire.begin – Wire.h 라이브러리 이용을 시작하게 해준다.
Wire.beginTransmission(MPU)—I2C 통신기기에게 통신을 시작한다고 알려줌
Wire.write(0X6B)—MPU 6050의 주소 입력
Wire.endTransmission을 해야 정보를 보낸다. True인 경우 정보를 보내고 false인 경우 처음으로 돌아가서 다시 정보를 받아온다.
get6050은 자이로센서에서의 값을 읽는 함수를 선언하여 만들어준것이다.
여기서 알아야 하는 것이 0X3B이다. 이 주소 값은 뭐지 라는 생각으로 공부를 하다보니 MPU 6050은 자이로와 가속도 값만을 측정하는 장치가 아니다. 온도도 굳이 측정을 한다….
무슨말이냐면 MPU 6050에서 나오는 데이터 값들 중 우리가 원하는 부분의 주소를 입력하여 그 부분부터 데이터를 받아오기 위해 0X3B로 입력을 해주는 것이다.
Wire.requestFrom(MPU,14,true); 는 14바이트의 데이터를 요청한다. 즉 1비트가 8개모이면 1바이트로 14개의 정보를 불러온다는 것이다.
여기서 14개를 불러오는 이유는 위의 참조를 보게되면
AcX=Wire.read()<<8|Wire.read()를 통해서 두개의 값을 합쳐준다. 이때 두가지의 값을 다 받아오기 위해 6개의 XYZ 가속도 센서 HIGH와 LOW 2개의 온도 H/L 6개의 자이로 H/L의 값을 받아온것이다.
그래서 이 값들을 온전히 이용하기 위해 16비트 짜리로 합쳐주는 과정을 거쳐서 우리가 원하는 값을 얻어 낸다.
결과
오랜만에 이ㅣㅣㅣㅣ지 하게 성공했다. 아니 솔직히 말하면 이 코딩을 하기전에는 interrupt()를 이용해 줘야한다는 것을 들었는데 진짜 필요성을 크게 못느껴서 그냥 버리고 이 코딩으로 했다. 개인적으로는 interrupt를 이용했을때보다 간단하여 응용하기도 더 쉬운것 같아서 나는 이런 방식으로 하는거를 추천한다.
V/R
윤.
드론도전기 #10_20.02.15 (1) | 2020.02.28 |
---|---|
드론도전기 #8_20.02.06 (0) | 2020.02.20 |
드론도전기 #7_20.02.04 (0) | 2020.02.20 |
드론도전기 #4_20.01.30 (0) | 2020.02.20 |
댓글 영역