04주차 ‐ 아날로그 장치와 기법을 이용한 실습 - gitjs523/SmartDevice2025 GitHub Wiki
1. PWM
(1) PWM이란?
- PWM(Pulse Width Modulation)
- 펄스 폭 변조라는 의미
- 디지털 신호를 일정한 비율로 조절하여 아날로그 출력처럼 동작시키는 기법
- ESP32는 16채널의 PWM 출력 지원, 주로 LED 밝기 조절, 모터 속도 제어, 오디오 신호 생성 등에 사용
(2) PWM의 특징
- LEDC(Low Energy Digital Controller) 모듈 사용
- 최대 16채널 지원
- 분해능 조정 가능 (1 ~ 16 비트 가능, 기본 8비트 사용, 256 단계 조절 가능)
- 주파수 범위: 1Hz ~ 40MHz
- 모든 GPIO 핀에서 PWM 출력 가능 (GPIO 34 ~ 29 핀은 입력 전용)
- PWM 신호는 일정한 주기로 ON/OFF를 반복하는 디지털 신호, 듀티 사이클에 따라 평균 출력 전압이 결정됨
- 듀티 사이클(Duty Cycle): ON 상태의 비율
- 0%: 항상 꺼짐 (출력 0%)
- 50%: ON/OFF 동일 (출력 평균값 50%)
- 100%: 항상 켜짐 (출력 최대)
2. ADC
(2) ADC란?
- ADC(Analog-to-Digital Converter): 아날로그-디지털 변환기
- 아날로그 신호(전압)을 디지털 값으로 변환하는 장치
- ESP32는 최대 18개의 ADC 입력 채널 제공
- 센서 데이터 측정, 신호 처리, 전압 감지 등 사용
(3) ADC의 특징
- ADC1: 8개 채널 (GPIO 32-GPIO 39 핀)
- ADC2: 10개 채널 (GPIO 0, 2, 4, 12, 13, 14, 15, 25, 26, 27 핀)
- 분해능: 기본 12비트(0~4095 값 출력, 설정 가능)
- 입력 전압 범위: 기본 0 ~ 3.3V (조정 가능)
- 노이즈 영향이 크므로(아날로그의 특징) 평균값 필터링 필요
- ADC1 채널은 Wi-Fi 동작과 무관하게 사용 가능
- ADC2 채널은 Wi-Fi 사용 시 충돌 발생 가능
- GPIO 34 ~ 39는 입력 전용
3. DAC
(1) DAC란?
- DAC(Digital-to-Analog Converter): 디지털-아날로그 변환기. 디지털 데이터를 아날로그 신호로 변환하는 장치
- ESP32는 2개의 8비트 DAC 채널을 제공
- 오디오 출력, 아날로그 신호 생성, 센서 캘리브레이션 등에 사용
(2) DAC의 특징
- 내장 DAC 채널: 2개 (DAC1, DAC2)
- DAC1: GPIO 25
- DAC2: GPIO 26
- 분해능: 8비트 (0 ~ 255 값 출력, 0V ~ 3.3V 범위)
- 출력 전압 범위: 0 ~ 3.3V (VDD에 따라 달라짐)
- 단순한 아날로그 신호 생성 가능 (파형 생성, 전압 제어)
- PWM 방식보다 부드러운 출력
- 부드러운 아날로그 출력이 필요한 경우(오디오, 정밀 전압 조절 등) DAC 사용
- 스위칭 방식이 효율적인 경우(모터, LED 제어 등) PWM 사용
4. 아날로그 실습
(1) 아날로그 출력(PWM) 실습
- PWM 출력을 이용하여 LED 밝기를 조절하기 회로 연결
- LED 모듈
- S: D4
- VCC: 3.3V
- GND: GND
기존에 쓰던 코드
const int ledPin = 4;
int brightness = 0;
void setup() {
ledcSetup(0, 5000, 8);
ledcAttachPin(ledPin, 0);
}
void loop() {
for (brightness = 0; brightness <= 255; brightness++) {
ledcWrite(0, brightness);
delay(10);
}
for (brightness = 255; brightness >= 0; brightness--) {
ledcWrite(0, brightness);
delay(10);
}
}
- 위 코드에 있는 ledcSetup 함수와 ledcAttachPin 함수가 ledcAttach 함수로 변경되었으므로 코드 내용을 수정해야 한다.
- 추가로 "ledcWrite(0, brightness)"를 "ledcWrite(ledPin, brightness)"로도 변경한다.
새로운 코드
const int ledPin = 4;
int brightness = 0;
void setup() {
ledcAttach(ledPin, 5000, 8);
}
void loop() {
for (brightness = 0; brightness <= 255; brightness++) {
ledcWrite(ledPin, brightness);
delay(10);
}
for (brightness = 255; brightness >= 0; brightness--) {
ledcWrite(ledPin, brightness);
delay(10);
}
}
https://github.com/user-attachments/assets/ccd64a95-cd93-453c-aa4a-69c90839de5a
(2) 아날로그 입력(가변 저항) 실습
- 가변 저항 값을 읽어 LED 밝기를 조절하기 회로 연결
- LED 모듈
- S: D4
- VCC: 3.3V
- GND: GND
- 가변 저항 모듈
- S: D34
- VCC: 3.3V
- GND: GND
기존에 있던 코드
const int potPin = 34;
const int ledPin = 4;
int potValue = 0;
void setup() {
ledcSetup(0, 5000, 8);
ledcAttachPin(ledPin, 0);
}
void loop() {
potValue = analogRead(potPin);
int brightness = map(potValue, 0, 4095, 0, 255);
ledcWrite(0, brightness);
delay(10);
}
- 이도 마찬가지로 새롭게 병합된 함수를 이용해 코드를 수정한다.
새로운 코드
const int potPin = 34;
const int ledPin = 4;
int potValue = 0;
void setup() {
ledcAttach(ledPin, 5000, 8);
}
void loop() {
potValue = analogRead(potPin);
int brightness = map(potValue, 0, 4095, 0, 255);
ledcWrite(ledPin, brightness);
delay(10);
}
https://github.com/user-attachments/assets/5bbd6702-d4fd-4ff2-8cea-10223c2b19c1