1. Home
  2. Docs
  3. ESP-IDF / ESP32
  4. Giriş
  5. ESP-IDF ile ADC Okuma ve Kalibrasyon: Hassas Analog Ölçüm

ESP-IDF ile ADC Okuma ve Kalibrasyon: Hassas Analog Ölçüm

Print

Analog sensörler (potansiyometreler, NTC sıcaklık probları, LDR ışık sensörleri veya pil voltaj bölücüleri) mikrodenetleyicilerde analog-dijital dönüştürücü (ADC) birimleri üzerinden okunur. Ancak ESP32’nin yerleşik SAR ADC birimi, 0V ve 3.3V uçlarında doğal bir lineersizliğe (doğrusal olmama) ve çip üretim farklılıklarından kaynaklanan referans gerilimi sapmalarına sahiptir. Bu nedenle endüstriyel doğrulukta gerilim ölçümü için ESP-IDF ADC kalibrasyon mekanizmasını (espadccal) ve zayıflatma (attenuation) yapılandırmasını eksiksiz uygulamak şarttır.

Bu rehberde; ESP32 ADC donanımını (ADC1 vs ADC2 farkı), zayıflatma parametrelerini, eFuse üzerinde saklanan fabrika kalibrasyon verilerini okumayı ve ham ADC değerlerini milivolt (mV) seviyesinde hassas gerilime dönüştürmeyi öğreneceğiz.


ESP32 ADC Donanım Mimarisi

ESP32 üzerinde 12-bit çözünürlüğe sahip iki adet bağımsız ADC birimi bulunur:

  • ADC1: 8 kanal içerir (GPIO32 – GPIO39). Wi-Fi açıkken güvenle kullanılabilir.
  • ADC2: 10 kanal içerir (GPIO0, GPIO2, GPIO4, GPIO12 – GPIO15, GPIO25 – GPIO27). Wi-Fi veya Bluetooth çalıştığında ADC2 sürücüsü kilitlenir ve kullanılamaz! Bu sebeple projelerinizde daima ADC1 kanallarını tercih edin.

Zayıflatma (Attenuation) ve Ölçüm Aralıkları

Dahili referans gerilimi yaklaşık 1.1V’tur. Daha yüksek gerilimleri ölçebilmek için giriş sinyali donanımsal bir gerilim bölücüden (attenuator) geçirilir:

Zayıflatma SeviyesiGiriş Gerilimi AralığıÖnerilen Kullanım
ADCATTENDB_0 (0 dB)100 mV ~ 950 mVDüşük sinyalli hassas sensörler
ADCATTENDB25 (2.5 dB)100 mV ~ 1250 mV~1.2V referanslı sensörler
ADCATTENDB_6 (6 dB)150 mV ~ 1750 mV~1.5V aralığı
ADCATTENDB_11 (11 dB) / 12150 mV ~ 3100 mV3.3V sistemler, potansiyometre ve pil ölçümü

Donanımsal Kalibrasyon: eFuse ve İki Nokta (Two Point)

Espressif, fabrikada her çipin ADC referans gerilimini ölçerek çipin tek seferlik yazılabilir eFuse hafızasına kaydeder:

  1. Two Point Kalibrasyonu: En hassas yöntemdir (150mV ve 850mV referansları saklanır).
  2. eFuse Vref: Çipin dahili 1100mV referansının gerçek değeri (örn: 1092mV) saklanır.
  3. Varsayılan Vref: eFuse yazılmamış eski çiplerde varsayılan 1100mV baz alınır.

espadccal_characterize fonksiyonu eFuse kayıtlarını otomatik okuyarak ideal transfer eğrisini (Look-Up Table / Polinom) çıkarır.


Adım Adım ADC Okuma ve Kalibrasyon Kodu

Aşağıdaki örnekte GPIO34 (ADC1 Kanal 6) üzerinden analog gerilim okuyup milivolt olarak ekrana basıyoruz:

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

#define ADC_CHANNEL         ADC1_CHANNEL_6     // GPIO34
#define ADC_ATTEN           ADC_ATTEN_DB_11    // 0 - 3.1V aralığı
#define ADC_WIDTH           ADC_WIDTH_BIT_12   // 12-bit (0 - 4095)
#define NO_OF_SAMPLES       64                 // Gürültüyü azaltmak için multisampling
#define DEFAULT_VREF        1100               // eFuse yoksa varsayılan mV

static const char *TAG = "ADC_CAL";
static esp_adc_cal_characteristics_t adc_chars;

static void check_efuse(void) {
    // eFuse kalibrasyon desteğini kontrol et
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_EFUSE_TP) == ESP_OK) {
        ESP_LOGI(TAG, "eFuse Two Point kalibrasyonu mevcut.");
    } else if (esp_adc_cal_check_efuse(ESP_ADC_CAL_EFUSE_VREF) == ESP_OK) {
        ESP_LOGI(TAG, "eFuse Vref kalibrasyonu mevcut.");
    } else {
        ESP_LOGW(TAG, "eFuse kalibrasyonu bulunamadı! Varsayılan Vref kullanılacak.");
    }
}

void app_main(void) {
    check_efuse();

    // 1. ADC Çözünürlük ve Kanal Zayıflatmasını Ayarla
    ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH));
    ESP_ERROR_CHECK(adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN));

    // 2. Kalibrasyon Karakteristiğini Çıkar
    esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN, ADC_WIDTH, DEFAULT_VREF, &adc_chars);

    ESP_LOGI(TAG, "ADC Başlatıldı. Ölçüm döngüsü başlıyor...");

    while (1) {
        uint32_t adc_reading = 0;
        
        // 3. Çoklu Örnekleme (Multisampling / Ortalama Alma)
        // Analog parazitleri süzmek için 64 okuma yapıp ortalamasını alıyoruz
        for (int i = 0; i < NO_OF_SAMPLES; i++) {
            adc_reading += adc1_get_raw(ADC_CHANNEL);
        }
        adc_reading /= NO_OF_SAMPLES;

        // 4. Ham Değeri Kalibre Edilmiş Gerilime (mV) Çevir
        uint32_t voltage_mv = esp_adc_cal_raw_to_voltage(adc_reading, &adc_chars);

        ESP_LOGI(TAG, "Ham ADC Değeri: %lu / 4095  |  Gerilim: %lu mV (%.3f V)", 
                 adc_reading, voltage_mv, (float)voltage_mv / 1000.0f);

        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

Donanımsal Doğruluğu Artırma Taktikleri

  1. Parazit Filtreleme Kondansatörü: ADC pini ile GND arasına 0.1µF (100nF) seramik kondansatör bağlamak, RF devrelerinden ve Wi-Fi anahtarlamasından kaynaklanan yüksek frekanslı gürültüyü filtreler.
  2. Uç Nokta Sınırları: ESP32 ADC’si 0V ile 100mV arasında ve 3.1V ile 3.3V arasında doyuma (saturation) ulaşır. Bu aralıklarda hassasiyet kaybolur. Eğer 0V’a çok yakın değerler okuyacaksanız sensör çıkışına harici bir OP-AMP (işlemsel kuvvetlendirici) ekleyin.
  3. Multisampling Sayısı: Kodumuzdaki NOOFSAMPLES = 64 değeri gürültü dalgalanmalarını neredeyse tamamen yok eder.

Özet

ESP32 projelerinizde analog ölçüm yaparken Wi-Fi ile çakışmaması için mutlaka ADC1 kanallarını seçin. espadccalcharacterize ve espadccalrawtovoltage fonksiyonları ile çipin donanımsal sapmalarını kompanse ederek fabrika kalitesinde mV hassasiyeti elde edebilirsiniz.

Tags , , , , ,

How can we help?