Analog To Digital Pada ESP32

Pendahuluan

Pada contoh project kali ini akan membahas penggunaan potensio untuk mengatur LED brightness. Potensio akan dihubungkan ke analog-to-digital converter (ADC) pin, value input dari potensio digunakan untuk mengatur tingkat kecerahan LED dengan menggunakan teknik pulse-width modulation (PWM).

Konversi analog-to-digital adalah teknik dasar dalam elektro untuk mengubah signal analog yang bersifat continuous, menjadi bentuk digital dengan resolusi. Contoh input
analog voltage dengan rentang 0-3.3 V dapat di-digitalasi oleh ADC dengan resolusi 10 bits, yang menyediakan value dengan rentang 0 sampai 1,023. ESP32 mengintegrasikan dua 12-bit ADCs
dengan 18 channels (GPIO pins).

PWM akan membuat efek sebaliknya. PWM sendiri bukat true digital-to-analog conversion (DAC),
namumn ketika kita mengenera high-frequency signal digital dan mengubah on-off ratio
(duty cycle) dalam satuan waktu, ratio digunakan untuk mengurangi output power.

Jadi pada contoh LED, akanterjadi dimming effect. 100% duty cycle berarti output
signal adalah on, dan 50% berarti hanya on separuh waktu. PWM juga dapat digunakan untuk mengatur direct current (DC) motors. Pada ESP32, semua output pins support PWM.

Contoh Penggunaan ADC

Component

  • LED dan resistor (>220 ohm).
  • Potensio

Skema

Code

Buka file main.c lalu tambahkan code berikut

// library yang digunakan
#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/adc.h"
#include "driver/ledc.h"

// definisikan variable dan macro
#define SAMPLE_CNT 32
static const adc1_channel_t adc_channel = ADC_CHANNEL_6;
#define LEDC_GPIO 18
static ledc_channel_config_t ledc_channel;

// hardware init
static void init_hw(void)
{
    adc1_config_width(ADC_WIDTH_BIT_10);
    adc1_config_channel_atten(adc_channel, ADC_ATTEN_DB_11);
    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_TIMER_10_BIT,
        .freq_hz = 1000,
        .speed_mode = LEDC_HIGH_SPEED_MODE,
        .timer_num = LEDC_TIMER_0,
        .clk_cfg = LEDC_AUTO_CLK,
    };
    ledc_timer_config(&ledc_timer);
    ledc_channel.channel = LEDC_CHANNEL_0;
    ledc_channel.duty = 0;
    ledc_channel.gpio_num = LEDC_GPIO;
    ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
    ledc_channel.hpoint = 0;
    ledc_channel.timer_sel = LEDC_TIMER_0;
    ledc_channel_config(&ledc_channel);
}

// main function
void app_main()
{
    init_hw();
    while (1)
    {
        uint32_t adc_val = 0;
        for (int i = 0; i < SAMPLE_CNT; ++i)
        {
            adc_val += adc1_get_raw(adc_channel);
        }
        adc_val /= SAMPLE_CNT;
        ledc_set_duty(ledc_channel.speed_mode, ledc_channel.
        channel, adc_val);
        ledc_update_duty(ledc_channel.speed_mode, ledc_channel.
        channel);
        vTaskDelay(500 / portTICK_RATE_MS);
    }
}

Penjelasan Code

Bagian import library:

Digunakan dua header files baru, yaitu driver/adc.h untuk ADC definitions dan
functions, dan driver/ledc.h untuk PWM control LEDs atau motors.

Bagian variable dan macro init

Kita gunakan ADC_CHANNEL_6 dari ADC-1 unit untuk sampling potensio. Channel berhubungan dengan GPIO34 pin (pada ESP32 devkitc ver4, silakan periksa datasheet board yang Anda gunakan). Untuk mendepatkan perkiraan yang lebih baik, signal tidak akan dibaca single value dari ADC channel, namun dilakukan sampling dalam single run dan menghitung nilai rata-ratanya.

Bagian Hardware init

Pertama, atur capture width dari ADC-1 unit ke ADC_WIDTH_BIT_10, yang berarti pembacaan akan dalam rentang 0-1,023. Maximum resolution adalah 12 bits, jadi kita gunakan 2^12 values dari ADC sampling.

Kemudian, konfigurasi channel attenuation untuk mendukung 3.3 V input dengan passing value ADC_ATTEN_DB_11 (terminal ketiga dari pot terhubung dengan 3.3 V pada devkit board).

Untuk mengkonfigurasi LED control channel perlu digunakan timer. LEDC_
TIMER_0 akan digunakan untuk keperluan ini, menyediakan 1,000 hertz (Hz) frequency untuk menjalankan LED.

Kita juga perlu mengkonfigurasi duty cycle resolution menjadi 10 bits agar pembacaan pada potensio secara langsung mengatur duty cycle value. Maximum resolution adalah 20 bits.

Perhatian: ESP32 memiliki empat 64-bit hardware timers dengan 16-bit prescalers dan up/down
counters.

Kemudian LED control channel configuration, yaitu LEDC_CHANNEL_0 (total tersedia 8 channels) pada LEDC_GPIO, yaitu GPIO18 dan menggunakan LEDC_TIMER_0, yang telah kita konfigurasi sebelumnya.

Pada main function

Pada app_main function, pertama kita inisialisasi hardware.

Kemudian, pada while loop, kita dapatkan samples dari ADC channel dengan bantuan adc1_get_raw function dan menghitung rata-rata untuk mendapatkan nilai perkiraan yang lebih baik.

Nila average digunakan untuk mengatur duty cycle dari LED control channel
(ledc_set_duty). Setting akan berefek ketika update channel untuk duty cycle dilakukan (ledc_update_duty).

Sampai disini kita sudah belajar menggunakan ADC dan PWM. Pada modul berikutnya kita akan belajar mengenai sensor.

Sharing is caring:

Leave a Comment