esp32-pwm

Cómo usar las salidas analógicas PWM en un ESP32

El ESP32 cuenta con múltiples pines que admiten la funcionalidad de PWM, lo que nos da una amplia flexibilidad para controlar diversos dispositivos.

Cada modelo de ESP32 tiene una cantidad de PWM disponibles saliendo. Por ejemplo, el ESP32 tiene 16, mientras que el ESP32-S3 tiene 8.

Sin embargo, el funcionamiento es algo distinto de lo que estamos acostumbrados en un Arduino “convencional”. Esto es debido a que el ESP32 dispone más de una forma de generar salidas PWM.

El equivalente al analogWrite que se emplea en Arduino para generar un PWM, en el caso del ESP32 sería la modulación que llaman ledc.

Aunque la función se llama ledc, no significa que únicamente sirva para LEDs. Puede usarse para cualquier dispositivo, incluidos motores, transitores, etc.

Cómo usar una salida PWM el ESP32

Antes de usar una salida PWM necesitamos configurar sus parámetros (como el canal PWM, el pin asociado y la frecuencia de modulación).

Para ello, utilizaremos la función ledcSetup()

const int ledChannel = 0;    // Canal PWM, puede ser de 0 a 15
const int ledPin = 5;        // Pin al que está conectado el dispositivo
const int frequency = 5000;  // Frecuencia en Hz
const int resolution = 8;    // Resolución en bits (de 1 a 15)

ledcSetup(ledChannel, frequency, resolution);

Una vez que hemos configurado los parámetros, podemos establecer el ciclo de trabajo para controlar la intensidad de la señal de salida.

El ciclo de trabajo se define como un valor entre 0 y 255 (o el valor máximo definido por la resolución) que representa el porcentaje del tiempo que el pin permanecerá en estado alto.

Un ciclo de trabajo de 0 significa que el pin estará siempre en estado bajo, mientras que un ciclo de trabajo de 255 mantendrá el pin siempre en estado alto.

Para establecer el ciclo de trabajo, utilizamos la función ledcWrite(). Aquí tienes un ejemplo de cómo controlar la intensidad del LED conectado al pin PWM:

int dutyCycle = 128; // Valor del ciclo de trabajo (0 a 255)

ledcWrite(ledChannel, dutyCycle);

Con un valor de dutyCycle de 128, el LED recibirá aproximadamente la mitad de la tensión máxima, lo que resultará en una luminosidad del 50%.

Ejemplo de código

A continuación, os pongo un ejemplo completo de cómo controlar la intensidad de un LED conectado al pin PWM del ESP32:

const int ledChannel = 0;
const int ledPin = 5;
const int frequency = 5000;
const int resolution = 8;

void setup() {
  ledcSetup(ledChannel, frequency, resolution);
  ledcAttachPin(ledPin, ledChannel);
}

void loop() {
  // Incrementar el ciclo de trabajo gradualmente para aumentar la intensidad del LED
  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
    ledcWrite(ledChannel, dutyCycle);
    delay(10);
  }

  // Disminuir el ciclo de trabajo gradualmente para reducir la intensidad del LED
  for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
    ledcWrite(ledChannel, dutyCycle);
    delay(10);
  }
}

En este ejemplo, el LED conectado al pin 5 se iluminará gradualmente desde el mínimo hasta el máximo ciclo de trabajo y luego se atenuará de nuevo.

Alternativa con una librería

Hay mucha gente que se ha acostumbrado a usar analogWrite como parte de sus programas, por la comodidad y sencillez que supone (incluso puede que tengáis muchos programas que la emplean, y que os gustaría usar en el ESP32).

Afortunadamente, no eres el único al que le pasa. Así que distintos autores han hecho librerías para permitir usar los PWM como en un Arduino “clásico”.

Un ejemplo de esta librería GitHub - erropix/ESP32_AnalogWrite: Provides an analogWrite polyfill for ESP32 using the LEDC functions

#include <Arduino.h>
#include <analogWrite.h>

int brightStep = 1;
int brightness = 0;

void setup() {
  // Set resolution for a specific pin
  analogWriteResolution(LED_BUILTIN, 12);
}

void loop() {
  brightness += brightStep;
  if ( brightness == 0 || brightness == 255 ) {
    brightStep = -brightStep;
  }

  analogWrite(LED_BUILTIN, brightness);

  delay(10);
}

Al usar esta librería vamos a perder parte de la flexibilidad que podemos usar ledc, por lo que es preferible que uséis esta.

Pero, como transición, para adaptar vuestros programas, o si os es más sencillo en docencia (por ejemplo), usar una librería no es una mala opción.



Referencias: