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 상태의 비율
    1. 0%: 항상 꺼짐 (출력 0%)
    2. 50%: ON/OFF 동일 (출력 평균값 50%)
    3. 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