Aziz Bench

Calculadora PWM: frecuencia y resolución

Elige el chip y la frecuencia que necesitas: verás cuántos bits de resolución del ciclo de trabajo obtienes, la frecuencia exacta, los valores del divisor o del temporizador y el código para Arduino, ESPHome y los SDK.

Resolución del ciclo de trabajo
13bits
8192 pasos a 5 kHz
Frecuencia obtenida
5 kHzexacta
Paso mínimo
24,4 ns0,0122 % del periodo
Divisor
1,953reloj APB, 80 MHz
Señal
encendido 100 µsperiodo 200 µs
Chip y software
Software

Arduino-ESP32 3.x toma el reloj del PWM del cristal en todos los chips salvo el ESP32 original, y eso limita la resolución. ESPHome elige la resolución por su cuenta.

Señal
Hz

En hercios: 5000 son 5 kHz.

%

Ajustes y código

Reloj y divisorReloj APB a 80 MHz, divisor 1,953 (div_param 500), 13 bits: el temporizador funciona a 5 kHz.
Valor que escribir50 % = 4096 de 8192. Escribe 8192 para dejarlo siempre encendido y 0 para dejarlo apagado.
Rango posibleA 5 kHz: de 1 a 13 bits. A 13 bits: de 0,119 Hz a 9,7656 kHz.
Ajustes compartidosEl ESP32 tiene 16 canales PWM y 8 temporizadores: los canales del mismo temporizador comparten frecuencia y resolución.

Código

Pon tu pin: los valores coinciden con el resultado de arriba.

Arduino-ESP32 3.x
const int PWM_PIN = 4;          // GPIO
const uint32_t PWM_FREQ = 5000;     // Hz
const uint8_t PWM_RES = 13;        // bit: 0–8192

void setup() {
  ledcAttach(PWM_PIN, PWM_FREQ, PWM_RES);
  ledcWrite(PWM_PIN, 4096);        // 50 %
}

void loop() {}
ESPHome
output:
  - platform: ledc
    pin: GPIO4
    id: pwm_out
    frequency: 5kHz

light:
  - platform: monochromatic
    output: pwm_out
    name: "LED"
ESP-IDF
#include "driver/ledc.h"
#include "esp_err.h"

void app_main(void)
{
    ledc_timer_config_t timer = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .duty_resolution = LEDC_TIMER_13_BIT,
        .timer_num = LEDC_TIMER_0,
        .freq_hz = 5000,
        .clk_cfg = LEDC_AUTO_CLK,
    };
    ESP_ERROR_CHECK(ledc_timer_config(&timer));

    ledc_channel_config_t channel = {
        .gpio_num = 4,
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel = LEDC_CHANNEL_0,
        .timer_sel = LEDC_TIMER_0,
        .duty = 4096,              // 50 %
        .hpoint = 0,
    };
    ESP_ERROR_CHECK(ledc_channel_config(&channel));
}

Resolución máxima a las frecuencias más habituales

FrecuenciaResolución
50 Hz20 bits
490 Hz17 bits
1 kHz16 bits
5 kHz13 bits
20 kHz11 bits
25 kHz11 bits
40 kHz10 bits
100 kHz9 bits
1 MHz6 bits

Consejos

Arduino-ESP32 3.x: ledcAttach(pin, freq, resolution) sustituye a ledcSetup() y ledcAttachPin() de la versión 2.x, y ledcWrite() recibe el pin, no el canal.

El ESP32 tiene dos grupos de 8 canales: high-speed, que aplica el nuevo ciclo de trabajo al instante, y low-speed. Arduino-ESP32 usa primero el grupo high-speed.

Cada canal toma la frecuencia de uno de los 8 temporizadores: dos salidas con frecuencias distintas necesitan dos temporizadores.

Para los LED usa al menos 1,25 kHz: la IEEE 1789 considera de bajo riesgo un PWM de todo encendido / todo apagado a partir de 1250 Hz, y para personas sensibles a partir de unos 3 kHz.

Texto listo para pegar en un foro o en una issue.

Por qué la frecuencia y la resolución van unidas

Un periférico PWM cuenta pulsos de reloj: el contador fija el periodo y el valor de comparación decide cuánto tiempo queda encendida la salida. Con n bits de resolución el contador necesita 2^n pulsos de reloj por periodo, así que la frecuencia máxima es el reloj dividido entre 2^n. A 80 MHz, con 8 bits se llega a 312,5 kHz, con 13 bits a 9,77 kHz y con 1 bit a 40 MHz, pero con el ciclo de trabajo fijo en el 50 %.

f(máx) = f(reloj) / 2^bits
f = f(reloj) / (divisor × 2^bits)

El divisor también tiene un tope, así que las frecuencias bajas necesitan más bits, no menos: en un ESP32-S3 con el reloj de 80 MHz, a 50 Hz hacen falta al menos 11 bits.

ESP32: el periférico LEDC

Todos los ESP32 generan el PWM con el periférico LEDC: un divisor con 8 bits fraccionarios, de 1 a unos 1024, y un contador de hasta 20 bits en el ESP32, C5, C6, H2 y P4, y de 14 bits en el S2, S3 y C3. El reloj puede ser el APB de 80 MHz (una salida del PLL en los chips más nuevos, 96 MHz en el H2), el cristal (40 MHz; 32 MHz en el H2, 40 o 48 MHz en el C5), un oscilador RC interno o, en el ESP32 y el S2, el REF_TICK de 1 MHz.

Arduino-ESP32 3.x toma el reloj del PWM del cristal en todos los chips salvo el ESP32 original. Eso baja la frecuencia máxima con cada resolución, a la mitad donde un cristal de 40 MHz sustituye a un reloj de 80 MHz: en un ESP32-S3, a 5 kHz se obtienen 12 bits en lugar de 13. Llamar a ledcSetClockSource(LEDC_AUTO_CLK) antes de ledcAttach() deja que el driver elija el reloj más rápido; la función existe desde Arduino-ESP32 3.0.5. ESPHome usa el reloj APB donde lo hay y elige la resolución por su cuenta.

Raspberry Pi Pico: RP2040 y RP2350

Cada slice PWM tiene un contador de 16 bits que vuelve a cero al pasar de TOP y un divisor de 1 a 255 + 15/16 en pasos de 1/16. La frecuencia es el reloj del sistema dividido entre (TOP + 1) y entre el divisor, y otra vez entre 2 en modo phase-correct. Como TOP puede tomar cualquier valor, la Pico clava casi cualquier frecuencia: a 125 MHz, 25 kHz son TOP 4999 con divisor 1, unos 12,3 bits.

Arduino Uno y Nano: los temporizadores del ATmega328P

Timer0 y Timer2 son de 8 bits y Timer1 de 16 bits, cada uno con una serie fija de prescalers N. La frecuencia sale de N y de TOP: reloj / (N × (TOP + 1)) en fast PWM, reloj / (2 × N × TOP) en phase-correct. analogWrite() los deja con prescaler 64: 976,6 Hz en los pines 5 y 6, 490,2 Hz en los pines 3, 9, 10 y 11. Para otras frecuencias, el Timer1 con TOP en ICR1 conserva los dos pines y hasta 16 bits: una señal de 25 kHz para un ventilador en el pin 9 es ICR1 = 639 sin prescaler.

ESP8266

El ESP8266 no tiene PWM por hardware: el core de Arduino y ESPHome lo generan por software, de 100 Hz a 40 kHz en el core de Arduino, con un rango por defecto de 255. Según la documentación del core, las frecuencias altas mantienen ocupada la CPU.

Qué frecuencia usar en cada caso

UsoFrecuenciaPor qué
Regulación de LED1,25 kHz o másLa IEEE 1789 considera de bajo riesgo de parpadeo un PWM de todo encendido / todo apagado a partir de 1250 Hz
Servo de modelismo50 Hz, pulsos de 1 a 2 msUn pulso cada 20 ms; la duración del pulso fija el ángulo
Ventilador de PC de 4 hilos25 kHz (21–28 kHz)Especificación de Intel para ventiladores PWM de 4 hilos
Motor DCunos 20 kHz o másPor encima del umbral de audición; mira el límite del driver
Zumbador pasivoLa frecuencia de la nota, 50 %La frecuencia es el tono

Valores por defecto de cada plataforma

PlataformaanalogWrite() por defectoResolución máximaReloj del PWM
ESP32 (Arduino-ESP32 3.x)1 kHz, 8 bits20 bitsAPB 80 MHz o REF_TICK 1 MHz (AUTO)
ESP32-S2, S3, C3 (Arduino-ESP32 3.x)1 kHz, 8 bits14 bitsXTAL 40 MHz por defecto
ESP32-C5, C6, P4 (Arduino-ESP32 3.x)1 kHz, 8 bits20 bitsXTAL 40 MHz por defecto (C5: 40 o 48 MHz)
ESP32-H2 (Arduino-ESP32 3.x)1 kHz, 8 bits20 bitsXTAL 32 MHz por defecto
RP2040, RP2350 (Arduino-Pico)1 kHz, rango 25516 bitsReloj del sistema: 200 MHz (Pico), 150 MHz (Pico 2)
ATmega328P (Uno, Nano)490 Hz (pines 3, 9, 10, 11), 976,6 Hz (pines 5, 6), 8 bits16 bits (Timer1)16 MHz con prescaler 64
ESP8266 (core de Arduino 3.x)1 kHz, rango 255Rango de hasta 65535PWM por software

Fuentes: driver LEDC y archivos de capacidades de los SoC de ESP-IDF (release 5.5), esp32-hal-ledc.c y documentación de la API LEDC de Arduino-ESP32 3.x, componentes ledc, rp2040_pwm y esp8266_pwm de ESPHome, hoja de datos del RP2040 y hardware_pwm del pico-sdk, wiring_analog.cpp de Arduino-Pico, hoja de datos de Microchip del ATmega328P y core AVR de Arduino, referencia del core de Arduino para ESP8266, especificación de Intel de ventiladores PWM de 4 hilos, IEEE 1789-2015 según el resumen del Departamento de Energía de EE. UU., biblioteca Servo de Arduino.

Preguntas frecuentes

¿Cuál es la frecuencia PWM máxima del ESP32?

40 MHz, con 1 bit de resolución y el ciclo de trabajo fijo en el 50 %: el reloj de 80 MHz dividido entre 2. Para una regulación útil, con 8 bits se llega a 312,5 kHz y con 10 bits a 78,1 kHz. Con Arduino-ESP32 3.x en chips distintos del ESP32 original, el reloj por defecto del cristal reduce estas cifras (a la mitad en los chips con cristal de 40 MHz y reloj APB o PLL de 80 MHz), salvo que llames a ledcSetClockSource(LEDC_AUTO_CLK), disponible desde la versión 3.0.5.

¿Por qué ledcAttach() falla con «requested frequency and duty resolution can not be achieved»?

Porque el divisor tiene que quedarse entre 1 y unos 1024. Si la frecuencia es demasiado alta para los bits que has pedido, baja la resolución. Si es demasiado baja, sube la resolución: con menos bits hace falta un divisor más grande. La calculadora muestra el rango válido de las dos.

¿Qué frecuencia PWM necesita un ventilador de PC de 4 pines?

25 kHz: la especificación de Intel acepta de 21 a 28 kHz. Un ESP32 a 25 kHz llega a 11 bits con el reloj de 80 MHz; un Arduino Uno saca 25 kHz por el pin 9 con el Timer1 e ICR1 = 639. Controla la línea PWM del ventilador con una salida open-drain o un transistor, porque es el propio ventilador el que la lleva a nivel alto.

¿Cómo muevo un servo con PWM en el ESP32?

A 50 Hz con 14 bits un paso son unos 1,2 µs, suficiente para un servo: 1,5 ms equivalen a 1229, 1 ms a 819 y 2 ms a 1638. En ESPHome, conecta una salida ledc a 50 Hz al componente servo; con Arduino también puedes usar una biblioteca como ESP32Servo.

¿Por qué la frecuencia PWM de los pines 5 y 6 del Arduino Uno es distinta?

Los pines 5 y 6 usan el Timer0 en fast PWM (976,6 Hz) y los demás, el Timer1 y el Timer2 en phase-correct (490,2 Hz). El Timer0 también cuenta millis(), así que cambia su prescaler solo si no te importa que millis() y delay() se desajusten.

¿Qué resolución PWM necesito para los LED?

Con 8 bits (256 pasos) la regulación se nota a saltos con poco brillo, donde el ojo percibe más los cambios pequeños; con 12 bits o más y una curva gamma los fundidos son suaves. Mantén la frecuencia en 1,25 kHz o más para que el parpadeo sea de bajo riesgo.

¿Pueden las dos salidas de un slice PWM de la Pico tener frecuencias distintas?

No: A y B comparten el contador, así que tienen la misma frecuencia y el mismo TOP, y solo puede cambiar el ciclo de trabajo. Si necesitas frecuencias distintas, usa pines de slices distintos.