이번 시간에는 조이스틱으로 서보모터의 각도를 조절해보도록 하겠습니다~


# 준비물


조이스틱 모듈, 서보모터, 아두이노



먼저 모터에는 구동방식에 따라 DC모터, 스텝모터, BLDC모터, 서보모터 등으로 나뉩니다.

그 중에서 서보모터(Servo Motor)는 지정된 각도 내에서,

원하는 각도로 움직일수 있게 제어가 가능한 모터입니다.


주로 0~180도의 움직임 각도를 가지며, 제어는 PWM 신호에 따라 각도가 바뀝니다.

PWM신호는 Pulse Width Modulation의 약자로, 

펄스 신호의 폭의 길이를 조절하는 신호를 통해 제어한답니다.



위 사진에서 보다싶이 모든 PWM 신호는 고정된 주기를 가지고 있으며,

유일하게 변하는 것은 한 주기 내에서 HIGH상태와 LOW 상태의 비율이 변하게 됩니다.


이러한 비율 변화가 각도의 변화가 되도록 서보모터 내부에서 신호처리가 된답니다~


그럼 이제 만들어봅시다!



먼저 저는 Adafruit사의 조이스틱 모듈을 구매해서 사용했습니다.



그리고 핀헤더를 수직으로 납땜하니 사용이 불편해서.. 이렇게 수평으로 납땜했어요~



회로는 위와같이 연결하시면 돼요!


조이스틱 모듈          아두이노

Vcc                       5V

 GND                     GND

Xout                       A0

Yout                       A1

Sel                         8


Xout은 X 축방향의 움직임 값을 나타내구요,

Yout은 Y 축 방향의 값을,

Sel는 눌렸을때 버튼 값을 의미합니다.

여기서 버튼 값의 경우는 단순히 연결한다고 끝이 아니라, Pull-up resistor 세팅을 해주셔야 합니다.

Pull-up resistor가 뭔지 궁금하시면 http://geronimob.tistory.com/19 참고!


  1. int Xval, Yval, Sel;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(8,INPUT);

      //Digital input needs Pull-up resistor setting.
      digitalWrite(8,HIGH);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      Xval = analogRead(A0);
      Yval = analogRead(A1);
      Sel = digitalRead(8);

      Serial.print(Xval);
      Serial.print('\t');
      Serial.print(Yval);
      Serial.print('\t');
      Serial.println(Sel);

      delay(100);
    }


위 코드를 업로드 하고나면 순차적으로 X값, Y값, 버튼 값 이 업데이트 될거에요!




자 그럼 이제 서보모터를 연결해봅시다.


먼저 서보모터는 위에서 언급했다싶이,

PWM신호로 제어가 된답니다.


때문에 Vcc, GND, Signal 이 세 핀이 필요하겠지요~


그럼 연결을 하고 코딩을 해봅시다.


위에 코드를 그대로 살리면서 추가합시다.

먼저 서보모터 함수를 사용하기위해 Servo.h를 불러옵니다.


그 다음 Servo 클래스를 선언하고, 셋업에서 3번핀에 서보를 할당합니다.

지금은 모터가 한개이므로,,, 한 축으로만 제어를 할게요;;


우선 서보모터를 움직이는 함수는 servo.write() 인데, 

안에 들어가야할 값은 0~180도 까지의 각도 값입니다.


하지만 analogRead를 통해 받아온 값은 0~1023의 값이 나오죠.


즉, 0~1023의 값을 0~180 사이의 값으로 맵핑을 해줘야 하는데,

바뀐 변수 = map(바꿀 변수, 바꿀 변수의 최소값, 바꿀 변수의 최대값, 바뀐 변수의 최소값, 바뀐 변수의 최대값)

으로 바꿀수 있습니다!


그리고 명령이 수행되는데 시간이 걸리므로 delay()함수를 넣어줍니다.


  1. #include <Servo.h>

    Servo servo;  // create servo object to control a servo

    int Xval, Yval, Sel,pos;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(8,INPUT);

      //Digital input needs Pull-up resistor setting.
      digitalWrite(8,HIGH);

      //Servo setup with pin3
      servo.attach(3);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      Xval = analogRead(A0);
      Yval = analogRead(A1);
      Sel = digitalRead(8);

      Serial.print(Xval);
      Serial.print('\t');
      Serial.print(Yval);
      Serial.print('\t');
      Serial.println(Sel);

      pos = map(Xval,0,1023,0,180);
      servo.write(pos);              // tell servo to go to position in variable 'pos'

      delay(15);
    }


그럼 위와같은 코딩이 되지요!



구동을 하면 스틱 움직임의 각도에 따라 모터도 움직여요~


아무래도 조이스틱의 축이 2개니, 모터를 2개써서 제어도 가능하겠지요?


그리고 버튼값을 잘 이용한다면 위치 고정(Lock)과 같은 기능도 넣을수 있을듯 하네요ㅋㅋ


궁금한 점은 댓글로 남겨주세요!

+ Recent posts