Pulse Width Modulation (PWM) is a technique that uses rapid digital on/off switching to simulate an analog voltage level by varying the ratio of on-time to off-time. Microcontrollers like the ESP32, Arduino Uno, or Raspberry Pi Pico operate strictly in the digital domain—their GPIO pins output either a solid HIGH (e.g., 3.3V or 5V) or a solid LOW (0V). They cannot natively output 2.1V to dim an LED or run a DC motor at half speed. PWM solves this by chopping the digital signal into high-frequency pulses, relying on the electrical or mechanical inertia of the load to average out the energy delivery.

The Core Mechanics: Duty Cycle, Frequency, and Hardware Specs

To understand PWM, you must separate the signal into two distinct parameters: duty cycle and frequency. The duty cycle is the percentage of one period that the signal remains HIGH. A 50% duty cycle means the pin is HIGH for exactly half the time and LOW for the other half. Frequency, measured in Hertz (Hz), dictates how many of these on/off cycles occur per second.

The Flashlight Analogy: If you turn a flashlight on and off once per second (1 Hz), you clearly see it blinking. If you toggle the switch 1,000 times per second (1 kHz), your eye's persistence of vision blends the flashes into a steady, dimmer beam. The bulb is still receiving full battery voltage during the 'on' pulses, but your eye averages the light output.

Different microcontroller architectures handle PWM generation via distinct hardware peripherals, which heavily dictates your maximum resolution and frequency limits. Below is a specification matrix for common maker boards.

Microcontroller Board PWM Peripheral Default/Base Frequency Max Resolution Logic Level
Arduino Uno (ATmega328P) 8-bit Timers (0, 1, 2) 490 Hz (980 Hz on pins 5/6) 8-bit (0-255) 5.0V
ESP32 DevKit V1 LEDC (LED Control) 5,000 Hz (configurable) Up to 16-bit (0-65535) 3.3V
Raspberry Pi Pico (RP2040) Hardware PWM Slices 125 MHz base clock (divided) 16-bit (0-65535) 3.3V
Arduino Nano Every (ATmega4809) Timer/Counter Type A/B 490 Hz (configurable via TCA) 8-bit to 16-bit 5.0V

When programming these boards, you interact with these hardware limits. For instance, the Arduino analogWrite() function abstracts the 8-bit timer limits, accepting values from 0 to 255. Conversely, the ESP32 LEDC API requires you to explicitly configure the timer bit-depth and frequency before attaching a channel to a GPIO pin.

Worked Numeric Example: The Peak vs. RMS Current Trap

The most common point of failure in DIY PWM circuits is sizing wires and switching components based on average current rather than peak or RMS current. Let us walk through a real-world scenario.

The Scenario: You are driving a 12V, 5-meter LED strip that draws 2.0 Amps at full brightness. You want to dim it to 75% brightness using an Arduino Uno and an IRLZ44N logic-level MOSFET.

  • Target Average Voltage: 12V × 0.75 = 9.0V
  • Required Duty Cycle: 75% (191 out of 255 on an 8-bit Arduino)
  • Average Current: 2.0A × 0.75 = 1.5A
Critical Mistake: Many hobbyists see the 1.5A average current and select 22 AWG jumper wires and a small TO-92 transistor, assuming the circuit will only experience 1.5A of load.

The Reality: During the 75% of the time the MOSFET is switched ON, the full 12V is applied across the strip, and it draws the full 2.0A peak current. During the OFF time, it draws 0A. Wire heating and component thermal limits are governed by RMS (Root Mean Square) current, not average current.

RMS Current Calculation:
I_rms = I_peak × √(Duty Cycle)
I_rms = 2.0A × √(0.75) = 2.0A × 0.866 = 1.732A

Your wiring and MOSFET must be rated to handle 1.732A continuously without overheating, and must survive the 2.0A peak spikes without voltage sag or inductive kickback damage. Always size your trace widths, jumper wires, and flyback diodes for the peak current of the load, regardless of how low you set the PWM duty cycle.

Where You Meet PWM in Practice (And What It Actually Changes)

PWM fundamentally changes the average energy delivered over time, not the instantaneous voltage. The load still sees the full supply voltage in chopped packets. Here is where this distinction matters on the workbench:

1. DC Motor Speed Control

When driving a DC motor via an H-bridge (like the DRV8871) or a brushed ESC, PWM controls speed. The mechanical inertia of the motor's rotor acts as a low-pass filter, smoothing the electrical pulses into continuous rotational force. If the PWM frequency is too low (e.g., 50 Hz), the motor will cog, vibrate, and emit an audible whine. Pushing the frequency above 20 kHz moves the switching noise out of the human hearing range.

2. RC Servo Positioning

Standard hobby servos (like the SG90 or MG996R) do not use PWM for power delivery; they use it for data encoding. They expect a 50 Hz signal (a pulse every 20 ms). The width of the HIGH pulse—strictly between 1,000 µs and 2,000 µs—dictates the absolute angular position of the output shaft. A 1,500 µs pulse centers the servo at 90 degrees.

3. High-Channel LED Dimming

When driving dozens of LEDs, microcontrollers run out of hardware PWM pins. Drivers like the TLC5940 use a single PWM input to generate a grayscale clock, multiplexing the duty cycle data across 16 constant-current sink channels via SPI, ensuring uniform brightness without taxing the MCU's internal timers.

Common Confusions: PWM vs. Linear Voltage and True Analog

Understanding what PWM is not is just as critical as understanding what it is. Beginners frequently conflate PWM with other voltage-reduction techniques.

Characteristic PWM (Switching) Linear Regulation (LDO/Resistor) True DAC (Analog)
Output Waveform Square wave (0V to Vcc) Flat DC line (e.g., steady 3.3V) Smooth, continuous variable DC
Power Efficiency Very High (>90%) Very Low (burns excess as heat) High (if using switching DAC)
Heat Generation Minimal (MOSFET is fully on/off) High (P = (Vin-Vout) × I) Minimal
Multimeter Reading Reads Average DC Voltage Reads Exact DC Voltage Reads Exact DC Voltage

The Multimeter Illusion: If you set your digital multimeter (DMM) to DC Voltage and probe a 5V PWM pin running at 50% duty cycle, the meter will display ~2.5V. This tricks many makers into believing the pin is outputting a steady 2.5V analog signal. It is not. The DMM's internal sampling rate is simply too slow to catch the high-frequency switching, so it mathematically averages the input. To see the true square wave, you must use an oscilloscope or a logic analyzer.

The Linear Heat Trap: If you need to drop 12V down to 6V to run a 1A motor, using a linear resistor or LDO regulator will dissipate 6 Watts of heat ((12V - 6V) × 1A = 6W). Using a 50% PWM signal through a MOSFET delivers the same average power to the motor, but the MOSFET dissipates almost zero heat because it spends its time either fully conducting (low resistance) or fully blocked (zero current).

Frequently Asked Questions

Why does my PWM-controlled motor emit a high-pitched whine?
This is caused by magnetostriction in the motor's magnetic core and physical vibration of the windings. If your PWM frequency is between 20 Hz and 16,000 Hz, it falls within human hearing. To silence it, reconfigure your microcontroller's timer prescalers to push the PWM frequency above 20 kHz (e.g., 22 kHz or 25 kHz).

Can I use PWM to power a sensitive analog sensor?
No. While you can pass a PWM signal through an RC (resistor-capacitor) low-pass filter to smooth it into a true DC voltage, the resulting signal will have residual ripple and a slow response time. For sensitive analog references, use a dedicated DAC (Digital-to-Analog Converter) like the MCP4725 over I2C.

Do I need a flyback diode for PWM LED strips?
Generally, no. LEDs are solid-state devices and do not generate inductive kickback. However, if your PWM circuit drives a relay coil, a solenoid, or a DC motor, you must place a flyback diode (like a 1N4007) in reverse parallel across the load to protect your switching MOSFET from voltage spikes when the PWM signal turns off.