06. 움직임 만들기: 서보모터 제어

소프트웨어의 논리가 물리적인 세상의 움직임으로 변하는 짜릿한 순간입니다.

1. DC 모터 vs 서보 모터(Servo Motor)

미니카에 들어가는 모터처럼 전기를 주면 윙~ 하고 무한히 도는 것을 DC 모터라고 합니다. 반면, 서보 모터는 내가 원하는 '각도'를 딱 지정하면 그 위치까지만 회전하고 멈추는 아주 똑똑한 모터입니다. 로봇 팔의 관절이나 자동문 등에 주로 쓰이죠.

90° 180°
▲ 서보 모터는 보통 0도에서 180도 사이를 우리가 지정한 각도로 정확하게 움직입니다.

2. 서보모터 연결하기: 3가닥의 비밀

일반 모터는 선이 2개(+, -)뿐이지만, 서보모터는 제어선(Signal)이 하나 더 있어서 총 3개의 선을 가집니다. 색깔을 잘 보고 아두이노에 연결해야 합니다.

선 색상 (제조사마다 다를 수 있음) 역할 아두이노 연결 핀
🟤 갈색 또는 검은색 GND (전기가 빠져나가는 곳) GND
🔴 빨간색 VCC (5V 전원 공급) 5V
🟠 주황색 또는 노란색 Signal (각도를 명령받는 신호선) 디지털 PWM 핀 (예: 9번 핀)

💡 왜 PWM 핀(~ 표시)에 연결하나요?

3장에서 배운 PWM 기억하시나요? 서보모터는 내부적으로 이 PWM 신호(펄스의 폭)를 감지하여 자신의 각도를 결정합니다. 따라서 ~9, ~10 같은 물결무늬 핀에 꽂아야 정상 작동합니다.

3. 라이브러리(Library): 마법의 주문서

PWM 신호로 각도를 제어하는 코드를 우리가 직접 처음부터 다 짜려면 엄청나게 복잡한 C언어 코드가 필요합니다. 다행히 전 세계의 똑똑한 개발자들이 '서보모터를 쉽게 다루는 코드 모음집'을 미리 만들어 두었습니다.

이러한 코드 모음집을 '라이브러리(Library)'라고 부르며, 코드 맨 윗줄에 #include라는 명령어로 불러와서 사용합니다.

💡 실습 1: 서보모터 와이퍼 만들기 (0도 ➡ 180도)

// 1. 서보모터 라이브러리 불러오기 (마법 주문서 장착!)
#include <Servo.h>

// 2. 서보모터를 조종할 객체(리모컨) 만들기
Servo myServo;  

void setup() {
    // 3. 서보모터의 신호선(주황선)이 아두이노 9번 핀에 연결되었다고 알려줌
    myServo.attach(9); 
}

void loop() {
    // 0도 방향으로 이동!
    myServo.write(0);      
    delay(1000); // 모터가 돌아갈 시간을 1초 줍니다.
    
    // 90도 (정면) 방향으로 이동!
    myServo.write(90);     
    delay(1000);
    
    // 180도 방향으로 이동!
    myServo.write(180);    
    delay(1000);
}

⚠️ 모터가 돌아갈 '시간'을 꼭 주세요!

아두이노의 명령 속도는 빛의 속도와 같지만, 물리적인 모터가 움직이는 데는 시간이 걸립니다. myServo.write(180); 명령 직후에 delay() 없이 바로 다음 각도를 명령하면, 모터가 목적지에 도달하기도 전에 다른 명령을 받아 바들바들 떨게 됩니다.

4. 🎯 심화 미션: 다이얼로 조종하는 로봇 팔 (가변저항 + 서보)

3장에서 배운 가변저항(다이얼)과 오늘 배운 서보모터를 결합해 봅시다! 다이얼을 돌리는 각도 그대로 서보모터가 똑같이 따라 돌게 만드는 아주 실용적이고 멋진 예제입니다.

이때, 0~1023의 가변저항 값을 0~180의 각도로 찰떡같이 바꿔주는 map() 함수가 또다시 활약합니다.

#include <Servo.h>

Servo myServo;
int potPin = A0; // 가변저항은 아날로그 A0핀에 연결

void setup() {
    myServo.attach(9); // 서보는 9번 핀에 연결
}

void loop() {
    // 1. 가변저항 손잡이를 얼마나 돌렸는지 읽어옴 (0 ~ 1023)
    int potValue = analogRead(potPin);
    
    // 2. 읽어온 값을 모터의 각도(0 ~ 180) 비율로 변환!
    int angle = map(potValue, 0, 1023, 0, 180);
    
    // 3. 변환된 각도(angle)로 모터를 회전시킴
    myServo.write(angle);
    
    delay(15); // 모터가 부드럽게 따라오도록 아주 약간의 딜레이만 줍니다.
}

🎉 축하합니다! 아두이노의 핵심을 모두 마스터하셨습니다!

입출력, 아날로그, 센서, 모터까지! 이제 이 조각들을 퍼즐처럼 조립하기만 하면 상상하는 거의 모든 것을 만들 수 있습니다. 다음 장부터는 배운 것들을 융합하여 만드는 '실전 미니 프로젝트'가 시작됩니다!