4주차_참고 : PWM - dhryu60/SmartDevice_2025-1 GitHub Wiki
ESP32 PWM 강의 자료
PWM(펄스 폭 변조)은 디지털 신호를 사용하여 아날로그 출력처럼 보이도록 하는 기법입니다. ESP32는 최대 16채널의 PWM 출력을 지원하며, 주로 LED 밝기 조절, 모터 속도 제어, 오디오 신호 생성 등에 활용됩니다.
- LEDC(Low-Energy Digital Controller) 모듈 사용
- 최대 16채널 지원 (독립적인 16개의 PWM 출력 가능)
- 분해능 조정 가능 (1~16비트) (기본 8비트 사용, 256단계 조절 가능)
- 주파수 범위: 1Hz ~ 40MHz
- 가변 듀티 사이클 (0~100%)
- 모든 GPIO 핀에서 PWM 출력 가능 (단, GPIO34~39는 입력 전용)
PWM 신호는 일정한 주기로 ON/OFF를 반복하는 디지털 신호이며, "듀티 사이클(Duty Cycle)"에 따라 평균 출력 전압이 결정됩니다.
- 주기(Period): 한 사이클의 총 시간
- 주파수(Frequency): 초당 반복 횟수
-
듀티 사이클(Duty Cycle, %): ON 상태 비율
- 0%: 항상 OFF (출력 0V)
- 50%: ON/OFF 동일 (출력 평균값 50%)
- 100%: 항상 ON (출력 최대)
ESP32의 PWM 기능은 LEDC(Low-Energy Digital Controller) 모듈을 사용하여 설정됩니다. LEDC 모듈을 통해 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까지의 값을 가집니다.
#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 신호를 조절합니다.
#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()
를 사용해 모터 속도를 점진적으로 증가/감소
- LED 밝기 조절 - LED의 밝기를 부드럽게 변경
- 모터 속도 제어 - 듀티 사이클을 조절하여 DC 모터의 속도를 제어
- 부저 사운드 생성 - 주파수를 변경하여 다양한 음을 생성
- 서보 모터 제어 - PWM을 사용하여 각도를 조절
- ESP32의 GPIO34~GPIO39는 입력 전용 핀이므로 PWM 출력 불가
- PWM 주파수 선택 시, 모터나 LED의 특성에 맞게 조정해야 함
- Wi-Fi 사용 시 ADC2 핀과 PWM 간 충돌 가능성이 있음
ESP32의 PWM 기능은 LED 제어, 모터 제어, 오디오 출력 등 다양한 응용이 가능하며, 최대 16채널을 독립적으로 제어할 수 있어 다채널 PWM이 필요한 프로젝트에서 매우 유용합니다. 듀티 사이클과 주파수를 적절히 설정하여 원하는 결과를 얻을 수 있도록 실습을 진행하는 것이 중요합니다.