메이킹 일지 (진행 중)/욘두 화살

욘두 화살 - 3. 코딩 작업 (자이로, 서보 모터)

  • -

 

https://bker001.tistory.com/358

 

저번 글에 이어서 하드웨어가 거의 준비되어서 이제 코딩을 할 때가 왔습니다.

일단 이번에 사용해본 자이로센서는 MPU6050으로, 조금 저가형 아두이노 자이로 센서입니다.

서보는 집에 있는거로다가 그냥 SG90과 MG90S를 사용했습니다.

 

 

 

 

servo 모터 아두이노 예시는 일단 서보와 콘트롤러 사이 연동을 확인하기 위한 예시를 사용했습니다.

 

https://make.e4ds.com/make/learn_guide_view.asp?idx=105 

 

e4ds make

 

make.e4ds.com

 

여기의 링크에서 알려주신 아두이노 코드를 그대로 사용했습니다. WASD를 활용해서 그대로 서보를 움직일 수 있기에 매우 편하게 사용할 수 있었습니다.

 

그렇게 실험을 해보니 조그마한 문제가 생겼습니다.

 

 


 

 

자이로 센서를 직접 해봤더니 조그마한 문제가 또 생겼습니다.

자이로 센서를 사용해보기 위해서 일단 예제를 사용해서 접촉해봤습니다.

https://scribblinganything.tistory.com/140

 

MPU6050 가속도 센서, 자이로 센서로 측정값 읽어 보기

MPU-6050 센서란? MPU-6050는 그림1과 같다. 모듈로 되어 있는 PCB 인데 내부에는 MEMS 가속도센서(Accelerometer)와 MEMS 자이로센서(gyro)를 포함하고 있다. 그림처럼 SCL, SDA 통신라인을 이용하는 I2C 통신을

scribblinganything.tistory.com

 

 

생각보다 자이로센서의 민감도가 높기도 하고, 높은 만큼 중간중간 값이 튀는 현상이 발생하는데, 이 문제를 해결할 수 있는 방법을 조금 찾아봤습니다.

 

일단 민감도 자체가 나쁘지는 않다는 게 확실합니다. 어차피 저 정도 정보량이면 코드가 긴거도 아니라서 작동에 큰 영향을 주는 않기 때문에 그대로 가져가며 되는데 가끔씩 튀는게 문제라고 생각했습니다.

그래도 일단 모터와 연동을 시킨 다음에 그때 모터가 받아들이는 것에 따라서 조치를 취하면 되니까..!

 

일단 위의 두 코드를 합쳐줬습니다.

 

// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain

#include <Wire.h>
#include <Servo.h>

Servo servo1; //servo1 변수 선언
Servo servo2; //servo2 변수 선언

const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

int motor1 = 10; //motor1을 입출력 3번 핀에 연결
int motor2 = 11; //motor2을 입출력 5번 핀에 연결
int angle1 = 110; //초기 각도값 설정  
int angle2 = 70; //초기 각도값 설정

int value = 0;

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);
  servo1.attach(motor1); //servo1에 입출력 3번 핀을 지정
  servo2.attach(motor2); //servo2에 입출력 5번 핀을 지정
  Serial.begin(9600);
}

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(50);
  value = map(AcX, -20000, 20000, 75, 135);
  servo1.write(value);
  Serial.print(" | value = "); Serial.print(value);
}

 

 

주로 바뀐 내용은 value 변수를 정의해서 함수를 추가했고, map 함수를 이용해 상한값과 최저값을 정리해서 value값을 모터에 내보냈습니다.

 

이 과정에서 이런식으로 작성되어 있는 시리얼 모니터 보고 자이로 센서를 움직여보면서 원하는 함수를 찾은게 AcX 였습니다.

 

 

 

그렇게 해서 나온 것 :

 

 

 

 

아래는 좀 더 빠르게 반응할 수 있도록 delay를 50으로 줘봤는데 이렇게 조금씩 설정하면서 바꿔나가면 좋을 것 같습니다.

그래도 어느정도 진행되고 있어서 기쁘네요.

 

이 다음에는 주문했던 마이크 모듈의 높낮이를 제서 휘파함 코딩을 진행할 것 같습니다

반응형
Contents

포스팅 주소를 복사했습니다!

이 글이 도움이 되었다면 추천 부탁드립니다!