ESP32 IDF

ESP32 IDF PWM

임베디드 친구 2024. 11. 8. 10:04
반응형

안녕하세요, '소프트웨어 공장'입니다. 오늘은 ESP32의 PWM(Pulse Width Modulation)을 활용해 LED의 밝기를 제어하는 방법에 대해 알아보도록 하겠습니다. ESP32는 매우 강력한 마이크로컨트롤러로, PWM 기능을 통해 다양한 애플리케이션에서 제어 작업을 수행할 수 있습니다. 이 글에서는 PWM이 무엇인지, 그리고 어떻게 LED의 밝기를 조절할 수 있는지 설명하고, 예제를 통해 실제로 적용해 보겠습니다.

PWM(Pulse Width Modulation)란?

PWM, 즉 펄스 폭 변조는 디지털 신호를 사용하여 아날로그 형태의 출력값을 제어하는 방법입니다. PWM은 특정 주기의 디지털 신호를 켜고 끄는 과정을 반복함으로써, 출력 전압의 평균값을 조절할 수 있습니다. LED 밝기 제어나 모터 속도 조절 등 다양한 분야에서 많이 사용되며, ESP32 역시 이러한 PWM을 쉽게 구현할 수 있는 하드웨어 타이머 기능을 제공합니다.

PWM의 기본 개념

PWM 신호의 중요한 개념은 다음과 같습니다.

  • 주기(Frequency): PWM 신호가 반복되는 시간입니다. 주기가 빠를수록 깜빡임 없이 제어가 가능합니다.
  • 듀티 사이클(Duty Cycle): PWM 신호가 HIGH 상태로 유지되는 시간의 비율입니다. 듀티 사이클이 100%이면 신호가 계속 HIGH이고, 0%이면 계속 LOW입니다. 듀티 사이클에 따라 LED의 밝기가 달라집니다.

2. 프로젝트 생성

ESP-IDF가 설치되었으면, VS Code에서 새로운 프로젝트를 생성합니다.

  1. Command Palette(Ctrl + Shift + P)에서 ESP-IDF: Show Examples Projects를 선택합니다.
  2. blink 예제를 선택하여 프로젝트를 생성합니다. 이 예제를 바탕으로 PWM을 추가하여 LED 밝기를 제어하는 코드를 작성할 것입니다.

PWM을 이용한 LED 제어 코드 작성

이제 본격적으로 PWM을 이용해 LED의 밝기를 제어하는 코드를 작성해 보겠습니다. GPIO 핀에 LED를 연결하고, PWM 신호를 사용해 LED의 밝기를 조절합니다.

1. 하드웨어 준비물

  • ESP32 개발 보드
  • LED (적색, 녹색 등 상관없음)
  • 저항 (330Ω ~ 1kΩ)
  • 브레드보드 및 점퍼 케이블

LED의 긴 다리는 양극(+)이고, 짧은 다리는 음극(-)입니다. 양극은 ESP32의 PWM 핀에 연결하고, 음극은 저항을 통해 GND에 연결합니다.

2. 코드 작성

다음은 PWM을 이용해 LED의 밝기를 점진적으로 변화시키는 코드입니다.

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include "esp_err.h"

#define LED_PIN 2          // LED가 연결된 핀 번호
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_TIMER   LEDC_TIMER_0
#define LEDC_MODE    LEDC_HIGH_SPEED_MODE
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT  // 듀티 사이클 해상도 (2^13 = 8192 단계)
#define LEDC_FREQUENCY (5000)            // PWM 주파수 5kHz

void app_main(void)
{
    // LEDC 타이머 설정
    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_DUTY_RES,
        .freq_hz = LEDC_FREQUENCY,
        .speed_mode = LEDC_MODE,
        .timer_num = LEDC_TIMER
    };
    ledc_timer_config(&ledc_timer);

    // LEDC 채널 설정
    ledc_channel_config_t ledc_channel = {
        .channel    = LEDC_CHANNEL,
        .duty       = 0,
        .gpio_num   = LED_PIN,
        .speed_mode = LEDC_MODE,
        .hpoint     = 0,
        .timer_sel  = LEDC_TIMER
    };
    ledc_channel_config(&ledc_channel);

    while (1) {
        // LED 밝기 증가
        for (int duty = 0; duty <= 8191; duty += 100) {
            ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty);
            ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }
        // LED 밝기 감소
        for (int duty = 8191; duty >= 0; duty -= 100) {
            ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty);
            ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }
    }
}

3. 코드 설명

  • ledc_timer_config_t 구조체를 사용하여 PWM 타이머를 설정합니다. 여기서 주파수는 5kHz로 설정하고, 듀티 사이클의 해상도는 13비트로 설정하여 0부터 8191까지의 값을 가질 수 있도록 합니다.
  • ledc_channel_config_t 구조체를 사용하여 PWM 채널을 설정합니다. GPIO 2번 핀을 사용하며, 초기 듀티 값은 0으로 설정합니다.
  • 무한 루프에서 듀티 사이클을 증가시키고 감소시켜 LED의 밝기를 점진적으로 변화시킵니다. vTaskDelay 함수를 사용하여 밝기가 천천히 변화하도록 조절합니다.

코드 업로드 및 실행

  1. ESP32 보드를 컴퓨터에 연결하고, VS Code의 터미널에서 아래 명령어를 입력하여 컴파일하고 보드에 업로드합니다.
  2. idf.py build idf.py flash idf.py monitor
  3. 코드가 정상적으로 업로드되면, LED의 밝기가 점차적으로 밝아졌다가 어두워지는 것을 확인할 수 있습니다.

주의사항

  • GPIO 핀 선택: LED를 연결하는 핀은 PWM 신호를 지원하는 핀이어야 합니다. ESP32에는 여러 PWM 핀이 있으니, 사용 가능한 핀을 선택하세요.
  • 저항 사용: LED에 전류가 너무 많이 흐르면 손상될 수 있으므로, 적절한 저항(330Ω ~ 1kΩ)을 사용하여 전류를 제한하세요.

마무리

이번 글에서는 ESP32의 PWM 기능을 이용해 LED의 밝기를 제어하는 방법에 대해 알아보았습니다. PWM은 LED 제어뿐만 아니라 모터 제어나 스피커 제어 등에도 많이 사용되는 유용한 기술입니다. 이번 예제를 바탕으로 여러분의 프로젝트에 PWM을 적용해 보시길 바랍니다.

반응형

'ESP32 IDF' 카테고리의 다른 글

ESP32 IDF DAC  (0) 2024.11.10
ESP32 IDF ADC  (0) 2024.11.09
ESP32 IDF FreeRTOS  (0) 2024.11.07
ESP32 IDF BLE 클라이언트  (0) 2024.11.06
ESP32 IDF BLE 서버  (0) 2024.11.05