ESP32 IDF

ESP32 IDF ADC

임베디드 친구 2024. 11. 9. 09:18
반응형

안녕하세요, '소프트웨어 공장'에 오신 것을 환영합니다. 오늘은 ESP32의 ADC(Analog to Digital Converter)를 어떻게 설정하고 사용하는지에 대해 알아보겠습니다. ESP32는 여러 아날로그 입력을 처리할 수 있는 강력한 ADC 기능을 제공하며, 이 기능을 통해 다양한 센서로부터 데이터를 수집할 수 있습니다. 이번 포스팅에서는 VS Code 개발 환경에서 ESP-IDF를 사용하여 ADC를 설정하고 값을 읽는 방법을 예제를 통해 설명드리겠습니다.

1. ADC란?

ADC(Analog to Digital Converter)는 아날로그 신호를 디지털 데이터로 변환하는 장치입니다. ESP32에는 최대 18개의 ADC 핀이 있으며, 두 개의 ADC 모듈(ADC1과 ADC2)이 있습니다. 이를 통해 다양한 아날로그 센서 값을 손쉽게 디지털 데이터로 변환하여 처리할 수 있습니다.

  • ADC1: GPIO32 ~ GPIO39 사용 가능
  • ADC2: GPIO0 ~ GPIO15 사용 가능

이번 예제에서는 ADC1을 사용하여 아날로그 신호를 읽는 방법을 설명하겠습니다.

2. 코드 예제: ADC 설정 및 값 읽기

2.1 프로젝트 생성 및 파일 구조

VS Code에서 새로운 ESP-IDF 프로젝트를 생성하고, main 폴더 안에 adc_example.c 파일을 생성합니다. 이 파일에 ADC 관련 코드를 작성합니다.

2.2 코드 작성

아래는 ADC를 설정하고 값을 읽는 예제 코드입니다.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"

#define DEFAULT_VREF    1100  // ADC 기본 참조 전압 (mV 단위)
#define NO_OF_SAMPLES   64    // 평균을 위한 샘플 수

static esp_adc_cal_characteristics_t *adc_chars;
static const adc_channel_t channel = ADC_CHANNEL_6;     // GPIO34에 해당하는 채널
static const adc_atten_t atten = ADC_ATTEN_DB_0;        // 감쇠 설정
static const adc_unit_t unit = ADC_UNIT_1;              // ADC1 사용

void app_main(void)
{
    // ADC 특성 초기화
    adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
    adc1_config_width(ADC_WIDTH_BIT_12);                // 12비트 해상도 설정
    adc1_config_channel_atten(channel, atten);          // 채널 및 감쇠 설정
    esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);

    while (1) {
        uint32_t adc_reading = 0;
        // 다수의 샘플을 읽어 평균화
        for (int i = 0; i < NO_OF_SAMPLES; i++) {
            adc_reading += adc1_get_raw((adc1_channel_t)channel);
        }
        adc_reading /= NO_OF_SAMPLES;

        // 전압 값으로 변환
        uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
        printf("Raw: %d\tVoltage: %dmV\n", adc_reading, voltage);

        vTaskDelay(pdMS_TO_TICKS(1000));  // 1초 지연
    }
}

2.3 코드 설명

  1. 헤더 파일 포함: 필요한 헤더 파일(freertos/FreeRTOS.h, driver/adc.h, esp_adc_cal.h)을 포함합니다.
  2. 매크로 정의:
    • DEFAULT_VREF: ESP32의 기본 참조 전압을 1100mV로 설정합니다.
    • NO_OF_SAMPLES: ADC 값을 평균화하기 위한 샘플 수를 64로 설정합니다.
  3. ADC 설정:
    • adc_chars 변수를 통해 ADC 특성을 초기화합니다.
    • adc1_config_width(ADC_WIDTH_BIT_12): ADC 해상도를 12비트로 설정합니다.
    • adc1_config_channel_atten(channel, atten): 채널과 감쇠를 설정합니다.
  4. ADC 값 읽기:
    • adc1_get_raw() 함수를 사용하여 아날로그 값을 읽고, esp_adc_cal_raw_to_voltage() 함수를 사용하여 읽은 값을 전압(mV)으로 변환합니다.
  5. 출력: 변환된 원시 값과 전압 값을 터미널에 출력합니다.

3. 감쇠 설정 (Attenuation)

ADC는 입력 전압 범위를 조정하기 위해 감쇠(attenuation)를 설정할 수 있습니다. 감쇠 설정에 따라 ADC가 측정할 수 있는 최대 전압이 달라집니다.

  • ADC_ATTEN_DB_0: 0 ~ 1.1V
  • ADC_ATTEN_DB_2_5: 0 ~ 1.5V
  • ADC_ATTEN_DB_6: 0 ~ 2.2V
  • ADC_ATTEN_DB_11: 0 ~ 3.9V

예를 들어, 우리가 3.3V 범위의 아날로그 신호를 측정하려면 ADC_ATTEN_DB_11로 설정해야 합니다.

4. 전압 보정 (Calibration)

ESP32의 ADC는 정확도가 다소 떨어질 수 있기 때문에, esp_adc_cal API를 사용하여 보정 작업을 수행할 수 있습니다. 이 예제에서는 esp_adc_cal_characterize() 함수를 통해 보정을 수행하였습니다.

보정 함수는 ADC 특성을 계산하고, 이를 통해 원시 데이터를 실제 전압 값으로 변환하는 데 사용됩니다.

5. 실습 결과 확인

코드를 업로드한 후, 시리얼 모니터를 통해 ADC 값과 변환된 전압 값을 확인할 수 있습니다. 다음과 같이 출력이 나타날 것입니다.

Raw: 2048    Voltage: 1100mV
Raw: 2050    Voltage: 1102mV
...

이는 센서나 입력 신호의 변화에 따라 값이 실시간으로 업데이트되는 것을 보여줍니다.

6. 주의사항

  • 전압 제한: ESP32의 ADC 핀은 최대 3.3V까지만 입력을 허용합니다. 이보다 높은 전압을 입력할 경우 칩이 손상될 수 있으므로 주의해야 합니다.
  • ADC2 사용 제한: Wi-Fi 기능을 사용할 때는 ADC2 핀을 사용할 수 없습니다. 따라서 Wi-Fi와 함께 아날로그 입력을 사용해야 할 경우 ADC1 핀을 사용하는 것이 좋습니다.

7. 결론

이번 포스팅에서는 ESP32의 ADC를 설정하고 값을 읽는 방법에 대해 알아보았습니다. ADC는 다양한 센서 데이터를 처리할 때 매우 유용하며, ESP32의 강력한 기능 중 하나입니다. ESP-IDF를 사용하여 아날로그 입력을 설정하고 데이터를 읽는 과정을 이해함으로써, 여러분의 프로젝트에서 보다 다양한 센서와 상호작용할 수 있을 것입니다.

VS Code와 ESP-IDF 환경에서 ADC를 활용한 개발을 시작해보세요.
감사합니다!

반응형

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

ESP32 IDF I2C  (0) 2024.11.11
ESP32 IDF DAC  (0) 2024.11.10
ESP32 IDF PWM  (0) 2024.11.08
ESP32 IDF FreeRTOS  (0) 2024.11.07
ESP32 IDF BLE 클라이언트  (0) 2024.11.06