PWM Calculator
Calculate PWM period, on/off times, and average voltage from frequency and duty cycle — or find the duty cycle needed to achieve a target average voltage.
PWM Parameters
Results
Vavg = Vpeak × D/100
Common PWM Frequencies by Application
| Application | Typical Frequency |
|---|---|
| DC motor speed control | 1–20 kHz |
| Servo motor control | 50 Hz |
| LED dimming | 100 Hz – 20 kHz |
| Switching power supply | 20 kHz – 2 MHz |
| Class D audio amplifier | 40 – 400 kHz |
| Piezo buzzer tone | 1 – 20 kHz |
How PWM Works
Pulse-Width Modulation (PWM) is a technique for encoding analog information in a digital signal by varying the fraction of time the signal is high (the duty cycle). The average voltage seen by the load equals the peak voltage multiplied by the duty cycle.
A low-pass filter on the output converts the PWM waveform to a true DC analog voltage equal to Vavg. Without a filter, the load itself may integrate the switching (e.g., a motor's inductance or an LED's phosphor persistence).
Average Voltage
Vavg = Vpeak × D / 100Period and Timing
T = 1 / f | tON = T × D/100Key Points
- Higher frequency: smoother output but higher switching losses
- D = 0% = always off; D = 100% = always on
- Motor control: higher frequency reduces audible noise (>20 kHz)
- Servos use 50 Hz with 1–2 ms pulse width to encode angle
- LED dimming: >100 Hz prevents visible flicker
- PWM resolution: an N-bit timer gives 2ᴺ steps of duty cycle
Applications
- Motor speed and direction control
- LED brightness dimming
- Servo position control
- Switching power supply duty cycle
- DAC via RC low-pass filter
PWM Formulas
D = t_on / T = t_on × f | Vavg = D × Vhigh + (1–D) × VlowFor Vlow=0: Vavg = D × Vcc | f = 1/T | T = t_on + t_offResolution: n bits → 2ⁿ steps, step size = Vcc/2ⁿArduino 8-bit: f = F_CPU / (prescaler × 256)Arduino PWM Reference
| Timer | Pins | Default freq | Prescaler options | Notes |
|---|---|---|---|---|
| Timer0 | D5, D6 | 976 Hz | 1,8,64,256,1024 | millis() uses this |
| Timer1 | D9, D10 | 490 Hz | 1,8,64,256,1024 | 16-bit timer |
| Timer2 | D3, D11 | 490 Hz | 1,8,32,64,128,256 | tone() uses this |
| ESP32 | Any GPIO | 1Hz–40MHz | configurable | LEDC peripheral |
| RP2040 | Any GPIO | 1Hz–62.5MHz | configurable | Flexible PWM |
Practical Examples
DC motor speed control (Arduino, D9)
analogWrite(9, 128): D = 128/255 = 50.2%, Vavg = 0.502×12V = 6.02V → ~50% speed
Frequency = 490Hz. For smoother motor control, increase to 20kHz (above audible).
LED dimming at 1kHz (ESP32)
ledcSetup(0, 1000, 8): 1kHz, 8-bit → 256 steps
ledcWrite(0, 64): D = 64/256 = 25% → LED at 25% brightness
At 1kHz: no visible flicker (human eye flicker threshold ~60Hz)
Design Tip
For motor control, use f > 20kHz to avoid audible whine. For LED dimming: f > 200Hz is sufficient (100Hz minimum to avoid flicker on camera). High-frequency PWM increases switching losses in MOSFETs (P_sw = ½×Vds×Id×(tr+tf)×f). RC low-pass filter converts PWM to analog: τ = RC >> 1/f for smooth DAC output.
Did you know? PWM dimming of LEDs is preferred over analog current reduction because LED colour temperature shifts at lower currents. By switching the LED fully on and off rapidly (>100 Hz), PWM maintains consistent colour while varying average brightness — the technique used in all quality LED dimmers.