PWM en Arduino, ESP8266 y ESP32: Guía de Pines, Frecuencia y Duty Cycle

En este tutorial aprenderás qué es el PWM, cómo crear diferentes señales PWM y cómo usar el PWM para controlar el brillo de un LED y la velocidad de un motor DC.

En esta guía técnica analizamos a fondo el funcionamiento de la modulación por ancho de pulsos (PWM, Pulse Width Modulation), el cálculo del ciclo de trabajo (duty cycle), las frecuencias nativas de conmutación en Arduino y ESP32, y cómo verificar la forma de onda en laboratorio con un osciloscopio digital:

  • Pines PWM y temporizadores hardware: frecuencias por defecto (490 Hz vs 980 Hz en Arduino Uno; 1 kHz en ESP8266; hasta 40 MHz en ESP32 con LEDC).
  • Cálculo de ciclo de trabajo y tensión media: relación matemática entre analogWrite(), porcentaje de tiempo en alto y tensión continua equivalente.
  • Control de potencia y seguridad eléctrica: desacoplo inductivo con diodos flyback para motores de corriente continua (driver L298N) y límites de corriente por pin.
  • Diagnóstico con osciloscopio: medición de frecuencia, ciclo de trabajo automático, filtrado paso bajo RC para convertir PWM en analógica pura y observación del rizado.

¿Cómo funciona PWM para microcontroladores?

Las entradas / salidas digitales de su microcontrolador tienen un voltaje constante de 3.3 V (para placas ESP8266 y ESP32) o 5 V (para placas Arduino). Pero en algunos casos, desea controlar el voltaje a un valor específico entre 0 V y el voltaje máximo.

En el caso de PWM, una señal pulsada entre ALTA (3.3V o 5V) y BAJA (0V). La frecuencia a la que la señal cambia entre ALTA y BAJA está definida por la frecuencia PWM. La frecuencia PWM en los pines de Arduino es de 976 ciclos por segundo (Herz), para el ESP8266 hasta 1 kHz y para el ESP32 hasta 40 MHz.

Para generar una señal PWM, utilice la función analogWrite (pin, value). Esta función crea una señal PWM de onda cuadrada. Puede controlar la forma de la señal PWM con el ciclo de trabajo de (valor / 255). Un ciclo de trabajo de 0% a 100% corresponde a un valor entre 0 y 255.

La siguiente tabla muestra en líneas generales la relación entre el ciclo de trabajo y el voltaje de salida promedio si el voltaje máximo es 5V para el microcontrolador Arduino y 3.3V para el microcontrolador ESP8266 y ESP32.

Ciclo de Trabajo (Duty Cycle) Tensión Media (Arduino 5 V) Tensión Media (ESP32/ESP8266 3,3 V) Valor analogWrite() (8 bits: 0-255) Valor analogWrite() (10 bits: 0-1023)
0% (Siempre en nivel BAJO) 0,00 V 0,00 V 0 0
25% (1/4 en ALTO) 1,25 V 0,825 V 64 256
50% (Onda cuadrada simétrica) 2,50 V 1,650 V 128 512
75% (3/4 en ALTO) 3,75 V 2,475 V 191 768
100% (Siempre en nivel ALTO) 5,00 V 3,300 V 255 1023

Usé mi osciloscopio para medir los ciclos de trabajo de la tabla anterior para el voltaje de salida de Arduino. Por lo tanto, conecté el pin digital 11 del Arduino Uno a mi PicoScope y configuré una medida para el ciclo de trabajo. Puede hacer exactamente la misma medición para el ESP8266 o ESP32

El código para la medición rápida es el siguiente. Para cada medición, cambié el valor de la función analogWrite.

Ciclo de trabajo del 0%
Tenga en cuenta que el ciclo de trabajo del 0% se mide al 100% porque no hay onda cuadrada al 0% y también al 100%. Por lo tanto, preste atención a cómo se mide el ciclo de trabajo. En mi caso, necesito ver si el voltaje es 0 al 100% del ciclo de trabajo.

Tutorial de PWM para Arduino ESP8266 y ESP32

Ciclo de trabajo del 25%

1616965910 162 Tutorial de PWM para Arduino ESP8266 y ESP32

Ciclo de trabajo del 50%

1616965911 130 Tutorial de PWM para Arduino ESP8266 y ESP32

Ciclo de trabajo 75%

1616965911 841 Tutorial de PWM para Arduino ESP8266 y ESP32

Ciclo de trabajo del 100%

1616965911 515 Tutorial de PWM para Arduino ESP8266 y ESP32

Cómo cambiar el brillo de un LED por PWM

En el siguiente ejemplo, queremos cambiar el brillo de un LED cambiando el ciclo de trabajo de la señal PWM relevante.

Los siguientes bocetos impresionantes muestran el circuito realizado con diferentes placas de microcontroladores Arduino, ESP8266 y ESP32. Necesitamos asegurarnos de que el LED esté conectado a un pin de microcontrolador compatible con PWM.

A continuación se detallan las conexiones y el cableado práctico para verificar el control PWM tanto en un LED indicador como en etapas de potencia mediante microcontroladores Arduino, ESP8266 y ESP32.

Cableado entre LED y microcontrolador Arduino para PWM

Las siguientes imágenes muestran el cableado entre diferentes placas Arduino, el LED que queremos controlar y una resistencia de 220Ω para evitar que el LED tenga un voltaje demasiado alto.

Para este ejemplo, estoy usando el pin digital 11 que es capaz de crear señales PWM, pero también puede usar cualquier otro pin compatible con PWM.

  • Arduino Nano
  • Arduino Pro Mini
  • Arduino Uno
  • Arduino Mega

Arduino Nano

PWM LED Arduino Nano

Para obtener más información sobre Arduino Nano, visite el tutorial de Arduino Nano.

Arduino Pro Mini

PWM LED Arduino Pro Mini

Arduino Uno

PWM LED Arduino Uno

Para obtener más información sobre Arduino Uno, visite el tutorial de Arduino Uno.

Arduino Mega

PWM LED Arduino Mega

Para obtener más información sobre Arduino Mega, visite el tutorial de Arduino Mega.

Cableado entre LED y microcontrolador ESP8266 para PWM

Las siguientes imágenes muestran la conexión entre diferentes placas ESP8266 como ESP8266 NodeMCU o ESP8266 WeMos D1 Mini y el LED, así como la resistencia de 220Ω.

Necesitamos una resistencia en serie para el LED para evitar que el LED tenga voltajes demasiado altos.

Puede elegir cualquier pin de E / S digital del ESP8266 para este ejemplo, porque todos los pines de E / S digitales del ESP8266 son capaces de crear señales PWM, pero asegúrese de cambiar también el pin en el script del programa. Estoy seleccionando el pin D4 para este ejemplo.

  • ESP8266 NodeMCU
  • ESP8266 WeMos D1 Mini

ESP8266 NodeMCU

PWM LED ESP8266 NodeMCU

ESP8266 WeMos D1 Mini

PWM LED ESP8266 WeMos D1 Mini

Cableado entre LED y microcontrolador ESP32 para PWM

La siguiente imagen muestra el cableado entre la placa del microcontrolador ESP32 ESP-WROOM-32, el LED y la resistencia de 220Ω para evitar que el LED tenga voltajes excesivamente altos.

Dado que cualquier pin de E / S digital en el ESP32 es capaz de crear señales PWM, puede elegir cualquier otro pin digital, pero asegúrese de cambiar el script del programa. En mi caso, conecto el pin 4 del ESP32 al LED.

ESP32 ESP-WROOM-32

PWM LED ESP32 NodeMCU

Código de programa para cambiar el brillo de un LED por PWM

El código del programa es bastante simple. Necesitamos configurar los pines y algunas variables de tiempo y altura para incrementar el brillo del LED. Si quieres saber cómo cambiar el color de los LED multicolores, utilizando diferentes señales PWM, lo encontrarás en mi tutorial de LED.

int LEDpin = 11;   // for Arduino microcontroller
//int LEDpin = D4;   // for ESP8266 microcontroller
//int LEDpin = 4;   // for ESP32 microcontroller

int bright = 0;    // initial value of LED brightness
int incremt = 5;   // incremental change in PWM frequency
int time = 100;    // time period the PWM frequency is changing

void setup()
  {
    pinMode(LEDpin, OUTPUT);  // define the LEDpin as output pin
  }

void loop()
  {
    analogWrite(LEDpin, bright);  // set LED brightness as PWM signal
    delay(time);                  // wait for a time period
    bright = bright + incremt;    // increment LED brightness
    // if the brightness is out of range, reduce brightness
    if (bright <=0 || bright >=255) incremt = - incremt;
  }

En la primera parte del código Arduino, definimos el pin que conecta el LED al microcontrolador. Dado que este script es para microcontroladores Arduino, ESP32 y ESP8266, debe comentar dos de las tres primeras líneas que definen el pin.

También necesitamos definir tres variables adicionales:

  • brillante: valor inicial de la luminosidad del LED y por tanto 0 para apagar el LED.
  • incremento: el cambio incremental de la frecuencia PWM. Con cada incremento, el LED aumenta y disminuye el brillo.
  • tiempo: el período en milisegundos para cada ciclo PWM.

En la función de configuración, estamos ajustando el pin, que configuramos como el pin LED al comienzo del script, como el pin de salida para usar el pin con PWM.

Iniciamos la función loop, con la función analogWrite (pin, value) establecemos el valor analógico (onda PWM) para el brillo en el pin LED. Después del retraso de 0,1 segundos, se incrementa el brillo. Si el brillo alcanza el valor mínimo (0) o máximo (255), el incremento cambia de un valor positivo a un valor negativo.

El siguiente video muestra el cambio en el brillo del LED debido a la función PWM.

Cómo controlar la velocidad de un motor de CC mediante PWM

Reglas de seguridad y protección eléctrica en circuitos PWM
  • Picos inductivos flyback en control de motores: Al conmutar cargas inductivas como motores de corriente continua mediante PWM, cada corte de corriente genera un transitorio inductivo inverso (V = −L × di/dt) que puede alcanzar de 50 a 100 V. Es obligatorio utilizar un diodo de rueda libre (flyback tipo Schottky 1N5819 o similar) conectado en antiparalelo con los bornes del motor, o verificar que tu driver (ej. L298N o DRV8833) cuente con diodos de supresión integrados para no destruir los transistores de conmutación.
  • Límites de corriente por pin del microcontrolador: Un pin digital de Arduino Uno/Nano solo puede entregar un máximo de 20 mA de forma continua (40 mA límite absoluto). Conectar un motor de CC directamente a un pin PWM quemará instantáneamente la etapa de salida del chip ATmega328P. Utiliza siempre un transistor MOSFET de nivel lógico (ej. IRLZ44N) o un controlador en puente H intermediario.
  • PWM no es una tensión analógica continua pura: Una señal PWM conmuta bruscamente entre 0 V y el voltaje de alimentación. Si conectas una señal PWM directamente a la entrada de un amplificador de audio analógico o un circuito de instrumentación que requiere tensión continua, inyectarás un ruido severo de alta frecuencia. Intercala siempre un filtro paso bajo RC pasivo o activo para alisar la señal.

El segundo ejemplo muestra cómo podemos cambiar la velocidad de un motor de CC usando una señal PWM. Usamos el módulo de controlador de motor L298N para conectar Arduino, ESP8266 o ESP32 al motor de CC. También se recomienda alimentar el motor de CC con una fuente de alimentación externa. Por lo tanto, estoy usando 4 pilas AA, cada una con 1,5 V, por lo que en total 6 V.

Quiero centrarme en la señal PWM en este ejemplo. Por lo tanto, no describo más el ejemplo del motor de CC. Pero si está interesado en los motores de CC, escribiré un artículo adicional sobre motores de CC, que lo explica todo en detalle.

Cableado entre el motor de CC y el microcontrolador Arduino para PWM

Las siguientes imágenes muestran las conexiones para controlar la velocidad de un motor de CC a través de la señal PWM del microcontrolador Arduino. El motor de CC está conectado al controlador del motor L298N.

Usamos 4 pilas AA o fuente de alimentación de laboratorio para alimentar el controlador del motor L298N. El microcontrolador Arduino se alimenta a través de USB o también a través de la fuente de alimentación del laboratorio

Para controlar la velocidad y el sentido de giro del motor DC, conectamos los pines ENA, INT1 e INT2 a los pines digitales de la placa Arduino.

  • Arduino Nano
  • Arduino Pro Mini
  • Arduino Uno
  • Arduino Mega

Arduino Nano

Motor Arduino Nano DC L298N

Para obtener más información sobre Arduino Nano, visite el tutorial de Arduino Nano.

Arduino Pro Mini

Motor de CC Arduino Pro Mini L298N

Arduino Uno

Motor Arduino Uno L298N DC

Para obtener más información sobre Arduino Uno, visite el tutorial de Arduino Uno.

Arduino Mega

Motor Arduino Mega L298N DC

Para obtener más información sobre Arduino Mega, visite el tutorial de Arduino Mega.

Cableado entre el motor de CC y el microcontrolador ESP8266 para PWM

El cableado entre la placa ESP8266, la fuente de alimentación, el controlador del motor L298N y el motor de CC se muestra en la siguiente imagen.

Se pueden usar cuatro baterías AA de una fuente de alimentación de laboratorio como fuente de alimentación para el controlador del motor. La tarjeta ESP8266 se alimenta mediante la conexión USB y la masa está conectada entre ellos.

La velocidad y la dirección de rotación del motor de CC se controlan a través de los pines ENA, INT1 e INT2 del controlador del motor L298N y se conectan a los pines digitales de la placa ESP8266. El motor de CC en sí está conectado directamente al controlador del motor.

  • ESP8266 NodeMCU
  • ESP8266 WeMos D1 Mini

ESP8266 NodeMCU

Motor de CC L298N ESP8266 NodeMCU

ESP8266 WeMos D1 Mini

Motor DC L298N ESP8266 WeMos D1 Mini

Cableado entre el motor de CC y el microcontrolador ESP32 para PWM

La siguiente imagen muestra cómo conectar un motor de CC al ESP32 ESP-WROOM-32. Para la fuente de alimentación de 6 V, puede utilizar 4 pilas AA o una fuente de alimentación de laboratorio. La tarjeta ESP32 se alimenta mediante la conexión USB o también mediante la fuente de alimentación del laboratorio.

Para controlar el motor de CC, no podemos conectar el motor de CC directamente al ESP32, pero necesitamos el controlador de motor L298N. Los pines ENA, INT1 e INT2 para controlar la velocidad y el sentido de rotación del motor de CC están conectados a tres pines digitales del ESP32. Luego, el motor de CC se conecta al controlador del motor L298N.

ESP32 ESP-WROOM-32

Motor de CC L298N ESP32 NodeMCU

Código de programa para controlar la velocidad de un motor de CC por PWM

Para el código del programa, queremos aumentar la velocidad del motor cada segundo. En el arranque, el voltaje suministrado por la señal PWM es demasiado bajo para arrancar el motor. Esta es la razón por la que se necesitan algunos intervalos en el bucle for hasta que el motor esté en funcionamiento.

// Arduino connection to L298N
int enA = 10; // PWM for Motor A
int in1 = 9;  // Control Rotation of Motor A
int in2 = 8;  // Control Rotation of Motor A

// ESP8266 connection to L298N
//int enA = D4; // PWM for Motor A
//int in1 = D5;  // Control Rotation of Motor A
//int in2 = D6;  // Control Rotation of Motor A

// ESP32 connection to L298N
//int enA = 4; // PWM for Motor A
//int in1 = 0;  // Control Rotation of Motor A
//int in2 = 2;  // Control Rotation of Motor A

int motor_speed = 0; 

void setup()
{
  // set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
}

void loop()
{
  // run the motor between 0 and 250 in increments of 10
  digitalWrite(in1, LOW); // Input1 LOW = move forward
  digitalWrite(in2, HIGH);  // Input2 HIGH = move forward
  for(motor_speed = 0; motor_speed < 250; motor_speed += 10)
  {
    analogWrite(enA, motor_speed); // PWM output
    delay(1000);
  }
}

En la primera parte del script, definimos los pines que conectan el microcontrolador al módulo L298N, que está conectado al motor de CC. En total, necesitamos definir 3 pines:

  • enA: transfiere la señal PWM al módulo L298N y debe ser un pin capaz de producir una señal PWM.
  • int1 e int2: controlan la dirección de rotación del motor. La siguiente tabla muestra cómo controlar int1 e int2 para detener el motor, avanzar y retroceder.

Como este script es para placas de microcontroladores Arduino, EPS8266 y ESP32, debe seleccionar solo las filas para su microcontrolador y comentar las otras filas. El script real está comentado de alguna manera, es decir, para placas Arduino.

Para aumentar la velocidad del motor, la velocidad debe almacenarse en una variable que llamamos motor_speed y que tiene un valor inicial de 0.

En la función de configuración definimos como salidas todos los pines digitales que conectan la placa al L298N.

Comenzamos la función de bucle configurando int1 LOW e int2 HIGH. Por lo tanto, el motor de CC gira hacia adelante. En el bucle for, aumentamos la velocidad del motor cada segundo en 10 entre 0 y 250. La velocidad del motor se escribe como una salida analógica (señal PWM) en la conexión enA.

El siguiente video muestra el script Arduino en acción para Arduino Uno como ejemplo.

Conclusión

Espero que hayas recomendado este artículo sobre la señal PWM. La señal PWM es una herramienta muy útil que se usa mucho en ejemplos prácticos. Se recomienda saber cómo funciona PWM. Por lo tanto, si tiene más preguntas, use la sección de comentarios a continuación para hacerlas.

Diagnóstico de Señales PWM con Osciloscopio: Frecuencia, Duty Cycle y Filtrado

Al programar salidas PWM para variar la velocidad de motores, la intensidad de iluminación o controlar etapas de potencia, el multímetro solo muestra un valor de tensión promedio aproximado, ocultando por completo la forma de onda, el rizado y las perturbaciones de conmutación. El osciloscopio digital es el instrumento imprescindible para auditar con rigor métrico la señal PWM.

1. Conexión de sondas y configuración del instrumento

  • Atenuación 10X: Configura la sonda del osciloscopio en modo 10X conectada al pin PWM bajo prueba. La atenuación 10X reduce la capacidad parásita a solo 10-15 pF, evitando falsear los tiempos de subida de la onda cuadrada.
  • Conexión de masa sólida: Conecta la pinza de cocodrilo de tierra al GND del circuito mediante un trayecto lo más corto posible para eliminar inductancias parásitas que generen timbrado artificial en pantalla.
  • Escala temporal y vertical: Para una señal de Arduino Uno a 490 Hz (período T = 2,04 ms), ajusta la base de tiempos a 500 μs/div o 1 ms/div. En vertical, selecciona 1 V/div o 2 V/div con acoplamiento DC.

2. Medición automática de frecuencia y ciclo de trabajo (Duty Cycle)

Los osciloscopios de sobremesa digitales permiten activar parámetros de medida continua en pantalla:

  • Frecuencia (Freq): Comprueba que la frecuencia se mantenga estable (ej. 490 Hz en pines 3, 9, 10 y 11 de Arduino Uno; 980 Hz en pines 5 y 6). Una fluctuación de frecuencia indica conflictos con librerías que modifican los divisores del temporizador (como Servo.h).
  • Ciclo de trabajo positivo (+Duty): Verifica que el porcentaje de tiempo en nivel ALTO responda proporcionalmente al valor pasado a analogWrite(pin, val). A val = 64 debe marcar 25%; a val = 128, exactamente 50%; y a val = 191, un 75%.
  • Tensión pico a pico (Vpp): Comprueba que los niveles lógicos alcancen los 5 V (o 3,3 V) limpios sin caídas excesivas causadas por sobrecarga de corriente en el pin.

3. Conversión de PWM en tensión analógica pura (Filtro paso bajo RC)

Para aplicaciones de control analógico (generación de audio básico, referencias de tensión de laboratorio o control de servomotores industriales), una señal PWM pura no es válida. Mediante un filtro paso bajo RC pasivo es posible alisar los pulsos en una tensión continua real:

  • Dimensionamiento del filtro: Utiliza una resistencia serie R = 4,7 kΩ y un condensador cerámico o electrolítico a masa C = 10 μF. La frecuencia de corte resultante es fc = 1 / (2πRC) ≈ 3,38 Hz, muy inferior a los 490 Hz de la portadora PWM.
  • Verificación en doble canal: Conecta el Canal 1 (CH1) antes del filtro (observando la onda cuadrada conmutando de 0 a 5 V) y el Canal 2 (CH2) después del filtro en acoplamiento AC para medir el rizado residual (ripple). Con estos valores, el rizado es inferior a 20 mV, proporcionando una tensión analógica continua suave y proporcional al duty cycle.
Modelo Ancho de Banda Canales Tasa de Muestreo Memoria Mediciones Automáticas y Filtrado
Rigol DS1054Z 50 MHz (ampliable a 100 MHz) 4 analógicos 1 GSa/s 24 Mpts Duty Cycle, Frecuencia, Filtro digital integrado y Math
Siglent SDS1104X-E 100 MHz 4 analógicos 1 GSa/s 14 Mpts 38 parámetros automáticos con estadísticas de jitter
Hantek DSO2D10 100 MHz 2 analógicos + AWG 1 GSa/s 8 Mpts Generador de funciones integrado (compara PWM con señal pura)
FNIRSI 1014D 100 MHz (efectivo ~30 MHz) 2 analógicos + AWG 1 GSa/s (compartido) 240 Kpts Medición de ciclo de trabajo y Vpp básica

Para diagnosticar circuitos PWM, controlar filtros analógicos y depurar puentes H en laboratorio, el Rigol DS1054Z es el osciloscopio más completo gracias a sus 4 canales y memoria de 24 Mpts:

Preguntas frecuentes sobre PWM en microcontroladores

¿Cómo obtener una tensión analógica continua real a partir de una salida PWM de Arduino?

Una salida PWM es una onda cuadrada digital que conmuta entre 0 V y 5 V. Si necesitas una tensión continua suave (DC) para controlar un amplificador o circuito analógico, intercala un filtro paso bajo RC a la salida del pin PWM: una resistencia serie de 4,7 kΩ seguida de un condensador de 10 μF conectado a masa (GND). Esto atenúa la componente de conmutación de 490 Hz dejando pasar únicamente la tensión media con un rizado inferior a 20 mV.

¿Por qué el motor de CC emite un zumbido agudo al controlarlo con PWM en Arduino?

La frecuencia PWM por defecto de Arduino Uno en la mayoría de pines es de 490 Hz, un tono que cae de lleno en el rango audible del oído humano (20 Hz a 20 kHz). Las bobinas del motor vibran acústicamente a esa frecuencia. Para eliminar el zumbido por completo, se debe elevar la frecuencia de conmutación por encima de 20 kHz (ultrasónica) modificando los registros de los temporizadores internos (Timer1 o Timer2) o utilizando el periférico LEDC en un ESP32.

¿Cómo se genera PWM en el ESP32 si no tiene pines marcados con la virgulilla (~)?

A diferencia de Arduino Uno, el ESP32 no tiene pines PWM fijos dedicados: dispone de un generador de control LED por hardware (LEDC) con 16 canales independientes. Cualquier pin GPIO de salida puede emitir una señal PWM configurando su frecuencia (de 1 Hz a 40 MHz) y su resolución (de 1 a 16 bits). Además, en las versiones modernas del núcleo de Arduino para ESP32 (core 3.x), la función estándar analogWrite(pin, valor) funciona directamente sobre cualquier GPIO de salida asignando un canal LEDC de forma automática.

Deja un comentario