서보모터는 주로 제어분야에 사용되는 모터로, 모터의 회전을 정밀하게 제어할 수 있도록 만들어진 모터입니다. 그중 오늘 사용할 서보모터는 SG90으로, 크기가 매우 작아 주로 마이크로 서보모터라고 불리는 제품입니다. 입력에 따라 모터의 회전각도 제어가 가능합니다. 이때 서보모터에 주는 입력은 PWM 입력을 통해서 입력하며 dutyCycle에 따라 회전각도를 출력하게 됩니다. 검색을 통해 찾은 SG90의 데이터 시트는 아래 첨부하도록 하겠습니다.
"파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음"
데이터 시트에서 SG90의 동작에 대한 정보를 알 수 있습니다. 오른쪽 아래 파형을 보면 우선 PWM의 주기는 20ms이며, DutyCycle의 범위가 1~2ms 임을 알 수 있죠. 데이터 시트에서는 DutyCycle이 1.5, ms 일 때 회전각은 0도, 1ms 일 때 -90도 2ms 일 때 +90도를 출력하게 됩니다. 즉 SG90의 회전각도는 180도라는 것이죠. 이보다 더 큰 회전각도가 필요하다면 다른 서보모터를 고려해보셔야 합니다.
그런데 위의 데이터 시트를 토대로 아두이노에서 SG90의 제어를 해보니, 180도의 회전각도가 나오지 않는 것을 발견했습니다. 데이터 시트가 잘못된 것인지 확인을 해보도록 하겠습니다.
아두이노 우노 보드와 SG90 서보모터와의 연결은 아래 그림과 같습니다. 데이터 시트에서 보면 갈색선은 GND 빨간 선은 5V, 노란선은 PWM 입력입니다. 저는 PWM 출력이 가능한 6번 핀을 사용하였습니다.
아두이노에서는 서보모터를 제어하기 위한 Servo 라이브러리를 제공하고 있습니다. 이를 활용해서 SG90의 DutyCycle을 확인해 보도록 하겠습니다. 저는 간단하게 컴퓨터와 아두이노 우노 보드의 시리얼 통신을 통해서 입력한 값으로 서보모터에 DutyCycle의 범위가 어떻게 되는지 확인해보았습니다. Servo 라이브러리에서는 20ms의 PWM 주기를 제공하고 있기 때문에 주기는 변경 없이 사용하도록 하겠습니다.
#include <Servo.h>;
Servo sg90;
int c;
void setup() {
Serial.begin(9600);
sg90.attach(6);
c=1000;
}
void loop() {
if(Serial.available()){
c = Serial.parseInt();
Serial.print("PWM출력 : ");
Serial.println(c);
sg90.writeMicroseconds(c);
delay(500);
}
}
Servo 라이브러리에서 제공하는 함수를 살펴보겠습니다. 우선 Servo 라이브러리는 C++ 언어를 기반으로 구현되어있기에 사용하기 위해서는 Servo 객체를 선언해주어야 합니다.
서보모터를 제어할 핀을 지정해주는 함수는 attach 함수입니다.
servo.attach(pin)
servo.attach(pin, min, max)
여기서 min과 max는 0도와 180도 기준의 DutyCycle 최솟값과 최댓값입니다. 따로 정하지 않으면 기본값으로는 544, 2400으로 지정됩니다.
서보모터 제어용 PWM을 출력하는 함수는 write와 writeMicroseconds 함수가 있습니다.
servo.write(angle)
servo.writeMicroseconds(uS)
두 함수의 차이는 write에는 원하는 각도를 입력하는데 이 각도를 통해 DutyCycle을 계산하여 출력합니다. 따라서 이 경우 attach 함수를 입력해줄 때 min과 max를 정확하게 입력해줘야 하겠죠. 반면 writeMicroseconds의 경우 입력해준 DutyCycle을 출력해주기 때문에 SG90의 데이터 시트가 맞지 않는 상황에서는 writeMicroseconds가 더 적합하죠.
시리얼 통신은 아두이노 IDE의 시리얼 모니터를 통해 입력했습니다. 시리얼 모니터는 아래 사진의 아이콘을 누르면 되며 제 코드에서 오류를 없애려면 line ending 없음으로 변경해주셔야 합니다.
시리얼 모니터에 적당한 값을 입력해 보았습니다. 우선 데이터 시트에서 얻어낸 1ms~2ms를 입력해보았으나, 회전각도가 거의 90도 정도밖에 안 되는 것을 알 수 있었습니다. 즉, 데이터 시트가 잘못됐다는 것이죠. 그래서 입력값을 여러 번 변경해보니 attach의 기본값인 min=544, max=2400이 대략 맞는 것을 알 수 있었습니다. 따라서 그냥 attch의 기본값을 통해 제어를 해도 SG90의 경우 큰 문제가 없을 것으로 보입니다.
DutyCycle을 확인했으니 서보모터 작동을 확인해보도록 하겠습니다. 서보모터 연결은 동일합니다.
#include <Servo.h>;
Servo sg90;
void setup() {
sg90.attach(6);
}
void loop() {
sg90.write(0);
delay(500);
sg90.write(45);
delay(500);
sg90.write(90);
delay(500);
sg90.write(135);
delay(500);
sg90.write(180);
delay(1000);
}
write 함수는 각도를 지정하기 때문에 0도부터 180도까지 변경되도록 코드를 만들었습니다.
코드를 보드에 올려 동작을 시켜보니 원하는 대로 0도에서 180도로 정상 작동하는 것을 알 수 있었습니다.
댓글