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.

Ciclo de trabajo del 25%

Ciclo de trabajo del 50%

Ciclo de trabajo 75%

Ciclo de trabajo del 100%

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

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

Arduino Uno

Para obtener más información sobre Arduino Uno, visite el tutorial de Arduino Uno.
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

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

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
- 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

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

Arduino Uno

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

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

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

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). Aval = 64debe marcar 25%; aval = 128, exactamente 50%; y aval = 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:
Para aprender más sobre análisis de señales periódicas y medidas de laboratorio, consulta nuestra guía sobre cómo medir el rizado con osciloscopio o la comparativa de mejores osciloscopios para Arduino y ESP32.
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.