단계 5 — 모터·서보 제어와 UDP

차시 3차시 · 선수 학습 단계 4

이번 단계 목표 PWM의 원리를 이해하고, 키보드로 차량을 수동 조종해 본다.

1. 학습 목표

2. 이론

2-1. PWM이란?

PWM(Pulse Width Modulation): 디지털 핀(0V/3.3V)에서 ON/OFF를 빠르게 반복해 평균 전압을 조절하는 기법입니다.

duty 30%:  ▁▁▁▁▁▔▔▔▁▁▁▁▁▔▔▔▁▁▁▁▁▔▔▔   → 평균 1V
duty 50%:  ▁▁▁▁▔▔▔▔▁▁▁▁▔▔▔▔▁▁▁▁▔▔▔▔   → 평균 1.65V
duty 80%:  ▁▔▔▔▔▔▔▔▁▔▔▔▔▔▔▔▁▔▔▔▔▔▔▔   → 평균 2.65V

2-2. DC 모터 양방향 제어 (L298N)

IN1IN2ENA(PWM)동작
HIGHLOWduty 50%전진 (50% 속도)
LOWHIGHduty 50%후진 (50% 속도)
LOWLOW무관정지 (자유 회전)
HIGHHIGH무관브레이크 (강제 정지)

2-3. 서보 각도 매핑

각도펄스폭본 차량 의미
0.5ms(사용 안 함)
45°약 1.0ms좌측 최대
90°1.5ms직진 (중립)
135°약 2.0ms우측 최대
180°2.5ms(사용 안 함)

2-4. 명령 패킷 형식

본 차량의 명령은 JSON으로 보냅니다:

{"speed": 100, "steering": 90}
필드범위의미
speed-255 ~ 255양수: 전진, 음수: 후진, 0: 정지
steering45 ~ 13545=좌최대, 90=중립, 135=우최대

3. 키보드 입력 받기 (OpenCV waitKey)

본 프로젝트에서는 OpenCV의 cv2.waitKey()를 키보드 입력 수신에 사용합니다.

import cv2
import numpy as np

# 검은 화면 만들기 (waitKey가 작동하려면 창이 필요)
canvas = np.zeros((300, 400, 3), dtype=np.uint8)

while True:
    cv2.imshow('Control', canvas)
    key = cv2.waitKey(50) & 0xFF  # 50ms 대기

    if key == ord('q'):
        break
    elif key == ord('w'):
        print("앞으로!")
    elif key == ord('s'):
        print("뒤로!")
    elif key == ord(' '):
        print("정지!")

cv2.destroyAllWindows()

ord('q')는 문자 'q'의 아스키 코드(113)를 반환합니다.

4. 활동

활동 4-A: PWM duty 실험 ⭐ Easy

학생용 프로그램 단계5_모터수동조종.py를 실행하고:

  1. 처음에는 차체를 책 위에 올려 바퀴를 공중에 띄운 상태에서 테스트
  2. 1 ~ 9 키를 눌러 모터 속도를 변경
  3. 속도와 회전 빠르기의 관계를 관찰

관찰 기록

speed 값바퀴 회전 느낌
125
5125
9225

활동 4-B: 키보드 수동 조종 ⭐⭐ Standard

학생용 프로그램의 빈칸을 모두 채워 다음을 완성:

미션 — 안전한 공간에서 차량을 직접 운전하며 다음 코스를 통과:

활동 4-C: 미니 레이스 ⭐⭐⭐ Challenge

팀별로 다음 코스의 통과 시간을 측정하시오.

출발 ─→ 직선 2m ─→ 좌커브(반경 50cm) ─→ 직선 1m ─→ 골인

규칙

5. ESP32 펌웨어 (참고)

학생은 ESP32 코드를 직접 짜지 않습니다. 이미 작성된 esp32_cam.ino가 다음 동작을 수행합니다:

// 의사코드로 표현
void onUDPReceive(json data) {
    int speed    = data["speed"];
    int steering = data["steering"];

    // DC 모터 제어
    if (speed > 0) {
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
    } else if (speed < 0) {
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        speed = -speed;
    } else {
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
    }
    analogWrite(ENA, speed);   // PWM duty

    // 서보 제어
    servo.write(steering);
}
💡 코드를 읽고 이해할 수 있다면 단계 8~9에서 확장 기능을 직접 추가해 볼 수 있습니다.

6. 핵심 개념 정리

개념설명
PWMON/OFF 비율로 평균 전압을 조절하는 기법
dutyPWM에서 ON이 차지하는 비율 (0~100% 또는 0~255)
H-bridge모터 양방향 회전을 위한 회로 (L298N 내장)
JSON키-값 쌍으로 데이터를 표현하는 형식
socketUDP/TCP 통신 끝점

7. 자기평가

항목12345
PWM의 원리를 설명할 수 있다
속도·조향각 명령을 송신할 수 있다
차량을 키보드로 안전하게 조종할 수 있다
안전 수칙(공중 띄움)을 지켰다