Pulse Width Modulation (PWM) is a technique that controls the average power delivered to a load by rapidly switching a digital signal on and off and varying the ratio of on-time to the total cycle time. Instead of dropping excess voltage as wasted heat through a linear resistor, a microcontroller uses PWM to simulate an analog voltage. What it changes in a real circuit is the effective voltage and power delivered to the load, allowing you to dim an LED to 20% brightness or run a DC motor at half speed while maintaining high electrical efficiency.
The Core Mechanism: Duty Cycle, Frequency, and Average Voltage
To understand PWM, you have to separate the concept into two distinct variables: duty cycle and frequency. The duty cycle is the percentage of one cycle where the signal is "ON" (high voltage). The frequency is how many of those complete on/off cycles occur per second, measured in Hertz (Hz).
Let's look at a worked numeric example. Suppose your ESP32 outputs a 3.3V digital logic signal. If you configure a 50% duty cycle, the pin outputs 3.3V for half the time and 0V for the other half. Because the switching happens thousands of times per second, the load averages this out. The effective voltage is calculated as:
V_avg = V_peak × Duty Cycle
V_avg = 3.3V × 0.50 = 1.65V
If you push the duty cycle to 80%, the average voltage becomes 3.3V × 0.80 = 2.64V. The microcontroller isn't actually outputting 2.64V; it is slamming the gate between 0V and 3.3V so fast that the downstream circuit only "feels" 2.64V.
Where You Meet PWM in Practice
You will encounter PWM across almost every embedded systems project, but the required frequency changes drastically depending on the load:
- LED Dimming: Typically uses 1kHz to 5kHz. This is fast enough to prevent visible flicker to the human eye, but slow enough to avoid excessive switching losses in the driver transistor.
- DC Motor Speed Control: Usually set between 1kHz and 20kHz. If you drop below 50Hz, the motor will audibly hum and stutter as it physically stops and starts. If you push past 30kHz, the MOSFET switching losses spike, generating excess heat.
- Servo Motors: A highly specific, low-frequency PWM (50Hz, meaning a 20ms period). Here, the absolute width of the pulse (usually 1ms to 2ms) dictates the physical shaft angle, not the average voltage.
- Switch-Mode Power Supplies (Buck/Boost): Dedicated ICs use high-frequency PWM (100kHz to 2MHz) to drive power transistors, storing energy in inductors to step voltages up or down with >90% efficiency.
Worked Scenario: Driving a 12V Fan with an ESP32 (And Why It Failed)
Theory is clean; the workbench is not. Here is a classic real-world scenario that burns out components for beginners.
- The Setup: You want to control a 12V, 0.5A PC cooling fan using an ESP32 DevKit v1. You wire ESP32 GPIO 25 to the gate of an IRLZ44N N-channel MOSFET, connect the fan between the 12V supply and the MOSFET drain, and tie the grounds together.
- The Numbers: You write a script outputting a 25kHz PWM signal at a 40% duty cycle, expecting the fan to run quietly at a low speed.
- The Outcome: The fan spins up but emits an audible, annoying whine. Worse, after three minutes, the IRLZ44N MOSFET is too hot to touch and eventually fails short, sending 12V straight to the fan.
- What Went Wrong: The ESP32 outputs 3.3V logic. While the IRLZ44N starts to turn on at a Gate-Source threshold voltage (Vgs) of 1V to 2V, its on-resistance (Rds(on)) isn't fully minimized until Vgs reaches 5V or 10V. At 3.3V, the MOSFET is stuck in its linear (ohmic) region, acting like a 10-ohm resistor rather than a closed switch. It dissipates massive heat (I²R) and the 25kHz switching frequency causes the gate capacitance to partially charge and discharge, creating the audible whine.
PWM vs. True Analog: What People Commonly Confuse
Builders frequently confuse PWM with a true analog signal generated by a Digital-to-Analog Converter (DAC). A DAC outputs a steady, continuous DC voltage. If you measure a 1.65V DAC output with a multimeter, it reads exactly 1.65V DC. If you measure a 50% duty cycle 3.3V PWM signal with a standard multimeter, the meter's internal averaging might also display 1.65V.
However, if you hook that PWM signal to an oscilloscope, you won't see a flat line; you will see a square wave slamming between 0V and 3.3V. This distinction matters immensely when interfacing with sensitive analog circuitry. If you feed a raw PWM signal directly into an analog audio amplifier input, you won't get a clean tone; you'll get a harsh, buzzing square wave rich in high-frequency harmonics. To convert PWM into a true analog voltage, you must pass it through a low-pass RC (resistor-capacitor) filter to smooth the square wave edges into a flat DC level. You can read more about signal filtering in this comprehensive guide to PWM theory by All About Circuits.
Configuring PWM on the ESP32: A Numbered Setup Guide
The ESP32 handles PWM via its LEDC (LED Control) peripheral. Note that the ESP32 Arduino Core underwent a major API shift in version 3.x. The old method of assigning "channels" is deprecated. Here is the modern, hardware-agnostic setup for 2026 development environments:
// ESP32 Arduino Core v3.x PWM Setup
const int fanPin = 25;
const int pwmFreq = 25000; // 25kHz to avoid audible motor whine
const int pwmResolution = 8; // 8-bit resolution (0-255)
void setup() {
// Step 1: Attach the pin to the LEDC peripheral with frequency and resolution
ledcAttach(fanPin, pwmFreq, pwmResolution);
// Step 2: Set initial duty cycle to 0% (Fan off)
ledcWrite(fanPin, 0);
}
void loop() {
// Step 3: Ramp up to 40% duty cycle
// 40% of 255 = 102
ledcWrite(fanPin, 102);
delay(5000);
// Step 4: Ramp up to 100% duty cycle
ledcWrite(fanPin, 255);
delay(5000);
}
For deeper technical details on the ESP32's LEDC hardware peripheral and resolution limits, refer to the official Espressif Arduino ESP32 LEDC API documentation.
Frequently Asked Questions
Can I use DC PWM to control an AC induction motor?
No. Feeding a chopped DC PWM signal into an AC motor will cause severe overheating and mechanical vibration, eventually destroying the motor windings. AC speed control requires a Variable Frequency Drive (VFD) that alters both the frequency and the RMS voltage of the AC sine wave simultaneously.
Why does my LED strip flicker on camera when using PWM?
Camera shutters roll at specific intervals. If your PWM frequency (e.g., 500Hz) beats against the camera's frame rate (e.g., 60fps), you get visual banding and flicker. Push your PWM frequency above 10kHz to eliminate camera flicker entirely, a technique heavily used in modern film-production LED panels.
Does PWM waste power like a potentiometer does?
No. A potentiometer drops excess voltage by converting it to heat (wasted power). A MOSFET switching a PWM signal is either fully ON (near-zero resistance) or fully OFF (near-infinite resistance). Because it spends almost no time in the middle "linear" region, it wastes very little energy, making PWM highly efficient for battery-powered embedded projects.






