Aziz Bench

PWM calculator: frequency and resolution

Pick the chip and the frequency you need: see how many bits of duty resolution you get, the exact frequency, the divider or timer values, and the code for Arduino, ESPHome and the SDKs.

Duty resolution
13bits
8,192 steps at 5 kHz
Frequency obtained
5 kHzexact
Smallest step
24.4 ns0.0122 % of the period
Divider
1.953APB clock, 80 MHz
Signal
on 100 µsperiod 200 µs
Chip and software
Software

Arduino-ESP32 3.x clocks the PWM from the crystal on every chip except the original ESP32, which limits the resolution. ESPHome picks the resolution itself.

Signal
Hz

In hertz: 5000 is 5 kHz.

%

Settings and code

Clock and dividerAPB clock at 80 MHz, divider 1.953 (div_param 500), 13 bits: the timer runs at 5 kHz.
Value to write50 % = 4,096 out of 8,192. Write 8,192 for always on, 0 for always off.
Possible rangeAt 5 kHz: from 1 to 13 bits. At 13 bits: from 0.119 Hz to 9.7656 kHz.
Shared settingsThe ESP32 has 16 PWM channels and 8 timers: channels on the same timer share frequency and resolution.

Code

Change the pin to yours: the values match the result above.

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));
}

Highest resolution at common frequencies

FrequencyResolution
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

Tips

Arduino-ESP32 3.x: ledcAttach(pin, freq, resolution) replaces ledcSetup() and ledcAttachPin() of version 2.x, and ledcWrite() takes the pin, not the channel.

The ESP32 has two groups of 8 channels: high-speed, which applies a new duty at once, and low-speed. Arduino-ESP32 fills the high-speed group first.

Each channel takes its frequency from one of the 8 timers: two outputs with different frequencies need two timers.

For LEDs use at least 1.25 kHz: IEEE 1789 rates full on-off PWM as low risk from 1250 Hz, and for sensitive viewers from about 3 kHz.

Text ready to paste in a forum or an issue.

Why frequency and resolution are linked

A PWM peripheral counts clock pulses: the counter sets the period, the compare value sets how long the output stays on. With n bits of resolution the counter needs 2^n clock pulses per period, so the highest frequency is the clock divided by 2^n. At 80 MHz, 8 bits allow up to 312.5 kHz, 13 bits up to 9.77 kHz and 1 bit up to 40 MHz, with the duty stuck at 50 %.

f(max) = f(clock) / 2^bit
f = f(clock) / (divider × 2^bit)

The divider has a top end too, so low frequencies need more bits, not fewer: on an ESP32-S3 with the 80 MHz clock, 50 Hz needs at least 11 bits.

ESP32: the LEDC peripheral

All ESP32 chips make PWM with the LEDC peripheral: a divider with 8 fractional bits, from 1 to about 1024, and a counter of up to 20 bits on the ESP32, C5, C6, H2 and P4, 14 bits on the S2, S3 and C3. The clock can be the 80 MHz APB (a PLL output on the newer chips, 96 MHz on the H2), the crystal (40 MHz; 32 MHz on the H2, 40 or 48 MHz on the C5), an internal RC oscillator or, on the ESP32 and S2, the 1 MHz REF_TICK.

Arduino-ESP32 3.x clocks the PWM from the crystal on every chip except the original ESP32. That lowers the highest frequency at each resolution, by half where a 40 MHz crystal replaces an 80 MHz clock: on an ESP32-S3, 5 kHz gets 12 bits instead of 13. Calling ledcSetClockSource(LEDC_AUTO_CLK) before ledcAttach() lets the driver choose the faster clock; the function exists from Arduino-ESP32 3.0.5. ESPHome uses the APB clock where there is one and picks the resolution itself.

Raspberry Pi Pico: RP2040 and RP2350

Each PWM slice has a 16-bit counter that wraps at TOP and a divider from 1 to 255 + 15/16 in steps of 1/16. The frequency is the system clock divided by (TOP + 1) and by the divider, and by 2 again in phase-correct mode. Since TOP can be any value, the Pico hits most frequencies exactly: at 125 MHz, 25 kHz is TOP 4999 with divider 1, about 12.3 bits.

Arduino Uno and Nano: the ATmega328P timers

Timer0 and Timer2 are 8-bit, Timer1 16-bit, each with a fixed set of prescalers N. The frequency comes from N and TOP: clock / (N × (TOP + 1)) in fast PWM, clock / (2 × N × TOP) in phase-correct mode. analogWrite() leaves them at prescaler 64: 976.6 Hz on pins 5 and 6, 490.2 Hz on 3, 9, 10 and 11. For other frequencies, Timer1 with TOP in ICR1 keeps both pins and up to 16 bits: a 25 kHz fan signal on pin 9 is ICR1 = 639 with no prescaler.

ESP8266

The ESP8266 has no PWM hardware: the Arduino core and ESPHome make it in software, from 100 Hz to 40 kHz in the Arduino core, with a range of 255 by default. High frequencies keep the CPU busy, according to the core documentation.

Which frequency for what

UseFrequencyWhy
LED dimming1.25 kHz or moreIEEE 1789 rates full on-off PWM as low-risk flicker from 1250 Hz
Hobby servo50 Hz, pulses of 1–2 msOne pulse every 20 ms; the pulse width sets the angle
4-wire PC fan25 kHz (21–28 kHz)Intel 4-wire PWM fan specification
DC motorabout 20 kHz or moreAbove the range of hearing; check the driver’s limit
Passive buzzerThe note’s frequency, 50 %The frequency is the pitch

Defaults of each platform

PlatformanalogWrite() by defaultHighest resolutionPWM clock
ESP32 (Arduino-ESP32 3.x)1 kHz, 8 bits20 bitsAPB 80 MHz or REF_TICK 1 MHz (AUTO)
ESP32-S2, S3, C3 (Arduino-ESP32 3.x)1 kHz, 8 bits14 bitsXTAL 40 MHz by default
ESP32-C5, C6, P4 (Arduino-ESP32 3.x)1 kHz, 8 bits20 bitsXTAL 40 MHz by default (C5: 40 or 48 MHz)
ESP32-H2 (Arduino-ESP32 3.x)1 kHz, 8 bits20 bitsXTAL 32 MHz by default
RP2040, RP2350 (Arduino-Pico)1 kHz, range 25516 bitsSystem clock: 200 MHz (Pico), 150 MHz (Pico 2)
ATmega328P (Uno, Nano)490 Hz (pins 3, 9, 10, 11), 976.6 Hz (pins 5, 6), 8 bits16 bits (Timer1)16 MHz with prescaler 64
ESP8266 (Arduino core 3.x)1 kHz, range 255Range up to 65535Software PWM

Sources: ESP-IDF LEDC driver and SoC capability files (release 5.5), Arduino-ESP32 3.x esp32-hal-ledc.c and LEDC API documentation, ESPHome ledc, rp2040_pwm and esp8266_pwm components, RP2040 datasheet and pico-sdk hardware_pwm, Arduino-Pico wiring_analog.cpp, Microchip ATmega328P datasheet and the Arduino AVR core, ESP8266 Arduino core reference, Intel 4-wire PWM fan specification, IEEE 1789-2015 as summarised by the US Department of Energy, Arduino Servo library.

Frequently asked questions

What is the highest PWM frequency on the ESP32?

40 MHz, with 1 bit of resolution and a fixed 50 % duty: the 80 MHz clock divided by 2. For usable dimming, 8 bits allow up to 312.5 kHz and 10 bits up to 78.1 kHz. With Arduino-ESP32 3.x on chips other than the original ESP32, the default crystal clock lowers these figures (to half on chips with a 40 MHz crystal and an 80 MHz APB or PLL clock) unless you call ledcSetClockSource(LEDC_AUTO_CLK), available from version 3.0.5.

Why does ledcAttach() fail with “requested frequency and duty resolution can not be achieved”?

Because the divider must stay between 1 and about 1024. If the frequency is too high for the bits you asked, lower the resolution. If it is too low, raise the resolution: fewer bits need a larger divider. The calculator shows the valid range for both.

Which PWM frequency for a 4-pin PC fan?

25 kHz: the Intel specification accepts 21 to 28 kHz. An ESP32 gets up to 11 bits at 25 kHz with the 80 MHz clock; an Arduino Uno gets 25 kHz on pin 9 with Timer1 and ICR1 = 639. Drive the fan’s PWM line with an open-drain output or a transistor, because the fan pulls it up itself.

How do I drive a servo with PWM on an ESP32?

At 50 Hz with 14 bits one step is about 1.2 µs, fine enough for a servo: 1.5 ms is 1229, 1 ms is 819 and 2 ms is 1638. In ESPHome, connect a ledc output at 50 Hz to the servo component; with Arduino you can also use a servo library such as ESP32Servo.

Why is the PWM frequency on pins 5 and 6 of the Arduino Uno different?

Pins 5 and 6 use Timer0 in fast PWM (976.6 Hz), the others Timer1 and Timer2 in phase-correct mode (490.2 Hz). Timer0 also counts millis(), so change its prescaler only if you can live with a wrong millis() and delay().

What PWM resolution do I need for LEDs?

8 bits (256 steps) look coarse at low brightness, where the eye notices small changes most; 12 bits or more give smooth fades with a gamma curve. Keep the frequency at 1.25 kHz or more for low flicker.

Can the two outputs of a Pico PWM slice have different frequencies?

No: A and B share the counter, so they share frequency and TOP and only the duty can differ. Use pins on different slices when you need different frequencies.