|
|
브레드보드 IO 2편, 아두이노 RC 서보모터.. : 네이버블로그
브레드보드 활용 IO 인터페이스 2편
아두이노, RC 서보모터 제어 + OLED 실시간 표시 & RC카 조향 테스트
민선생의 전자공방
blog.naver.com/hansikmin
아두이노 Uno + OLED(I2C) + SG90 서보모터 브레드보드 배선(서보모터는 외부 전원 사용), [도면작성 툴: Wokwi]
1장. RC 서보모터의 원리와 PWM 제어
1.1 서보모터란?
대부분의 전자기기 중 출력으로 사용되는 장치 중 하나가 바로 모터입니다. 일반 직류 모터는 회전은 쉽지만 '45도만 회전하고 멈추기'는 매우 어렵습니다. 스텝핑 모터는 특정 각도 회전이 가능하지만 정지 시 외력에 버티는 힘이 없습니다.
서보모터는 원하는 위치만큼 정확히 회전하고, 그 위치에서 외력이 가해져도 버티면서 유지합니다. 서보모터 내부에는 마이크로컨트롤러, 감속 기어, 회전각을 감지하는 가변저항(포텐시오미터)이 내장되어 있습니다.
실제 산업현장의 고가 로봇은 서보모터로 움직이게 됩니다. 공장에서 사용하는 서보모터에는 직류 서보모터와 교류 서보모터가 있습니다. 직류 서보라면 로터리 엔코더가 부착된 직류 모터를 서보드라이버라는 제어기로 컨트롤 해 속도와 위치를 원하는 대로 제어해주는 장치이며, 교류 서보 역시 3상 유도형 모터를 사용하는 것만 다르지 속도와 위치를 제어해주는 모터와 컨트롤러를 합쳐 직류 또는 교류 서보라 합니다. 하지만 이와 같은 서보는 모터와 속도와 위치를 감지하는 로터리 엔코더, 서보드라이버의 가격이 매우 고가입니다.
보통 무선 자동차, 무선조종 비행기 등의 액추에이터로 사용되는 RC(Remote Control) 서보 모터는 10,000원 정도면 구입할 수 있고 제어기에서 일정한 간격의 펄스를 가해주면 이에 상응하는 위치로 회전하며, 산업용 서보모터와 같이 360도 회전하는 것이 아니고 180도 범위 내에서 좌우로만 회전할 수 있습니다. 10,000원 정도에 구매하는 RC 서보모터의 경우 정지 토크가 3Kg 정도이어서 간단하고 거창한 동작에 사용방법이 매우 간단하여 소형 응용 제품에 많이 사용되고 있습니다.
RC 서보 모터에는 펄스간격을 측정해 각도지령을 해석하고 내장한 직류 모터를 회전시켜 원하는 각도로 제어하기 위해 소형 마이크로컨트롤러를 내장하고 있으며 가격을 저렴하게 구성하기 위해 회전각도 검출은 비싼 로터리엔코더 대신에 가변저항(포텐시오미터)으로 회전 각도를 입력받아 위치제어를 합니다. 아두이노가 일정한 주기로 위치 지령을 펄스폭으로 주면 RC 서보 모터가 이를 해석해 원하는 각도로 회전시키고 그 각도를 유지하게 되는 것입니다.
보통 1ms의 폭을 입력하면 0도로 회전하고, 1.5ms의 폭을 서보 모터에 주면 90도, 2ms의 폭을 주면 180도로 회전합니다. RC 서보 모터는 다음과 같은 동작 특성을 가지고 있으며 인터넷으로 검색해 보면 정말 다양한 크기와 가격의 RC 서보 모터가 판매되고 있음을 확인할 수 있을 것입니다.
AI 활용
하이텍 RC 서보모터
AI 활용
서보모터 분해도
1.2 RC 서보모터의 특징
RC(Remote Control) 서보모터는 무선 자동차, 무선조종 비행기 등의 액추에이터로 사용되며 1만 원 정도에 구입할 수 있는 저렴한 위치제어 모터입니다. 산업용 서보모터와 달리 360도 연속 회전이 아닌 0°~180° 범위 내에서만 동작합니다.
| 항목 | 내용 |
| 모델 | SG90 (9g 미니 서보) |
| 동작 전압 | 4.8V ~ 6.0V |
| 속도 | 0.12sec / 60° (4.8V) |
| 정지 토크 | 1.8 Kg·cm (4.8V) |
| 회전 범위 | 0° ~ 180° |
| 제어 신호 | 20ms 주기 PWM 펄스폭으로 각도 지령 |
| 커넥터 | 갈색=GND / 빨강=VCC / 주황=신호 |
1.3 PWM 펄스폭과 회전각의 관계
RC 서보모터는 약 20ms(50Hz) 주기로 반복되는 PWM 펄스의 폭(펄스 ON 시간)으로 회전 각도를 제어합니다. 아두이노 Servo.h 라이브러리는 이 펄스 생성을 자동으로 처리합니다.
아두이노의 RC서보모터 제어명ㄹ
| 펄스폭 | writeMicroseconds() | write() | 회전각 |
| 1.0 ms (1000μs) | writeMicroseconds(1000) | write(0) | 0° (왼쪽 끝) |
| 1.5 ms (1500μs) | writeMicroseconds(1500) | write(90) | 90° (중앙) |
| 2.0 ms (2000μs) | writeMicroseconds(2000) | write(180) | 180° (오른쪽 끝) |
| 💡 write() vs writeMicroseconds() servo.write(각도) -> 0~180도의 정수갑으로 간단하게 제어(권장) servo.writeMicroseconds(us) -> 1000~2000us로 더 세밀한 제어 가능 이 콘텐츠에서는 두값 모두 OLED에 실시간으로 표시합니다. |
1.4 Servo.h 주요 함수
| 함수 | 설명 |
| Servo servo1; | 서보 객체 선언. 여러 개 사용 시 servo2, servo3 추가 |
| servo1.attach(pin) | 서보 신호핀 지정. PWM 지원 핀 권장 (D3·D5·D6·D9·D10·D11) |
| servo1.write(angle) | 0~180° 각도로 회전 명령. 내부에서 펄스폭 자동 변환 |
| servo1.writeMicroseconds(us) | 펄스폭(μs)으로 직접 제어. 1000~2000 범위 |
| servo1.read() | 마지막 write() 값 반환 |
| servo1.detach() | 서보 제어 해제. 핀을 일반 디지털 핀으로 복귀 |
| ⚠️ 서보모터 전원 주의사항 SG90은 동작시 순간 전류 최대 500mA~1A가 흐릅니다. 아두이노 5V 핀 공급한계(약 500mA)에 근접하므로 여러 개 사용 시 반드시 외부 5V 전원을 별도 공급하고, GND만 공통으로 연결해야 합니다. 서보모터를 D0(RX)핀에 연결하면 스케치 업로드시 충돌이 발행하므로 절대 사용하지 마세요. 이 콘텐츠에서는 D9를 사용합니다. |
2장. 회로 배선
2.1 준비물
• Arduino Uno R3
• SSD1306 OLED 모듈 (0.96인치, I2C, 4핀) — 1편 배선 그대로
• SG90 미니 서보모터
• 브레드보드
• 점퍼 와이어 (빨강, 검정, 주황/노랑)
2.2 핀 연결표
| 부품 | 부품 핀 | 아두이노 핀 | 비고 |
| OLED | VCC | 5V | 1편 배선 그대로 |
| OLED | GND | GND | 1편 배선 그대로 |
| OLED | SDA | A4 | 1편 배선 그대로 |
| OLED | SCL | A5 | 1편 배선 그대로 |
| SG90 서보 | 빨강 (VCC) | 5V | 외부 전원 |
| SG90 서보 | 갈색 (GND) | GND | 접지 |
| SG90 서보 | 주황 (신호) | D9 | PWM 출력 |
2.3 회로 구성도
회로 배선. 주의 [반드시 모터에 외부 전원 연결해 주세요.]
아두이노 Uno + OLED(I2C) + SG90 서보모터 브레드보드 배선(서보모터는 외부 전원 사용), [도면작성 툴: Wokwi]
3장. 메인 예제 소스코드
3.1 동작 설명
이 프로그램은 두 가지 동작 모드를 4회씩 반복하며 무한 루프합니다.
| 모드 | 동작 | OLED 표시 |
| 모드 1 | 45°→90°→135°→90°→45° 3초마다 스텝 이동 × 2회 | 현재 각도 + PWM값(μs) |
| 모드 2 | 45°↔135° 좌우 스윕 × 32회 (부드럽게) | 현재 각도 + PWM값(μs) |
아두이노, OLED, SG90 서보모터 예제 실행 영상
OLDE 출력
3.2 소스코드(코드는 주석을 붙여 놨고 순서대로 동작하는 코드이니 꼭 한번 머리속으로 동작 시뮬레이션을 해보시기 바랍니다.)
// ================================================ // 민선생의 전자공방 - 브레드보드 IO 인터페이스 2편 // RC 서보모터 제어 + OLED 실시간 표시 (수정판) // 500us=0도, 2500us=180도 기준 // 파일명: servo_oled_control.ino // ================================================ #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Servo.h> #define SCREEN_W 128 #define SCREEN_H 64 #define OLED_ADDR 0x3C #define OLED_RESET -1 #define SERVO_PIN 9 // ── 캘리브레이션 확정값 ───────────────────────── #define PWM_0DEG 500 // 0도 = 500μs ** 모터마다 설정값이 다릅니다. 모터마다 테스트가 필요 #define PWM_180DEG 2500 // 180도 = 2500μs ** 모터마다 값이 다를수 있습니다. // ── 동작 각도 정의 ────────────────────────────── #define ANGLE_MIN 45 // 왼쪽 한계 #define ANGLE_MID 90 // 중앙 #define ANGLE_MAX 135 // 오른쪽 한계 // ── 타이밍 설정 ───────────────────────────────── #define STEP_DELAY 3000 // 스텝 모드 대기 (3초) #define SWEEP_DELAY 15 // 스윕 속도 (15ms/도) #define REPEAT_STEP 2 // 모드1 반복 횟수 #define REPEAT_SWEEP 2 // 모드2 왕복 횟수 Adafruit_SSD1306 display(SCREEN_W, SCREEN_H, &Wire, OLED_RESET); Servo servo1; // ── 각도 → PWM(μs) 변환 ───────────────────────── // 500us=0도, 2500us=180도 선형 변환 int angleToPWM(int angle) { return map(angle, 0, 180, PWM_0DEG, PWM_180DEG); } // ── OLED 표시 함수 ────────────────────────────── void showOLED(int angle, int pwm, String mode) { display.clearDisplay(); // 타이틀 display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.print("SERVO CTRL"); display.drawLine(0, 10, 127, 10, SSD1306_WHITE); // 모드 display.setCursor(0, 14); display.print("Mode: "); display.print(mode); // 각도 (큰 글자) display.setTextSize(2); display.setCursor(0, 26); display.print(angle); display.print(" deg"); // PWM값 display.setTextSize(1); display.setCursor(0, 50); display.print("PWM: "); display.print(pwm); display.print(" us"); // 게이지 바 (45~135도 범위) display.drawRect(0, 58, 128, 6, SSD1306_WHITE); int barW = map(angle, ANGLE_MIN, ANGLE_MAX, 0, 126); barW = constrain(barW, 0, 126); display.fillRect(1, 59, barW, 4, SSD1306_WHITE); display.display(); } // ── 서보 이동 + OLED 업데이트 ─────────────────── void moveServo(int angle, String mode) { int pwm = angleToPWM(angle); servo1.writeMicroseconds(pwm); // write() 대신 μs 직접 제어 showOLED(angle, pwm, mode); } void setup() { if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) { while (1); } display.clearDisplay(); servo1.attach(SERVO_PIN); moveServo(ANGLE_MID, "INIT"); // 시작 시 90도(중앙) delay(1000); } void loop() { // ══════════════════════════════════════════════ // 모드 1: 스텝 이동 45→90→135→90→45 ×4회 // ══════════════════════════════════════════════ for (int r = 0; r < REPEAT_STEP; r++) { moveServo(45, "STEP"); delay(STEP_DELAY); moveServo(90, "STEP"); delay(STEP_DELAY); moveServo(135, "STEP"); delay(STEP_DELAY); moveServo(90, "STEP"); delay(STEP_DELAY); moveServo(45, "STEP"); delay(STEP_DELAY); } // ══════════════════════════════════════════════ // 모드 2: 스윕 45↔135 ×3회 왕복 // ══════════════════════════════════════════════ for (int r = 0; r < REPEAT_SWEEP; r++) { // 45 → 135 정방향 for (int a = ANGLE_MIN; a <= ANGLE_MAX; a++) { moveServo(a, "SWEEP"); delay(SWEEP_DELAY); } // 135 → 45 역방향 for (int a = ANGLE_MAX; a >= ANGLE_MIN; a--) { moveServo(a, "SWEEP"); delay(SWEEP_DELAY); } } }
4장. OLED 화면 구성 설명
4.1 화면 레이아웃
128×64 픽셀 OLED에 5가지 정보를 한 화면에 표시합니다.
| Y 위치 | 크기 | 표시 내용 |
| y=0 | TextSize(1) | SERVO CTRL 타이틀 |
| y=10 | ───── | 가로 구분선 |
| y=14 | TextSize(1) | 현재 모드 (STEP / SWEEP) |
| y=26 | TextSize(2) | 현재 각도 (예: 90 deg) — 큰 글자 |
| y=50 | TextSize(1) | PWM값 (예: PWM: 1472 us) |
| y=58 | 게이지 바 | 45~135° 범위 진행 바 |
📌 angleToPWM() 함수 해설
SG90의 실제 PWM 범위는 544μs(0°) ~ 2400μs(180°)입니다.
map(angle, 0, 180, 544, 2400) 으로 선형 변환합니다.
예) 45° → map(45, 0, 180, 500, 2500) = 1000μs
90° → map(90, 0, 180, 500, 2500) = 1500μs
135° → map(135, 0, 180, 500, 2500) = 2000μs
5장. 같은 코드로 RC카 조향·구동 제어
5.1 RC카에 적용하는 원리
이 예제에서 서보모터를 제어하는 PWM 신호는 RC카의 조향 서보 및 모터 드라이버(ESC)에도 그대로 적용됩니다. RC카용 서보와 ESC 모두 동일한 20ms 주기 PWM 프로토콜을 사용하기 때문입니다.
| 연결 대상 | 신호 핀 | 동작 변화 |
| SG90 브레드보드 | D9 → 서보 신호 | 이 예제 기본 동작 |
| RC카 조향 서보 | D9 → 조향 서보 신호 | 좌/우 조향 동작 |
| RC카 ESC (모터드라이버) | D9 → ESC 신호 | 전진/후진/속도 제어 |
5.2 연결 방법
• RC카 조향 서보 또는 ESC의 신호선(주로 흰색 또는 주황색)을 아두이노 D9에 연결
• RC카 배터리 GND와 아두이노 GND를 공통 연결
• RC카 전원은 반드시 별도 전원(구동 전압은 서보마다 다르며, 본 영상은 15V 외부전원사용)을 사용하여야 함. (** 절대로 아두이노 5V를 사용하면 안됨)
아두이노 Uno + OLED(I2C) + SG90 서보모터 브레드보드 배선(서보모터는 외부 전원 사용)
접기/펴기
PWM으로 실제 RC서보모터 조향장치 구동 영상
⚠️ RC카 적용 시 주의사항
ESC(전자변속기)는 처음 켤 때 '캘리브레이션' 과정이 필요한 경우가 있습니다.
모터 드라이버에 따라 90°=중립(정지), 45°=후진, 135°=전진으로 동작합니다.
**** 반드시 RC카 전원(배터리)과 아두이노 전원은 분리하고, GND만 공통으로 연결하세요. ****
다음 과제 예고
다음 3편에서는 HC-SR04 초음파 센서로 거리를 측정하고 OLED에 실시간으로 표시하는 프로젝트를 진행합니다.
• 초음파 센서 거리 측정 원리 (TOF 방식)
• pulseIn() 함수 활용
• OLED 거리 바 그래프 실시간 표시
• 일정 거리 이하 접근 시 경보 기능
