PWM (Pulse Width Modulation) control is a technique where a microcontroller rapidly switches a digital output pin between HIGH and LOW states to simulate a variable analog voltage. Instead of lowering the actual voltage peak, PWM control changes the ratio of on-time to off-time, altering the average power delivered to a load while the instantaneous voltage remains at the supply rail.

What this changes in a real circuit is profound: it allows a 3.3V or 5V digital logic pin to dim a 12V light or control the speed of a 24V motor without wasting massive amounts of energy as heat. However, because the voltage is rapidly toggling between zero and the maximum supply, it behaves very differently than a true analog signal, leading to a host of common misconceptions among beginners.

The Core Mechanism: Duty Cycle and Frequency

To master PWM control, you must understand its two independent variables: duty cycle and frequency.

Duty Cycle is the percentage of one period that the signal remains HIGH. A 50% duty cycle means the pin is on for exactly as long as it is off. A 10% duty cycle means it is on for a brief fraction of the time, delivering very little average power.

Frequency is how many of these on/off cycles occur per second, measured in Hertz (Hz). The frequency dictates how "smooth" the power delivery feels to the load. If the frequency is too low, an LED will visibly flicker, and a motor will stutter. If it is high enough, the load's inherent inductance or thermal mass averages the pulses into a smooth response.

Standard Arduino UNO PWM Frequency: 490 Hz on most digital pins, but 980 Hz on pins 5 and 6 due to internal timer prescaler configurations.

Think of a digital water valve that only has two physical states: fully open or fully closed. If you snap it open for half a second, then closed for half a second, repeating endlessly, a bucket placed underneath fills at exactly half the speed of leaving it open constantly. The water pressure (voltage) never drops; only the average flow (current and power) changes. This is the fundamental physics behind PWM control.

Worked Example: Dimming a 12V, 5A LED Strip via ESP32

Let’s look at a real-world bench scenario. You want to dim a 12V LED strip that draws 5A at full brightness using an ESP32. The ESP32 GPIO pins output 3.3V and can only source about 40mA—far too weak to drive the strip directly. We use a logic-level MOSFET like the IRLZ44N, which fully turns on with a 3.3V gate signal.

We configure the ESP32's LEDC (LED Control) peripheral for an 8-bit resolution (values 0 to 255) and a frequency of 5,000 Hz (5kHz).

Suppose we write a duty cycle value of 64 to the pin. Here is the exact math of what happens in the circuit:

  • Duty Cycle Percentage: 64 / 255 = 0.25 (25%)
  • Average Voltage: 12V × 0.25 = 3.0V
  • Average Current: 5A × 0.25 = 1.25A
  • Average Power: 3.0V × 1.25A = 3.75W (instead of the full 60W)
Component Sizing Trap: Even though the average current is 1.25A, the MOSFET and the wires must be sized for the peak current. During the "on" portion of the pulse, the full 5A is flowing. If you use a tiny 22 AWG jumper wire rated for 1.5A, it will overheat and melt, regardless of the 25% duty cycle. Always size your conductors and switches for the peak load current.

For more details on configuring the ESP32's specific hardware timers for this task, refer to the official Espressif LEDC API documentation.

Where You Meet PWM Control in Practice

You will encounter PWM control across almost every sub-discipline of embedded electronics and power systems:

  • LED Dimming: Reducing analog voltage to an LED shifts its color temperature and can cause it to drop out of regulation entirely. PWM dims the light by turning it fully on and off, preserving the exact color spectrum while reducing perceived brightness.
  • DC Motor Speed Control: Motor driver ICs (like the TB6612FNG or L298N) use PWM to control speed. The motor's internal inductance smooths the current pulses, resulting in proportional torque and speed.
  • RC Servo Positioning: Standard hobby servos use a very specific, low-frequency PWM control signal: 50 Hz (a 20ms period). The width of the HIGH pulse dictates the angle: 1ms pulse = 0°, 1.5ms = 90°, and 2ms = 180°. This translates to a duty cycle of just 5% to 10%.
  • Switching Power Supplies: Buck and boost converters use high-frequency PWM (often 500kHz to 2MHz) internally to chop input voltage, passing it through an inductor and capacitor to create a smooth, stepped-down DC output.

PWM Control vs. Linear Analog Regulation

The most common point of confusion for beginners is assuming PWM control "steps down" voltage the same way a linear regulator (like an LM317) or a series resistor does. It does not. Understanding this distinction is critical for thermal management and circuit design.

Criteria PWM Control (Switching) Linear Analog Regulation
Voltage Profile at Load Square wave (swings 0V to Vcc) Constant, smooth DC (Vcc minus drop)
Efficiency >95% (only switching losses) Poor (efficiency = Vout / Vin)
Heat Dissipation Minimal (switch gets slightly warm) High (burns excess voltage as heat)
Audible Noise Can cause coil whine if < 1kHz Completely silent
Best Used For Motors, LEDs, heaters, SMPS Sensitive analog sensors, audio amps

If you apply a 50% duty cycle PWM signal to a raw 12V DC motor, it runs at roughly half speed efficiently. If you try to achieve the same result by putting a massive resistor in series to drop the voltage to 6V, that resistor will dissipate 30W of heat and require a massive heatsink. For a deeper look at how these topologies compare in power design, SparkFun's PWM tutorial provides excellent oscilloscope captures showing the difference.

Frequently Asked Questions

Why does my PWM-controlled motor whine at low speeds?

This is caused by magnetostriction and physical vibration of the copper windings inside the motor. When the PWM frequency falls within the human hearing range (20 Hz to 20,000 Hz), the rapid magnetic expansion and contraction of the motor coils create an audible whine. To fix this, increase your microcontroller's PWM frequency above 20 kHz (e.g., 25,000 Hz). The motor will still respond to the duty cycle, but the switching will be ultrasonic and silent to human ears.

Can I use PWM control to directly power a Raspberry Pi or sensitive logic?

No. Digital logic chips and microprocessors require a clean, constant DC voltage (e.g., a steady 5.0V or 3.3V). Feeding a square wave into the VCC pin of a Raspberry Pi will cause immediate brownouts, system crashes, and potentially destroy the silicon due to voltage spikes and capacitor inrush currents. If you need to step down a voltage for logic, use a buck converter, which uses PWM internally but filters it through an inductor and capacitor to output smooth DC.

What is the difference between analogWrite() and a true DAC on an ESP32?

On an Arduino, analogWrite() is a misnomer; it actually outputs a PWM square wave, not a true analog voltage. The ESP32, however, features two true Digital-to-Analog Converter (DAC) pins (GPIO 25 and GPIO 26 on the original WROOM module). A true DAC outputs a steady, smooth DC voltage (0 to 3.3V) without any switching or ripple. Use PWM for power delivery (LEDs, motors) and the true DAC for generating audio waveforms or providing precise reference voltages to analog sensors.

How do I accurately measure PWM voltage with a multimeter?

Standard digital multimeters (DMMs) are designed to measure steady DC or sinusoidal AC. When you probe a PWM pin, a cheap DMM will often display erratic, fluctuating numbers because its internal sampling rate conflicts with the PWM frequency. To measure it properly, you need an oscilloscope to see the peak voltage and duty cycle. If you only have a DMM, look for one with a specific "Duty Cycle" or "Frequency" measurement mode, or place a low-pass RC filter (a resistor and capacitor) on the probe tip to average the signal into a readable DC voltage before it hits the meter.