Implementación de una Señal PWM en ESP32
1. Introducción
En esta práctica, aprenderemos a generar una señal PWM (Modulación por Ancho de Pulso) con ESP32 usando Visual Studio Code. Para ello, utilizaremos un circuito que ya empleamos en la lectura de señales analógicas, modificándolo para generar una salida PWM que nos permitirá controlar la intensidad de un LED a través de un potenciómetro.
2. Configuración del Entorno y Circuito
Antes de comenzar con el código, asegurémonos de contar con:
- ESP32 correctamente conectada.
- Potenciómetro para la entrada analógica.
- LED conectado a un pin de salida PWM.
- Documentación del pinout de la placa para seleccionar pines adecuados.
3. Lectura de Señal Analógica
El siguiente código permite leer un valor analógico y mostrarlo en la consola:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/adc.h"
void app_main(void) {
int32_t raw_value;
adc2_config_channel_atten(ADC2_CHANNEL_6, ADC_ATTEN_DB_0);
while (1) {
adc2_get_raw(ADC2_CHANNEL_6, ADC_WIDTH_BIT_12, &raw_value);
printf("adc raw: %d\n", raw_value);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
4. Configuración del PWM en ESP32
Agregamos la librería necesaria:
#include "driver/ledc.h"
Definimos constantes clave:
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_HIGH_SPEED_MODE
#define LEDC_OUTPUT 12
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_DUTY_RES LEDC_TIMER_12_BIT
#define LEDC_FREQUENCY 5000
#define LEDC_DUTY 0
#define LEDC_HPOINT 0
Configuración del Temporizador (Timer)
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_MODE,
.timer_num = LEDC_TIMER,
.duty_resolution = LEDC_DUTY_RES,
.freq_hz = LEDC_FREQUENCY,
.clk_cfg = LEDC_AUTO_CLK
};
ledc_timer_config(&ledc_timer);
Configuración del Canal PWM
ledc_channel_config_t ledc_channel = {
.speed_mode = LEDC_MODE,
.channel = LEDC_CHANNEL,
.timer_sel = LEDC_TIMER,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = LEDC_OUTPUT,
.duty = LEDC_DUTY,
.hpoint = LEDC_HPOINT
};
ledc_channel_config(&ledc_channel);
5. Implementación de la Señal PWM
Dentro del bucle principal, ajustamos el PWM según la entrada analógica:
while (1) {
adc2_get_raw(ADC2_CHANNEL_6, ADC_WIDTH_BIT_12, &raw_value);
printf("adc raw: %d\n", raw_value);
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, raw_value);
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}