4주차 ‐ ESP32 GPIO 입출력 실습 2 (PWM, ADC) - boguuu/SmartDevice_2025-1 GitHub Wiki
🖥️PWM(Pulse Width Modulation)
PWM(펄스 폭 변조)은 디지털 신호를 사용하여 아날로그 출력처럼 보이도록 하는 기법 ESP32는 최대 16채널의 PWM 출력을 지원하며, 주로 LED 밝기 조절, 모터 속도 제어, 오디오 신호 생성 등에 활용
ESP32의 PWM 특징
- LEDC(Low-Energy Digital Controller) 모듈 사용
- 최대 16채널 지원 (독립적인 16개의 PWM 출력 가능)
- 분해능 조정 가능 (1~16비트) (기본 8비트 사용, 256단계 조절 가능)
- 주파수 범위: 1Hz ~ 40MHz
- 가변 듀티 사이클 (0~100%)
- 모든 GPIO 핀에서 PWM 출력 가능 (단, GPIO34~39는 입력 전용)
PWM 신호 개념
PWM 신호는 일정한 주기로 ON/OFF를 반복하는 디지털 신호이며, "듀티 사이클(Duty Cycle)"에 따라 평균 출력 전압이 결정
- 주기(Period): 한 사이클의 총 시간
- 주파수(Frequency): 초당 반복 횟수
- 듀티 사이클(Duty Cycle, %): ON 상태 비율
- 0%: 항상 OFF (출력 0V)
- 50%: ON/OFF 동일 (출력 평균값 50%)
- 100%: 항상 ON (출력 최대)
ESP32에서 PWM 설정
ESP32의 PWM 기능은 LEDC(Low-Energy Digital Controller) 모듈을 사용하여 설정
PWM 설정 파라미터
- 채널 번호: 0~15 (총 16개 PWM 채널)
- 주파수: 1Hz ~ 40MHz
- 분해능 (Resolution): 1~16비트 (기본 8비트 = 256단계)
- 듀티 사이클: 0~100%
- 출력 핀 (GPIO): 출력할 GPIO 지정
- 타이머 설정: LEDC 타이머를 사용하여 주파수 및 분해능 설정
PWM 활용 사례
- LED 밝기 조절 - LED의 밝기를 부드럽게 변경
- 모터 속도 제어 - 듀티 사이클을 조절하여 DC 모터의 속도를 제어
- 부저 사운드 생성 - 주파수를 변경하여 다양한 음을 생성
- 서보 모터 제어 - PWM을 사용하여 각도를 조절
실습 아날로그 출력 (PWM)
PWM 출력을 이용하여 LED 밝기를 조절
📌 회로 연결 방법
- LED 모듈
- S: D4
- VCC: 3.3V
- GND: GND
디지털 출력 코드
const int ledPin = 4; // LED가 연결된 핀 번호 설정
int brightness = 0; // LED 밝기 변수 초기화
void setup() {
ledcSetup(0, 5000, 8); // 채널 0을 주파수 5000Hz, 8비트 해상도로 PWM 설정
ledcAttachPin(ledPin, 0); // ledPin(4번 핀)을 채널 0에 연결
}
void loop() {
// LED 밝기를 점점 증가 (0 → 255)
for (brightness = 0; brightness <= 255; brightness++) {
ledcWrite(0, brightness); // 채널 0에 brightness 값 적용 (PWM)
delay(10); // 10ms 대기 (부드러운 밝기 변화)
}
// LED 밝기를 점점 감소 (255 → 0)
for (brightness = 255; brightness >= 0; brightness--) {
ledcWrite(0, brightness); // 채널 0에 brightness 값 적용 (PWM)
delay(10); // 10ms 대기
}
}
결과
https://github.com/user-attachments/assets/64a3e063-b19a-460c-acd7-b8f5a333c169
ADC(Analog-to-Digital Converter)
ADC(아날로그-디지털 변환기)는 아날로그 신호(전압)를 디지털 값으로 변환하는 장치 ESP32는 최대 18개의 ADC 입력 채널을 제공하며, 센서 데이터 측정, 신호 처리, 전압 감지 등에 활용
💡연속적인 analog 신호를 0과 1로 discrete하게 구성된 digital 신호로 변환하는 칩(I/C)
ESP32의 ADC 특징
- ADC1: 8개 채널 (GPIO32-GPIO39)
- ADC2: 10개 채널 (GPIO0, 2, 4, 12-15, 25-27)
- 분해능(Resolution): 기본 12비트 (0~4095 값 출력, 설정 가능)
- 입력 전압 범위: 기본 0~3.3V (조정 가능)
- ADC2는 Wi-Fi와 동시에 사용할 경우 제한됨
- 노이즈 영향이 크므로 평균값 필터링 필요
ADC 활용 사례
- 온도 센서 (LM35 등) 측정
- 조도 센서 (LDR)로 빛 감지
- 전위차계(가변 저항) 값 읽기
- 배터리 전압 모니터링
- 아날로그 마이크 신호 분석
주의사항 및 최적화 팁
- ADC2는 Wi-Fi 사용 시 충돌 가능 (ADC1 사용 권장)
- 입력 전압 범위가 3.3V를 초과하면 ESP32 손상 가능
- ADC는 노이즈 영향을 받으므로 필터링 기법 사용
- ESP32 내부 ADC는 고정밀 측정이 필요할 경우 캘리브레이션이 필요함
실습 아날로그 입력 (가변 저항)
가변 저항 값을 읽어 LED 밝기를 조절
📌 회로 연결 방법
- LED 모듈
- S: D4
- VCC: 3.3V
- GND: GND
- 가변 저항 모듈
- S: D34
- VCC: 3.3V
- GND: GND
코드 작성
const int potPin = 34; // 가변 저항(Potentiometer)이 연결된 아날로그 핀
const int ledPin = 4; // LED가 연결된 핀 번호
int potValue = 0; // 가변 저항의 값을 저장할 변수
void setup() {
ledcSetup(0, 5000, 8); // 채널 0을 주파수 5000Hz, 8비트 해상도로 PWM 설정
ledcAttachPin(ledPin, 0); // ledPin(4번 핀)을 채널 0에 연결
}
void loop() {
potValue = analogRead(potPin); // 가변 저항에서 아날로그 값을 읽음 (0~4095)
int brightness = map(potValue, 0, 4095, 0, 255); // 0~4095 범위를 0~255로 매핑
ledcWrite(0, brightness); // LED 밝기 조절 (PWM)
delay(10); // 10ms 대기
}
결과
https://github.com/user-attachments/assets/51025420-15c7-4086-93c1-877ec6ad718c