본문 바로가기
코딩/아두이노

아두이노에서 서보모터 SG-90 사용하는 방법

by DIYver 2020. 9. 14.

<목표>

 

모든 기계에서 구동부로 사용되는 부품중 제일 많은 것이 바로 모터이다.

서보모터는 기계 중에서도 로봇을 제어에 엄청 많이 사용되고 있다.

서보모터는 안에 여러개의 크고 작은 기어들로 구성되어 있어서 힘(토크)이 세고,

PWM 신호를 통해서 각도를 제어할 수 있다.

 

 

-서보모터의 원리를 이해하고, 아두이노에서는 어떻게 사용할 수 있는지 알아보자.

 


<준비물>

 

 

- 아두이노(나노, 우노, 메가), 시리얼 통신 케이블, 점퍼선(M-M)

 


<회로도>

 

 

 

서보모터를 사용하다보면 항상 헷갈리곤 하는게 GND가 뭐고, SIGNAL 선이 어떤 것인지이다.

 

신호선에 ▼ 삼각형 표시가 있으니, 앞으로는 헷갈려하지 말자!

아니면 주황색 선이 신호선이라는 것을 기억하자!

 

 

 


<센서 원리>

 

서보모터는 PWM 신호를 통해서 제어할 수 있다.

아두이노 우노에는 PWM 신호를 보낼 수 있는 디지털 핀이 3 5 6 9 10 11 로 총 6개가 있다.

 

PWM 신호는 Pulse Width Modulation 의 약자로 펄스 폭 변조 라는 뜻이다.

디지털 출력으로 아날로그를 흉내낸다고 보면 이해하기 편하다.

 

만약 신호를 일정하게 계속 내보내 준다면 그 신호는 5V가 될 것이다.

그런데 신호를 0.1초 동안 HIGH를, 0.1초 동안은 LOW를 반복해서 출력한다면

그 신호는 중간값인 2.5V를 띄게 된다.

이때 duty 비를 50% 라고 한다.

 

만약 duty비가 20%이면 출력 전압은 몇 V 일까?

답은 1V 가 된다.

5V * 20%(duty ratio) =  1V

 

쉽운 이해를 위해서 0.1초 라고 한 것인데, 

서보모터에서는 한 사이클이 20ms 라고 보고,

HIGH 신호가 1ms 동안 지속되면 ( duty ratio = 5% ) 0도를 가리킨다.

HIGH 신호가 1.5ms 동안 지속되면 (duty ratio = 7.5% ) 90도를 가리킨다.

HIGH 신호가 2ms 동안 지속되면 (duty ratio = 10% ) 180도를 가리킨다.

이처럼 서보모터는 PWM 신호로 제어하게 된다.

아두이노 이외의 다른 임베디드 보드에서 서보모터를 제어한다면

PWM 신호를 통해서 제어해야 한다.

1500 이면 중앙, 1000이면 오른쪽, 2000 이면 왼쪽이 되겠다.

펄스 신호 폭에 해당하면 단위는 micro sec ( 10^-6 sec) 이다.

 

PWM 신호를 통해서 제어를 한다면 더 세밀하게 각도 제어가 된다는 것이 장점이다.

 

 

PWM 신호를 통해서 제어하는것이 원칙이지만,

아두이노는 사용자의 편의성을 위해서 Servo.h 라는 헤더파일을 기본으로 제공하고 있다.

이 헤더파일이 있으면 어느 핀에서든지 서보모터를 제어할 수 있게된다.

대신 PWM 신호로 제어하는 것이 아닌 각도로 제어할 수 있어 편리하지만,

아무래도 PWM 신호보다는 섬세함이 떨어지게 된다.

 

 


<코드>

 

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

  코드는 아두이노의 예제 파일에 있다.

 

Servo 에 보면 두개가 있는데, Sweep 을 열면 된다.

 

 

Servo.h 헤더 파일을 추가하는 부분이다.

이 헤더 파일 덕분에 아두이노에서 아주 편리하게 서보모터를 이용할 수 있다.

 

서모 모터 이름을 선언해주는 부분이다.

myservo 대신에 자신이 원하는 이름으로 설정해 주면 된다.

 

각도를 뜻하는 position 의 앞 세글자만 딴 변수이다.

초기값을 0으로 설정하였다.

 

셋업 부분에서 자신이 사용하려는 서보모터 신호를 디지털핀에 매칭시킨 것이다.

즉, 9번핀을 통해서 서보모터를 제어하겠다는 셋팅이다.

 

반복문에서 각도를 0도에서 180도 까지 1도씩 증가시키고,

180도 까지 움직였으면, 다시 0도까지 움직이게하는 명령이다.

 

 

 

여기서 중요한 것은 각도 증가가 1도씩 되어있는데, 

1도를 초과해서 증가시키면 서보모터가 휙휙 움직이면서 진동이 심해지게된다.

이런 진동은 나중에 문제가 될 수 있으므로 가끔씩 1도씩 제어하는 것이 부드러운 제어에 도움이 된다.

 

그리고 서보모터를 제어하고 나서는 delay(15); 를 필수적으로 넣어주어야 한다.

서보모터가 돌아가는데 까지 시간을 부여하는 것이다.

 

만약 0도에서 갑자기 180 도 까지 움직이고 싶다면 delay(50) 정도 부여하면 안정적이다.

 

 

이 밖에도 서보모터로 각도를 읽어들일 수 있고,

서보모터 연결을 해제할 수도 있다.

이건 다음에 다루도록 한다.

 

 

 


<실행 결과>

https://youtu.be/p4bzCPr89ag

 

서보모터가 비교적 정확하게 움직이기도 하지만, 각도제어가 완벽하다고 할 수는 없다.

영상에서 보는 것 처럼 움직이는 반경이 0~180 도 라고 하기에는 무리가 있다.

 

현실적 문제는 0~190도 까지 움직이는 녀석도 있고,

영상처럼 0~170 도 까지 움직이는 녀석도 있다는 것이다.

 

따라서 서보모터는 일반 모터에 비해서 각도를 제어할 수 있지만

스테핑 모터에 비하면 그 정확도가 확실히 낮다고 할 수 있다.

 

 

***

아두이노는 출력 가능한 전류량이 적어서 서보모터를 2개 이상 돌릴때, 

문제가 생길 수 있다.

따라서 서보모터를 여러개 사용해야 하는 경우에는 외부 출력이 필수적이다.

***

 

 

 

 


※ 궁금하시거나 질문사항이 있으시면 댓글로 작성해주시면 답변해 드릴 수 있는 부분에서 친절히 답변드리겠습니다!

 

 

 

 

댓글