LED가 켜지는 순간에서 바퀴가 도는 순간으로
앞 장에서 우리는 LED를 켜고, 버튼을 읽고, 브레드보드 위에서 전류가 어떻게 흐르는지 살펴보았다. LED가 켜지는 회로는 조용하다. 불빛이 들어오고 꺼질 뿐이다. 하지만 모터는 다르다. 전기를 넣는 순간 축이 돌아가고, 바퀴가 굴러가며, 로봇이 책상 위를 실제로 움직이기 시작한다.
이 장에서 다룰 DC 모터는 바퀴 로봇에서 가장 흔히 만나는 액추에이터다. 액추에이터란 전기 신호를 실제 움직임으로 바꾸는 장치를 말한다. 센서가 세상을 읽는 눈과 귀라면, 모터는 로봇의 다리와 팔이다.
DC 모터는 구조가 단순하고 가격이 저렴하며 제어 방법도 비교적 쉽다. 그래서 처음 만드는 장애물 회피 자동차, 라인트레이서, 소형 이동 로봇에는 거의 항상 DC 모터가 들어간다. 그러나 단순하다고 해서 아무렇게나 연결해도 된다는 뜻은 아니다. DC 모터는 LED보다 훨씬 큰 전류를 사용하고, 회전할 때 전기적 노이즈도 만든다. 보드의 GPIO 핀에 직접 연결하면 보드가 고장 날 수 있다.
이번 장의 목표는 하나다. DC 모터를 "그냥 돌아가는 부품"이 아니라 "속도와 방향을 제어할 수 있는 로봇 구동 장치"로 이해하는 것이다.

DC 모터는 어떻게 회전할까
DC 모터의 DC는 직류 전원을 뜻한다. 배터리처럼 +와 -가 정해진 전원을 넣으면 회전하는 모터라고 생각하면 된다. 아주 단순하게 말하면, DC 모터 안에서는 전기와 자석이 서로 밀고 당기면서 축을 돌린다.
일반적인 브러시 DC 모터 안에는 고정된 자석과 회전하는 코일이 들어 있다. 코일에 전류가 흐르면 코일도 전자석처럼 동작한다. 전자석이 주변 자석과 밀고 당기면서 회전력이 생긴다. 그런데 한 방향으로 계속 돌게 하려면 회전 중간중간 전류의 방향이 적절히 바뀌어야 한다. 이 역할을 브러시와 정류자가 맡는다. 브러시는 회전하는 부분에 전기를 전달하는 접점이고, 정류자는 회전 위치에 따라 코일에 흐르는 전류 방향을 바꿔 주는 구조다.
이 과정을 눈으로 볼 수는 없지만, 손에 모터를 들고 배터리를 살짝 연결해 보면 느낌은 바로 온다. 한쪽 방향으로 전원을 연결하면 축이 시계 방향으로 돌고, +와 -를 바꾸면 반대 방향으로 돈다. DC 모터의 첫 번째 특징은 바로 이것이다. 전원 극성을 바꾸면 회전 방향이 바뀐다.
하지만 실제 로봇에서는 배터리 선을 손으로 바꿔 끼울 수 없다. 로봇이 스스로 앞으로 가고, 뒤로 가고, 왼쪽으로 돌고, 오른쪽으로 돌려면 제어 보드가 모터의 방향을 전기적으로 바꿔야 한다. 이때 필요한 회로가 모터 드라이버다.
그냥 모터보다 기어드 모터를 쓰는 이유
작은 DC 모터를 손에 들고 전원을 넣어 보면 꽤 빠르게 회전한다. 그런데 그 축에 바퀴를 직접 끼워 로봇을 만들면 생각보다 잘 움직이지 않는다. 소리는 요란하게 나는데 바퀴가 힘없이 헛돌거나, 바닥에 내려놓는 순간 멈춰 버리기도 한다.
이유는 토크가 부족하기 때문이다. 토크는 회전시키는 힘이다. 문손잡이를 돌릴 때 손잡이를 비트는 힘, 자전거 페달을 밟아 바퀴를 굴리는 힘을 떠올리면 된다. 모터가 아무리 빠르게 돌아도 바퀴를 밀어낼 힘이 부족하면 로봇은 움직이지 못한다.
그래서 바퀴 로봇에는 보통 기어드 DC 모터를 사용한다. 기어드 모터는 DC 모터 앞에 기어박스가 붙어 있는 모터다. 기어박스는 회전 속도를 낮추는 대신 토크를 높여 준다. 빠르게 도는 작은 모터의 힘을 천천히, 그러나 더 강하게 바꿔 바퀴에 전달하는 것이다.
예를 들어 모터 자체는 1분에 6000번 회전할 수 있다고 하자. 여기에 1:100 감속 기어가 붙으면 출력축은 약 60RPM으로 회전한다. RPM은 1분 동안 몇 바퀴 도는지를 나타내는 단위다. 속도는 100분의 1로 줄었지만, 이론적으로는 토크가 크게 증가한다. 실제로는 기어 마찰 때문에 손실이 있지만, 작은 로봇을 움직이기에는 훨씬 유리해진다.
바퀴 로봇에서 기어드 모터가 중요한 이유는 세 가지다.
바퀴를 천천히 돌릴 수 있어 로봇을 제어하기 쉽다.
감속을 통해 토크가 커져 바닥 마찰과 로봇 무게를 이겨내기 쉽다.
같은 전압에서도 실제 주행에 적합한 속도 범위를 만들 수 있다.
처음 로봇을 만든다면 고속 모터보다 100RPM에서 300RPM 사이의 기어드 모터가 다루기 쉽다. 너무 빠른 모터는 멋져 보이지만, 로봇이 직진하기도 전에 책상 밖으로 달려 나갈 수 있다. 처음에는 느리고 힘 있는 모터가 훨씬 좋은 선생님이다.
DC 모터를 보드 핀에 직접 연결하면 안 되는 이유
LED는 아두이노나 ESP32의 GPIO 핀에 저항을 거쳐 연결할 수 있었다. 그래서 처음 모터를 만지는 사람은 이런 생각을 하기 쉽다. "모터도 출력 장치니까 GPIO 핀에 연결하면 되지 않을까?"
절대 그렇게 하면 안 된다.
GPIO 핀은 신호를 내보내는 핀이지, 모터를 돌릴 만큼 큰 전류를 공급하는 전원 장치가 아니다. 작은 DC 모터도 회전할 때 수십 mA에서 수백 mA 이상의 전류를 사용할 수 있다. 특히 멈춘 상태에서 처음 돌기 시작할 때, 또는 바퀴가 걸려서 모터가 멈췄을 때는 훨씬 큰 전류가 흐른다. 이것을 기동 전류 또는 스톨 전류라고 한다. 스톨은 모터가 전원을 받았지만 축이 움직이지 못하는 상태다.
마이크로컨트롤러의 GPIO 핀은 보통 작은 신호 전류만 다룰 수 있다. 여기에 모터를 직접 연결하면 핀이 과열되거나 보드가 리셋되거나, 심하면 보드가 영구적으로 고장 날 수 있다. 게다가 모터는 코일로 이루어진 부품이다. 코일에 흐르던 전류가 갑자기 끊기면 순간적으로 높은 전압이 튀는 현상이 생길 수 있다. 이것을 역기전력 또는 인덕티브 킥백이라고 부른다. 말이 어렵지만, 쉽게 말하면 모터가 전기적으로 "툭" 하고 반발하는 순간이 생긴다는 뜻이다.
그래서 제어 보드와 모터 사이에는 모터 드라이버가 들어간다. 제어 보드는 모터 드라이버에 작은 신호를 보낸다. 모터 드라이버는 외부 전원에서 큰 전류를 받아 모터로 흘려보낸다. 즉, 보드는 명령을 내리고 드라이버는 힘을 쓰는 구조다.
로봇 회로를 그릴 때는 이 구분을 꼭 기억해야 한다.
제어 보드 GPIO ── 신호 ──> 모터 드라이버 ── 큰 전류 ──> DC 모터
배터리 전원 ───────────> 모터 드라이버 ───────────> DC 모터여기서 중요한 조건이 하나 더 있다. 제어 보드의 GND와 모터 전원의 GND는 서로 연결되어야 한다. 앞 장에서 배운 공통 GND 개념이 여기서 다시 등장한다. 신호는 기준점이 있어야 의미가 있다. 보드와 드라이버가 같은 GND를 기준으로 삼아야 HIGH와 LOW 신호가 제대로 전달된다.
단, GND를 공유한다는 말은 보드의 5V 핀으로 모터 전원을 공급하라는 뜻이 아니다. 보드 전원과 모터 전원은 필요에 따라 분리하고, 기준점인 GND만 함께 묶는다고 이해하면 된다.
속도 제어의 핵심, PWM
DC 모터의 속도는 대체로 전압과 관련이 있다. 같은 모터에 더 높은 전압을 주면 더 빠르게 돌고, 낮은 전압을 주면 느리게 돈다. 물론 모터마다 정격 전압이 있으므로 무작정 전압을 높이면 안 된다. 6V 모터에 12V를 계속 넣으면 빠르게 돌 수는 있지만 발열과 손상 위험도 커진다.
그렇다면 제어 보드가 모터 속도를 조절하려면 어떻게 해야 할까? 매번 전압을 아날로그 방식으로 부드럽게 바꿔야 할까? 실제로는 PWM을 많이 사용한다.
PWM은 Pulse Width Modulation의 약자로, 펄스 폭 변조라고 부른다. 말은 어렵지만 원리는 간단하다. 전원을 아주 빠르게 켰다 껐다 하면서, 켜져 있는 시간의 비율을 바꾸는 방식이다.
예를 들어 5V 전원을 기준으로 생각해 보자. 모터에 5V를 계속 주면 100% 출력이다. 반대로 계속 꺼져 있으면 0% 출력이다. 그런데 아주 짧은 시간 안에서 절반은 켜고 절반은 끄면, 모터는 평균적으로 약 2.5V를 받은 것처럼 반응한다. 이때 켜져 있는 시간의 비율을 듀티 사이클이라고 한다.
듀티 사이클 100% : 계속 ON → 빠르게 회전
듀티 사이클 50% : 절반 ON/OFF → 중간 속도
듀티 사이클 20% : 조금만 ON → 느리게 회전
듀티 사이클 0% : 계속 OFF → 정지모터는 LED처럼 빠르게 깜빡이는 것을 눈으로 보는 장치가 아니다. 회전축과 바퀴에는 관성이 있다. 관성은 움직이던 물체가 계속 움직이려는 성질이다. 그래서 PWM 신호가 충분히 빠르면 모터는 켜졌다 꺼졌다를 따로따로 느끼기보다 평균적인 힘으로 회전한다.
아두이노에서는 analogWrite() 함수를 사용해 PWM 출력을 만들 수 있다. 이름은 analogWrite지만 실제로는 진짜 아날로그 전압을 출력하는 것이 아니라 PWM 신호를 출력한다. ESP32에서도 PWM 기능을 사용할 수 있으며, 보드 환경에 따라 analogWrite()가 지원되거나 LEDC 기능을 사용한다.
모터 드라이버로 한 개의 DC 모터 돌리기
이제 실제 연결을 생각해 보자. 여기서는 특정 드라이버 칩의 모든 세부 사항을 외우기보다, 대부분의 DC 모터 드라이버가 비슷한 방식으로 동작한다는 감각을 익히는 것이 중요하다. 자세한 모터 드라이버 선택과 H-Bridge 구조는 뒤에서 별도의 장으로 더 깊게 다룬다.
일반적인 DC 모터 드라이버에는 방향 제어 핀 두 개와 속도 제어 핀 하나가 있다. 이름은 모듈마다 조금 다르지만 역할은 비슷하다.
IN1, IN2: 모터의 회전 방향을 정하는 핀
EN 또는 PWM: 모터 출력의 세기, 즉 속도를 조절하는 핀
VM 또는 Motor VCC: 모터를 돌리기 위한 외부 전원 입력
VCC 또는 Logic VCC: 드라이버의 논리 회로 전원 입력
GND: 기준 전압, 보드와 모터 전원이 함께 공유해야 하는 지점
예를 들어 방향 핀을 다음처럼 제어할 수 있다.
| IN1 | IN2 | 모터 상태 |
|---|---|---|
| LOW | LOW | 정지 또는 브레이크 방식에 따라 대기 |
| HIGH | LOW | 정방향 회전 |
| LOW | HIGH | 역방향 회전 |
| HIGH | HIGH | 정지 또는 브레이크 |
드라이버마다 LOW/LOW와 HIGH/HIGH에서의 정지 동작이 조금 다를 수 있다. 어떤 모듈은 모터를 자유롭게 굴러가게 두는 코스트 상태가 되고, 어떤 모듈은 전기적으로 제동을 거는 브레이크 상태가 된다. 처음에는 "IN1과 IN2를 서로 반대로 주면 방향이 바뀐다" 정도로 이해하면 충분하다.
연결할 때는 반드시 전원을 다시 확인해야 한다. 제어 보드의 5V 또는 3.3V 핀으로 모터를 돌리려고 하면 안 된다. 작은 테스트라 해도 USB 포트가 버티지 못해 보드가 리셋될 수 있다. 모터 전원은 별도 배터리나 충분한 전류를 낼 수 있는 전원에서 공급하고, GND를 보드와 공유한다.
기본 연결 구조는 다음과 같다.
아두이노/ESP32 GND ─────────┐
├── 모터 드라이버 GND
모터 배터리 - ─────────────┘
보드 GPIO 1 ────────────────> IN1
보드 GPIO 2 ────────────────> IN2
보드 PWM 핀 ────────────────> EN 또는 PWM
모터 배터리 + ──────────────> VM 또는 Motor VCC
모터 드라이버 OUT1/OUT2 ───> DC 모터 양쪽 단자처음 실험할 때는 바퀴를 바닥에 내려놓지 말고 공중에 띄운 상태에서 테스트하자. 로봇이 갑자기 튀어나가는 일을 막을 수 있고, 배선이 잘못되었을 때도 피해를 줄일 수 있다.
아두이노로 DC 모터 속도와 방향 제어하기
다음 예제는 방향 핀 두 개와 PWM 핀 하나로 DC 모터 한 개를 제어하는 기본 코드다. 사용하는 모터 드라이버에 따라 핀 이름이 조금 다를 수 있지만, 개념은 같다.
const int IN1 = 7;
const int IN2 = 8;
const int PWM_PIN = 9;
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(PWM_PIN, OUTPUT);
}
void motorForward(int speedValue) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(PWM_PIN, speedValue);
}
void motorBackward(int speedValue) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(PWM_PIN, speedValue);
}
void motorStop() {
analogWrite(PWM_PIN, 0);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
void loop() {
motorForward(80);
delay(1500);
motorForward(160);
delay(1500);
motorForward(255);
delay(1500);
motorStop();
delay(1000);
motorBackward(160);
delay(1500);
motorStop();
delay(2000);
}아두이노의 analogWrite() 값은 보통 0부터 255까지 사용한다. 0은 0%, 255는 거의 100% 듀티 사이클에 해당한다. 위 코드에서는 먼저 낮은 속도로 돌리고, 중간 속도, 최대 속도에 가깝게 올린 뒤 멈춘다. 그다음 반대 방향으로 회전한다.
여기서 한 가지 재미있는 현상을 볼 수 있다. 아주 작은 PWM 값에서는 모터가 "윙" 소리만 내고 돌지 않을 수 있다. 예를 들어 analogWrite(PWM_PIN, 20)을 넣었는데 모터가 움직이지 않는 경우가 있다. 이것은 이상한 일이 아니다. 모터가 처음 회전하려면 정지 마찰을 이겨야 한다. 너무 약한 출력은 이 마찰을 넘지 못한다.
그래서 실제 로봇에서는 최소 구동 PWM 값을 찾아 두는 것이 좋다. 어떤 모터는 40부터 돌기 시작하고, 어떤 모터는 70 이상을 줘야 안정적으로 움직인다. 같은 모델의 모터라도 좌우가 완전히 같지 않을 수 있다. 이 차이가 나중에 로봇이 한쪽으로 휘어지는 원인이 된다.
ESP32로 DC 모터 제어하기
ESP32도 DC 모터 제어에 자주 사용된다. Wi-Fi와 Bluetooth를 내장하고 있어 스마트폰으로 조종하는 자동차나 웹 인터페이스를 가진 로봇을 만들기 좋다. 다만 ESP32의 GPIO는 3.3V 논리 신호를 사용한다. 모터 드라이버가 3.3V 입력을 확실히 인식하는지 확인해야 한다.
ESP32 개발 환경에서는 보드 패키지 버전에 따라 analogWrite()를 사용할 수 있는 경우도 있지만, PWM 제어를 명확히 이해하려면 LEDC 기능을 사용하는 방식을 알아두는 것이 좋다. LEDC는 ESP32의 PWM 출력 기능이라고 보면 된다.
const int IN1 = 25;
const int IN2 = 26;
const int PWM_PIN = 27;
const int PWM_CHANNEL = 0;
const int PWM_FREQ = 1000;
const int PWM_RESOLUTION = 8; // 0~255
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
ledcSetup(PWM_CHANNEL, PWM_FREQ, PWM_RESOLUTION);
ledcAttachPin(PWM_PIN, PWM_CHANNEL);
}
void setMotor(int speedValue) {
if (speedValue > 0) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
ledcWrite(PWM_CHANNEL, speedValue);
} else if (speedValue < 0) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
ledcWrite(PWM_CHANNEL, -speedValue);
} else {
ledcWrite(PWM_CHANNEL, 0);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
}
void loop() {
setMotor(120);
delay(1500);
setMotor(220);
delay(1500);
setMotor(0);
delay(1000);
setMotor(-160);
delay(1500);
setMotor(0);
delay(2000);
}이 예제에서는 속도값에 부호를 붙였다. 양수면 정방향, 음수면 역방향, 0이면 정지다. 이런 방식은 나중에 좌우 바퀴를 제어할 때 편리하다. 왼쪽 모터에 150, 오른쪽 모터에 150을 주면 전진하고, 왼쪽에 -150, 오른쪽에 150을 주면 제자리 회전에 가까운 움직임을 만들 수 있다.
단, ESP32 보드와 모터 전원을 함께 사용할 때는 전압 강하에 주의해야 한다. 모터가 출발하는 순간 전류를 많이 끌어가면 ESP32가 재부팅될 수 있다. 무선 연결이 갑자기 끊기거나 시리얼 모니터에 부팅 메시지가 반복된다면 전원 문제를 먼저 의심하자.
방향 제어와 H-Bridge의 직관적 이해
DC 모터의 방향은 모터 양쪽 단자에 걸리는 전압의 극성으로 결정된다. 왼쪽 단자에 +, 오른쪽 단자에 -를 연결하면 정방향으로 돌고, 반대로 연결하면 역방향으로 돈다.
그렇다면 회로 안에서 이 극성을 어떻게 바꿀까? 가장 대표적인 방법이 H-Bridge다. H-Bridge는 네 개의 스위치를 H 모양처럼 배치해 모터에 흐르는 전류 방향을 바꾸는 회로다. 실제 모터 드라이버 안에는 트랜지스터나 MOSFET이라는 전자식 스위치가 들어 있다. 우리는 손으로 스위치를 누르지 않고, GPIO 신호로 이 스위치를 켜고 끈다.
직관적으로는 네 개의 문이 있다고 생각하면 된다. 전류가 왼쪽 위에서 들어와 모터를 지나 오른쪽 아래로 빠져나가면 한 방향으로 돈다. 반대로 오른쪽 위에서 들어와 모터를 지나 왼쪽 아래로 빠져나가면 반대 방향으로 돈다. 모터 드라이버는 이 문을 안전하게 열고 닫아 주는 장치다.
중요한 점은 위쪽과 아래쪽 스위치를 잘못 동시에 켜면 전원이 바로 GND로 연결되는 위험한 상태가 될 수 있다는 것이다. 이것을 쇼트라고 한다. 모터 드라이버 칩은 이런 위험을 줄이도록 설계되어 있지만, 사용자는 데이터시트나 모듈 설명에 맞게 핀을 연결해야 한다. 방향 핀을 바꿀 때 잠깐 정지 시간을 두는 습관도 좋다.
예를 들어 고속으로 정방향 회전 중인 모터를 즉시 역방향으로 바꾸면 모터와 드라이버에 큰 부담이 걸린다. 작은 로봇에서는 큰 문제가 없어 보일 수 있지만, 모터가 커질수록 위험해진다. 실제 로봇 코드에서는 방향을 바꾸기 전에 PWM을 0으로 낮추고 짧게 멈춘 뒤 반대 방향으로 가속하는 방식이 안전하다.
motorForward(180);
delay(1000);
motorStop();
delay(200);
motorBackward(180);
delay(1000);이 짧은 0.2초의 여유가 회로와 기계 구조를 훨씬 편하게 해 준다.
바퀴 지름, 감속비, 토크가 주행을 바꾼다
같은 모터를 사용해도 어떤 바퀴를 끼우느냐에 따라 로봇의 움직임은 크게 달라진다. 모터는 회전하고, 바퀴는 그 회전을 직선 이동으로 바꾼다. 이때 핵심은 바퀴 둘레다.
바퀴가 한 바퀴 돌 때 로봇이 앞으로 이동하는 거리는 바퀴의 둘레와 같다. 바퀴 둘레는 대략 다음 공식으로 계산한다.
바퀴 둘레 = 바퀴 지름 × 3.14지름이 65mm인 바퀴라면 둘레는 약 204mm다. 바퀴가 한 바퀴 돌 때 로봇은 약 20.4cm 이동한다. 만약 모터 출력축이 100RPM으로 돈다면, 1분에 바퀴가 100바퀴 도는 셈이다. 이론적인 이동 거리는 다음과 같다.
204mm × 100 = 20400mm/min
= 20.4m/min
= 약 0.34m/s초속 0.34m면 작은 실내 로봇에는 꽤 적당한 속도다. 하지만 지름이 100mm인 큰 바퀴를 끼우면 한 바퀴당 이동 거리가 늘어난다. 같은 RPM에서도 로봇은 더 빨라진다. 대신 바퀴가 커질수록 모터가 바닥을 밀어내기 위해 더 큰 토크를 내야 한다. 자전거의 높은 기어로 출발할 때 다리가 무거운 느낌이 드는 것과 비슷하다.
감속비도 중요하다. 감속비가 큰 모터는 출력축이 천천히 돌지만 힘이 좋다. 감속비가 작은 모터는 빠르지만 힘이 약할 수 있다. 로봇이 가볍고 평평한 바닥에서 빠르게 달리면 작은 감속비가 유리할 수 있다. 반대로 배터리와 센서를 많이 싣거나 카펫, 문턱, 경사로를 지나야 한다면 큰 감속비가 필요하다.
토크는 등판 능력에도 영향을 준다. 로봇이 경사로를 올라갈 때는 중력 때문에 뒤로 끌려 내려가는 힘을 이겨야 한다. 바퀴가 크고 로봇이 무거울수록 모터에는 더 큰 부담이 걸린다. 이때 토크가 부족하면 모터는 뜨거워지고, 속도는 떨어지며, 심하면 멈춰 버린다. 바퀴가 헛도는 경우도 있고, 모터는 돌고 있는데 로봇이 올라가지 못하는 경우도 있다.
처음 부품을 고를 때는 최고 속도보다 여유 있는 토크를 우선하는 편이 좋다. 로봇은 자동차 경주를 하기 전에 먼저 안정적으로 출발하고 멈추는 법을 배워야 한다.
양쪽 모터가 똑같이 돌지 않는 문제
바퀴 로봇을 처음 만들면 많은 사람이 같은 문제를 만난다. 왼쪽 모터와 오른쪽 모터에 같은 PWM 값을 줬는데 로봇이 똑바로 가지 않는다. 한쪽으로 슬금슬금 휘거나, 심하면 원을 그리며 돈다.
이것은 아주 흔한 현상이다. 저렴한 DC 기어드 모터는 좌우 특성이 완전히 같지 않다. 기어 마찰, 브러시 상태, 바퀴 조립 상태, 바닥 마찰, 무게 중심이 모두 조금씩 다르다. 같은 analogWrite(150)을 넣어도 왼쪽 모터는 120RPM, 오른쪽 모터는 130RPM으로 돌 수 있다.
처음에는 보정값을 넣어 해결할 수 있다. 예를 들어 오른쪽으로 휘는 로봇은 왼쪽 바퀴가 더 빠르거나 오른쪽 바퀴가 더 느린 경우가 많다. 이때 빠른 쪽 PWM을 조금 낮추거나 느린 쪽 PWM을 조금 올린다.
int baseSpeed = 150;
int leftCorrection = -5;
int rightCorrection = 8;
setLeftMotor(baseSpeed + leftCorrection);
setRightMotor(baseSpeed + rightCorrection);이런 보정은 간단하지만 완벽하지는 않다. 배터리 전압이 낮아지거나 바닥이 바뀌면 다시 달라질 수 있다. 더 정확한 제어가 필요하면 엔코더를 사용해 실제 바퀴 회전량을 측정해야 한다. 엔코더는 뒤의 센서 장에서 자세히 다룬다. 여기서는 DC 모터가 "명령한 만큼 정확히 도는 장치"가 아니라는 점을 기억하면 된다. DC 모터는 명령을 받으면 대략 그에 맞게 도는 장치이고, 정확한 움직임은 센서 피드백과 제어 알고리즘이 함께 만들어 낸다.
이 사실은 로봇 제어의 중요한 출발점이다. 로봇은 명령만으로 움직이지 않는다. 실제로 어떻게 움직였는지 확인하고, 다시 조정하면서 움직인다.
간단한 바퀴 로봇 동작 만들기
DC 모터 두 개를 좌우 바퀴에 연결하면 가장 기본적인 차동 구동 로봇을 만들 수 있다. 차동 구동은 왼쪽 바퀴와 오른쪽 바퀴의 속도 차이로 방향을 바꾸는 방식이다. 자동차처럼 조향 바퀴를 꺾는 것이 아니라, 양쪽 바퀴를 다르게 돌려 회전한다.
기본 동작은 다음과 같이 만들 수 있다.
| 왼쪽 모터 | 오른쪽 모터 | 로봇 동작 |
|---|---|---|
| 정방향 | 정방향 | 전진 |
| 역방향 | 역방향 | 후진 |
| 정지 | 정방향 | 왼쪽으로 회전 |
| 정방향 | 정지 | 오른쪽으로 회전 |
| 역방향 | 정방향 | 제자리 좌회전 |
| 정방향 | 역방향 | 제자리 우회전 |
두 모터를 제어하는 함수는 다음처럼 구성할 수 있다. 실제 핀 번호는 사용하는 보드와 드라이버에 맞게 바꾸면 된다.
void drive(int leftSpeed, int rightSpeed) {
setLeftMotor(leftSpeed);
setRightMotor(rightSpeed);
}
void loop() {
// 전진
drive(150, 150);
delay(1000);
// 정지
drive(0, 0);
delay(500);
// 제자리 우회전
drive(150, -150);
delay(600);
// 다시 전진
drive(150, 150);
delay(1000);
// 후진
drive(-120, -120);
delay(800);
// 정지
drive(0, 0);
delay(2000);
}이 코드는 아직 똑똑한 로봇은 아니다. 센서를 보고 판단하지 않고, 정해진 시간 동안 움직일 뿐이다. 하지만 로봇 제작에서 매우 중요한 첫걸음이다. 바퀴가 원하는 방향으로 돌고, PWM 값에 따라 속도가 달라지고, 좌우 모터 조합으로 방향을 바꿀 수 있다면 로봇의 하체가 완성되기 시작한 것이다.
이제 여기에 거리 센서를 붙이면 장애물을 피할 수 있고, 라인 센서를 붙이면 검은 선을 따라갈 수 있다. 카메라를 붙이면 색깔을 따라 움직이는 로봇도 만들 수 있다. 모든 것은 모터가 안정적으로 움직이는 것에서 출발한다.
실습할 때 꼭 확인할 것들
DC 모터 실습은 회로가 조금만 잘못되어도 증상이 다양하게 나타난다. 모터가 안 돌 수도 있고, 보드가 재부팅될 수도 있고, 한쪽 방향만 동작할 수도 있다. 당황하지 말고 순서대로 확인하면 대부분 해결된다.
먼저 전원을 확인한다. 모터 전압이 모터 정격에 맞는지, 배터리가 충분히 충전되어 있는지 살펴보자. 무부하 상태에서는 도는 것처럼 보이지만 바닥에 내려놓으면 멈춘다면 전류가 부족할 수 있다.
그다음 GND를 확인한다. 보드 GND와 모터 드라이버 GND, 모터 전원 GND가 연결되어 있어야 한다. 공통 GND가 빠지면 신호가 제대로 전달되지 않아 모터가 이상하게 동작할 수 있다.
마지막으로 핀과 방향을 확인한다. IN1과 IN2가 바뀌면 방향이 반대로 돌 수 있다. 이것은 고장이 아니다. 코드에서 방향을 바꾸거나 모터 선을 서로 바꾸면 된다. PWM 핀이 실제 PWM을 지원하는 핀인지도 확인해야 한다. 아두이노 UNO에서는 모든 디지털 핀이 PWM을 지원하지 않는다. 보통 ~ 표시가 붙은 핀이 PWM 핀이다.
테스트할 때는 다음 순서를 추천한다.
바퀴를 공중에 띄우고 낮은 PWM 값부터 천천히 올린다.
모터와 드라이버가 뜨거워지는지 손으로 조심스럽게 확인한다.
방향 전환 전에는 잠깐 정지 시간을 넣는다.
USB 전원만으로 모터를 돌리려 하지 않는다.
배선 변경은 반드시 전원을 끈 상태에서 한다.
특히 모터가 멈춘 상태로 "웅" 소리만 내는 상황을 오래 방치하면 안 된다. 이때는 전류가 많이 흐르면서 모터와 드라이버가 빠르게 뜨거워질 수 있다. 바퀴가 걸렸다면 즉시 전원을 끄고 원인을 확인하자.
DC 모터를 다룬다는 것의 의미
DC 모터는 단순하다. 전압을 주면 돌고, 극성을 바꾸면 반대로 돈다. PWM을 주면 속도가 바뀐다. 여기까지만 보면 쉬워 보인다.
하지만 로봇에서 DC 모터를 제대로 다룬다는 것은 조금 더 넓은 의미를 가진다. 모터가 요구하는 전류를 이해해야 하고, 보드 핀을 보호해야 하며, 모터 드라이버를 통해 큰 전류를 안전하게 제어해야 한다. 바퀴 크기와 감속비를 고려해 원하는 속도와 힘을 맞춰야 하고, 좌우 모터의 차이를 받아들이고 보정해야 한다.
이 장에서 배운 내용은 앞으로 계속 등장한다. 서보 모터와 스텝 모터를 배울 때도, 모터 드라이버를 고를 때도, PWM으로 속도를 제어할 때도, 엔코더로 실제 회전량을 측정할 때도 오늘의 감각이 바탕이 된다.
로봇이 처음으로 바퀴를 굴리는 순간은 꽤 인상적이다. 코드 몇 줄과 전선 몇 가닥이 작은 기계를 움직이게 만든다. 하지만 진짜 중요한 것은 그다음이다. 왜 움직였는지, 왜 느려졌는지, 왜 한쪽으로 휘었는지 이해하기 시작하면 로봇은 더 이상 우연히 움직이는 장난감이 아니다. 이제부터는 당신이 의도한 대로 움직이는 기계가 되어 간다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.