서보 모터는 위치 피드백을 사용하여 모션과 최종 위치를 제어하는 폐루프 시스템입니다. 서보 모터에는 여러 유형이 있으며, 주요 특징은 샤프트의 위치를 정밀하게 제어할 수 있다는 점입니다.
산업용 서보 모터의 위치 피드백 센서는 보통 고정밀 인코더인 반면, 소형 RC 또는 하비용 서보에서는 일반적으로 단순한 가변저항(포텐셔미터)을 사용합니다. 이들 장치에서 감지된 실제 위치는 오차 검출기로 피드백되어 목표 위치와 비교됩니다. 그런 다음 오차에 따라 컨트롤러가 모터의 실제 위치를 목표 위치와 일치하도록 보정합니다.
이 튜토리얼에서는 하비용 서보 모터를 자세히 살펴보고, 이들이 어떻게 작동하는지 그리고 아두이노로 어떻게 제어하는지 설명하겠습니다.
하비용 서보는 RC 장난감 자동차, 보트, 비행기 등을 제어하는 데 사용되는 소형 액추에이터입니다. 공학도들이 로봇 공학 프로토타이핑, 로봇 팔 제작, 생체 모방 로봇, 휴머노이드 로봇 등에 활용하기도 합니다.
서보 모터 작동 원리
하비용 서보 내부에는 네 가지 주요 구성 요소가 있습니다: DC 모터, 기어박스, 가변저항, 제어 회로. DC 모터는 고속 저토크이지만 기어박스가 속도를 약 60 RPM으로 낮추면서 토크를 증가시킵니다.
가변저항은 최종 기어나 출력 샤프트에 부착되어 있어 모터가 회전하면 가변저항도 함께 회전하며, 출력 샤프트의 절대 각도에 비례하는 전압을 생성합니다. 제어 회로에서 이 가변저항 전압이 신호선에서 오는 전압과 비교됩니다. 필요하면 컨트롤러가 내장 H-브리지를 활성화하여 두 신호의 차이가 0이 될 때까지 모터를 양방향으로 회전시킵니다.
서보 모터는 신호선을 통해 일련의 펄스를 보내 제어합니다. 제어 신호의 주파수는 50Hz여야 하며, 즉 20ms마다 펄스가 발생해야 합니다. 펄스의 폭(지속 시간)이 서보의 각도 위치를 결정하며, 이러한 서보들은 보통 180도 회전합니다(물리적 이동 한계가 있음).
일반적으로 1ms 펄스는 0도, 1.5ms는 90도, 2ms는 180도에 해당합니다. 다만 브랜드에 따라 최소/최대 펄스 폭이 달라질 수 있으며, 0.5ms가 0도, 2.5ms가 180도인 경우도 있습니다.
아두이노 프로젝트용 인기 RC/하비 서보
RC 또는 하비용 서보에는 다양한 모델과 제조사가 있습니다. 서보 모터 선택 시 주요 고려사항은 토크, 작동 전압, 소비 전류, 크기입니다.
메이커들 사이에서 가장 인기 있는 두 모델은 SG90 마이크로 서보와 MG996R입니다.
SG90 마이크로 서보 사양
스톨 토크
1.2kg·cm @4.8V, 1.6kg·cm @6V
작동 전압
3.5 ~ 6V
무부하 전류
100mA
스톨 전류
650mA
최대 속도
60도 / 0.12초
무게
9g
MG996R 서보 사양
스톨 토크
11kg·cm @4.8V, 13kg·cm @6V
작동 전압
4.8 ~ 7.2V
무부하 전류
220mA @4.8V, 250mA @6V
스톨 전류
2.5A
최대 속도
60도 / 0.20초
무게
55g
아두이노 서보 모터 제어
위 내용을 바탕으로 하비용 서보를 아두이노로 제어하는 실습 예제를 만들어 보겠습니다. 스톨 토크 10kg-cm의 금속 기어 고토크 서보인 MG996R을 사용하겠습니다. 높은 토크의 대가는 스톨 전류 2.5A입니다. 구동 전류는 500mA~900mA, 작동 전압은 4.8~7.2V입니다.
전류 사양을 보면 이 서보를 아두이노에 직접 연결할 수 없으며, 별도 전원 공급 장치를 사용해야 함을 알 수 있습니다.
회로도
이 예제의 회로도는 다음과 같습니다.
서보의 제어 핀을 아두이노의 아무 디지털 핀에 연결하고, 그라운드와 양극 선을 외부 5V 전원에 연결한 다음, 아두이노 그라운드도 서보 그라운드에 연결하면 됩니다.
더 작은 하비 서보인 S90 마이크로 서보를 사용하는 경우 아두이노 5V 핀에서 직접 전원 공급이 가능합니다.
S90 마이크로 서보는 무부하 구동 전류가 약 100~200mA로 낮지만, 스톨 전류는 약 500~700mA입니다. 반면 아두이노 5V 핀은 USB 전원 시 약 500mA, 배럴 커넥터 전원 시 최대 1A까지 출력 가능합니다.
이 9g 서보 모터들을 아두이노에 직접 연결해도 작동은 하지만, 더 안정적인 작동을 위해 항상 외부 전원 공급 장치를 사용할 것을 권장합니다.
필요한 부품
MG996R 서보 모터
또는 S90 마이크로 서보
아두이노 보드
5V 2A DC 전원 공급 장치
서보 모터 제어 아두이노 코드
서보 모터 제어를 위한 아두이노 코드를 살펴보겠습니다. 코드는 매우 간단합니다. 서보가 연결된 핀을 정의하고, 그 핀을 출력으로 설정한 후, loop 섹션에서 앞서 설명한 특정 지속 시간과 주파수의 펄스를 생성하면 됩니다.
/* 서보 모터 제어 - 50Hz 펄스 트레인 생성 by Dejan, https://howtomechatronics.com */
#define servoPin 9
void setup() {
pinMode(servoPin, OUTPUT);
}
void loop() {
// 20ms마다 펄스 하나
digitalWrite(servoPin, HIGH);
delayMicroseconds(1450); // 펄스 지속 시간 (마이크로초)
digitalWrite(servoPin, LOW);
delayMicroseconds(18550); // 20ms - 펄스 지속 시간
// 펄스 지속 시간: 600 - 0도; 1450 - 90도; 2300 - 180도
}
테스트 결과 제 서보에서 작동하는 펄스 지속 시간 값은 다음과 같습니다. 0.6ms 펄스가 0도, 1.45ms가 90도, 2.3ms가 180도에 해당했습니다.
서보에 직렬로 멀티미터를 연결해 전류 소모를 측정했습니다. 스톨 시 최대 전류 소모는 0.63A였습니다. 이 제품이 정품 TowerPro MG996R이 아니라 저렴한 복제품이라 성능이 떨어지는 것입니다.
그럼 아두이노 서보 라이브러리를 사용한 더 편리한 제어 방법을 살펴보겠습니다.
/* 아두이노 서보 라이브러리를 사용한 서보 모터 제어 by Dejan, https://howtomechatronics.com */
#include <Servo.h>
Servo myservo; // 서보 제어용 서보 객체 생성
void setup() {
myservo.attach(9, 600, 2300); // (핀, 최소 펄스, 최대 펄스)
}
void loop() {
myservo.write(0); // 서보를 특정 각도로 이동
delay(1000);
myservo.write(90);
delay(500);
myservo.write(135);
delay(500);
myservo.write(180);
delay(1500);
}
라이브러리를 포함하고 서보 객체를 정의한 후, attach() 함수로 서보가 연결된 핀과 펄스 지속 시간의 최소/최대값을 정의합니다. 그런 다음 write() 함수로 0~180도 사이의 서보 위치를 간단히 설정합니다.
여러 서보 모터를 아두이노로 제어하기
아두이노 서보 라이브러리는 대부분의 아두이노 보드에서 최대 12개, 아두이노 메가 보드에서는 최대 48개의 서보를 동시에 제어할 수 있습니다. 여러 서보 제어도 단일 서보 제어만큼 쉽습니다.
다중 서보 제어 예제 코드
/* 아두이노로 다중 서보 모터 제어 by Dejan, https://howtomechatronics.com */
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
void setup() {
servo1.attach(8);
servo2.attach(9);
servo3.attach(10);
servo4.attach(11);
servo5.attach(12);
}
void loop() {
// 모든 서보를 0도 위치로
servo1.write(0);
servo2.write(0);
servo3.write(0);
servo4.write(0);
servo5.write(0);
delay(2000);
// 모든 서보를 90도 위치로
servo1.write(90);
servo2.write(90);
servo3.write(90);
servo4.write(90);
servo5.write(90);
delay(2000);
// 모든 서보를 180도 위치로
servo1.write(180);
servo2.write(180);
servo3.write(180);
servo4.write(180);
servo5.write(180);
delay(2000);
}
Servo 클래스에서 각 서보 모터용 객체를 생성하고 어떤 아두이노 핀에 연결되는지 정의하면 됩니다. 물론 각 서보를 언제든 원하는 위치로 이동시킬 수 있습니다.
아두이노로 서보를 제어하는 또 다른 방법은 PCA9685 서보 드라이버를 사용하는 것입니다. 이는 아두이노와 I2C 버스로 통신하는 16채널 12비트 PWM 및 서보 드라이버입니다. 내장 클록이 있어 16개 서보를 아두이노와 독립적으로 자유롭게 구동할 수 있습니다.
더 놀라운 것은 최대 62개의 드라이버를 단일 I2C 버스에 데이지 체인으로 연결할 수 있다는 점입니다. 이론적으로 아두이노의 I2C 핀 두 개만으로 최대 992개의 서보를 제어할 수 있습니다. 6개의 주소 선택 핀으로 각 추가 드라이버의 I2C 주소를 다르게 설정합니다. 납땜 패드를 다음 표에 따라 연결하면 됩니다.
회로도
다시 한번 서보용 별도 전원 공급 장치가 필요함을 알 수 있습니다.
필요한 부품
MG996R 서보 모터
PCA9685 PWM 서보 드라이버
아두이노 보드
5V 6A DC 전원 공급 장치
아두이노와 PCA9685 코드
이 서보 드라이버 제어를 위해 GitHub에서 다운로드할 수 있는 PCA9685 라이브러리를 사용합니다.
/* 아두이노와 PCA9685 드라이버를 사용한 서보 모터 제어 by Dejan, https://howtomechatronics.com
라이브러리: https://github.com/NachtRaveVL/PCA9685-Arduino */
#include <Wire.h>
#include "PCA9685.h"
PCA9685 driver; // PCA9685 출력 = 12비트 = 4096 스텝
// 20ms의 2.5% = 0.5ms; 20ms의 12.5% = 2.5ms
// 4096의 2.5% = 102 스텝; 4096의 12.5% = 512 스텝
PCA9685_ServoEvaluator pwmServo(102, 470); // (-90도, +90도)
// 두 번째 서보
// PCA9685_ServoEvaluator pwmServo2(102, 310, 505); // (0도, 90도, 180도)
void setup() {
Wire.begin(); // Wire 먼저 시작
Wire.setClock(400000); // 지원 보드레이트: 100kHz, 400kHz, 1000kHz
driver.resetDevices(); // Wire 라인의 모든 PCA9685 장치 소프트웨어 리셋
driver.init(B000000); // 주소 핀 A5-A0을 B000000으로 설정
driver.setPWMFrequency(50); // 주파수를 50Hz로 설정
}
void loop() {
driver.setChannelPWM(0, pwmServo.pwmForAngle(-90));
delay(1000);
driver.setChannelPWM(0, pwmServo.pwmForAngle(0));
delay(1000);
driver.setChannelPWM(0, pwmServo.pwmForAngle(90));
delay(1000);
}
라이브러리를 포함하고 PCA9685 객체를 정의합니다. 그런 다음 Servo_Evaluator 인스턴스로 펄스 지속 시간이나 드라이버의 PWM 출력을 정의합니다. 출력이 12비트(4096 스텝 해상도)임을 주의하세요. 최소 펄스 0.5ms(0도)는 102 스텝, 최대 펄스 2.5ms(180도)는 512 스텝에 해당합니다. 하지만 앞서 설명했듯 이 값들은 서보 모터에 맞게 조정해야 합니다. 제 경우 102~470 값이 0~180도에 해당했습니다.
setup에서 I2C 클록 속도, 드라이버 주소, 주파수 50Hz를 설정합니다.
loop에서 setChannelPWM()과 pwmForAngle() 함수로 서보를 원하는 각도로 설정합니다.
두 번째 서보를 드라이버에 연결했는데, 예상대로 첫 번째 서보와 위치가 달랐습니다. 사용 중인 서보가 저렴한 복제품이라 신뢰성이 떨어지기 때문입니다. 하지만 Servo_Evaluator 인스턴스로 각 서보마다 다른 출력 설정을 지정하면 큰 문제가 아닙니다. 90도 위치가 정중앙이 아닌 경우에도 조정 가능하여 모든 서보가 정확한 각도에서 작동하게 할 수 있습니다.
아두이노와 PCA9685 드라이버로 다량의 서보 제어하기
여러 개의 체인된 PCA9685 드라이버로 많은 서보를 제어하는 예제를 더 살펴보겠습니다.
드라이버들을 서로 연결하고 적절한 주소 선택 납땜 패드를 연결해야 합니다. 회로도는 다음과 같습니다.