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
| Use | Frequency | Why |
|---|---|---|
| LED dimming | 1.25 kHz or more | IEEE 1789 rates full on-off PWM as low-risk flicker from 1250 Hz |
| Hobby servo | 50 Hz, pulses of 1–2 ms | One pulse every 20 ms; the pulse width sets the angle |
| 4-wire PC fan | 25 kHz (21–28 kHz) | Intel 4-wire PWM fan specification |
| DC motor | about 20 kHz or more | Above the range of hearing; check the driver’s limit |
| Passive buzzer | The note’s frequency, 50 % | The frequency is the pitch |
Defaults of each platform
| Platform | analogWrite() by default | Highest resolution | PWM clock |
|---|---|---|---|
| ESP32 (Arduino-ESP32 3.x) | 1 kHz, 8 bits | 20 bits | APB 80 MHz or REF_TICK 1 MHz (AUTO) |
| ESP32-S2, S3, C3 (Arduino-ESP32 3.x) | 1 kHz, 8 bits | 14 bits | XTAL 40 MHz by default |
| ESP32-C5, C6, P4 (Arduino-ESP32 3.x) | 1 kHz, 8 bits | 20 bits | XTAL 40 MHz by default (C5: 40 or 48 MHz) |
| ESP32-H2 (Arduino-ESP32 3.x) | 1 kHz, 8 bits | 20 bits | XTAL 32 MHz by default |
| RP2040, RP2350 (Arduino-Pico) | 1 kHz, range 255 | 16 bits | System 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 bits | 16 bits (Timer1) | 16 MHz with prescaler 64 |
| ESP8266 (Arduino core 3.x) | 1 kHz, range 255 | Range up to 65535 | Software 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.