4주차_참고 : PWM - dhryu60/SmartDevice_2025-1 GitHub Wiki

ESP32 PWM 강의 자료

1. PWM(Pulse Width Modulation) 개요

PWM(펄스 폭 변조)은 디지털 신호를 사용하여 아날로그 출력처럼 보이도록 하는 기법입니다. ESP32는 최대 16채널의 PWM 출력을 지원하며, 주로 LED 밝기 조절, 모터 속도 제어, 오디오 신호 생성 등에 활용됩니다.

https://youtu.be/b46f4I8ttN4

2. ESP32의 PWM 특징

  • LEDC(Low-Energy Digital Controller) 모듈 사용
  • 최대 16채널 지원 (독립적인 16개의 PWM 출력 가능)
  • 분해능 조정 가능 (1~16비트) (기본 8비트 사용, 256단계 조절 가능)
  • 주파수 범위: 1Hz ~ 40MHz
  • 가변 듀티 사이클 (0~100%)
  • 모든 GPIO 핀에서 PWM 출력 가능 (단, GPIO34~39는 입력 전용)

3. PWM 신호 개념

PWM 신호는 일정한 주기로 ON/OFF를 반복하는 디지털 신호이며, "듀티 사이클(Duty Cycle)"에 따라 평균 출력 전압이 결정됩니다.

  • 주기(Period): 한 사이클의 총 시간
  • 주파수(Frequency): 초당 반복 횟수
  • 듀티 사이클(Duty Cycle, %): ON 상태 비율
    • 0%: 항상 OFF (출력 0V)
    • 50%: ON/OFF 동일 (출력 평균값 50%)
    • 100%: 항상 ON (출력 최대)
      esp32-pwm-01 esp32-pwm-02 esp32-pwm-03

4. ESP32에서 PWM 설정 방법

ESP32의 PWM 기능은 LEDC(Low-Energy Digital Controller) 모듈을 사용하여 설정됩니다. LEDC 모듈을 통해 PWM 신호를 생성하기 위해 다음과 같은 파라미터를 설정해야 합니다.

1) PWM 설정 파라미터

  • 채널 번호: 0~15 (총 16개 PWM 채널)
  • 주파수: 1Hz ~ 40MHz
  • 분해능 (Resolution): 1~16비트 (기본 8비트 = 256단계)
  • 듀티 사이클: 0~100%
  • 출력 핀 (GPIO): 출력할 GPIO 지정
  • 타이머 설정: LEDC 타이머를 사용하여 주파수 및 분해능 설정

  • 채널: PWM 신호를 출력할 채널 번호입니다. ESP32는 최대 16개의 채널을 지원하며, 각 채널은 독립적으로 설정할 수 있습니다.

  • 주파수: PWM 신호의 주파수를 설정합니다. 주파수는 1Hz부터 최대 40MHz까지 설정할 수 있으며, 이는 LED의 깜박임 속도나 모터의 회전 속도 등에 영향을 줍니다.

  • 분해능: PWM 신호의 분해능(비트 수)을 설정합니다. 분해능이 높을수록 PWM 신호의 정밀도가 높아집니다. 예를 들어, 8비트 분해능은 0부터 255까지의 값을 가지며, 10비트 분해능은 0부터 1023까지의 값을 가집니다.

2) PWM 설정 코드 예제

기본 PWM 설정 및 사용 (LED 밝기 조절)

#include <Arduino.h>

#define LED_PIN 23 // PWM 신호 출력할 핀
#define PWM_CHANNEL 0 // PWM 채널 (0~15 사용 가능)
#define PWM_FREQUENCY 5000 // PWM 주파수 (Hz)
#define PWM_RESOLUTION 8 // PWM 분해능 (8비트 = 256단계)

void setup() {
    ledcSetup(PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOLUTION); // PWM 채널 설정
    ledcAttachPin(LED_PIN, PWM_CHANNEL); // GPIO 핀을 PWM 채널에 연결
}

void loop() {
    for (int duty = 0; duty <= 255; duty += 5) {
        ledcWrite(PWM_CHANNEL, duty); // 듀티 사이클 변경
        delay(20);
    }
    for (int duty = 255; duty >= 0; duty -= 5) {
        ledcWrite(PWM_CHANNEL, duty);
        delay(20);
    }
}

설명:

  • ledcSetup(채널, 주파수, 분해능): PWM 채널을 설정합니다.
  • ledcAttachPin(핀번호, 채널): 지정된 GPIO 핀을 PWM 채널과 연결합니다.
  • ledcWrite(채널, 듀티 사이클): 듀티 사이클을 변경하여 PWM 신호를 조절합니다.

모터 속도 제어 (PWM 활용)

#define MOTOR_PIN 18
#define PWM_CHANNEL 1
#define PWM_FREQUENCY 1000
#define PWM_RESOLUTION 10 // 10비트 (0~1023)

void setup() {
    ledcSetup(PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOLUTION);
    ledcAttachPin(MOTOR_PIN, PWM_CHANNEL);
}

void loop() {
    for (int speed = 0; speed <= 1023; speed += 10) {
        ledcWrite(PWM_CHANNEL, speed);
        delay(50);
    }
    for (int speed = 1023; speed >= 0; speed -= 10) {
        ledcWrite(PWM_CHANNEL, speed);
        delay(50);
    }
}

설명:

  • ledcSetup()을 이용해 주파수를 1000Hz, 분해능을 10비트(1024단계)로 설정
  • 듀티 사이클을 변경하여 모터 속도를 조절
  • ledcWrite()를 사용해 모터 속도를 점진적으로 증가/감소

5. PWM 활용 사례

  1. LED 밝기 조절 - LED의 밝기를 부드럽게 변경
  2. 모터 속도 제어 - 듀티 사이클을 조절하여 DC 모터의 속도를 제어
  3. 부저 사운드 생성 - 주파수를 변경하여 다양한 음을 생성
  4. 서보 모터 제어 - PWM을 사용하여 각도를 조절

6. 주의사항

  • ESP32의 GPIO34~GPIO39는 입력 전용 핀이므로 PWM 출력 불가
  • PWM 주파수 선택 시, 모터나 LED의 특성에 맞게 조정해야 함
  • Wi-Fi 사용 시 ADC2 핀과 PWM 간 충돌 가능성이 있음

7. 결론

ESP32의 PWM 기능은 LED 제어, 모터 제어, 오디오 출력 등 다양한 응용이 가능하며, 최대 16채널을 독립적으로 제어할 수 있어 다채널 PWM이 필요한 프로젝트에서 매우 유용합니다. 듀티 사이클과 주파수를 적절히 설정하여 원하는 결과를 얻을 수 있도록 실습을 진행하는 것이 중요합니다.

⚠️ **GitHub.com Fallback** ⚠️