If you need to convert a digital PWM signal from a microcontroller into a smooth analog DC voltage, a simple resistor capacitor circuit configured as a low-pass filter (LPF) is your fastest, cheapest solution. For a standard 5kHz PWM signal driving a high-impedance load, use a 10kΩ resistor and a 100nF C0G/NP0 capacitor. This yields a cutoff frequency of roughly 159Hz, reducing 5V PWM ripple to under 50mV while maintaining a reasonable step-response time.

Below is the complete design framework, from topology mapping and failure analysis to picking exact off-the-shelf part numbers and verifying the output on your bench.

Topology Map: Nodes and Signal Flow

The RC low-pass filter relies on a series impedance and a shunt reactance. Here is the exact node map for the standard first-order topology:

  • Node A (Input): The raw PWM signal source (e.g., ESP32 GPIO pin).
  • Node B (Junction/Output): The connection point between the resistor and the capacitor. This is where you measure your smoothed DC voltage.
  • Node C (Ground): The common ground shared by the microcontroller, the capacitor, and your measurement equipment.

The signal flows from Node A, through Resistor R1, to Node B. Capacitor C1 connects between Node B and Node C. The resistor limits the current charging the capacitor, while the capacitor integrates the charge, effectively averaging the high-frequency PWM pulses into a steady DC level proportional to the duty cycle.

Why Passive RC Over Active or LC Alternatives?

You might wonder why we don't just use an inductor-capacitor (LC) filter or an active op-amp filter. The choice comes down to cost, board space, and load requirements.

TopologyProsConsBest Use Case
Passive RCCheap ($0.02), tiny footprint, no EMI, no power rails neededOutput impedance equals R (causes voltage droop under load), slow settling timeHigh-impedance loads (>100kΩ), DAC smoothing, LED dimming control
Active (Op-Amp)Near-zero output impedance, steep roll-off (2nd order+), no load droopRequires dual/split rails or rail-to-rail op-amp, higher BOM cost, needs PCB layout careDriving low-impedance loads, precision motor control, audio
Passive LCLow DC resistance (no voltage droop), high current capabilityInductors are bulky, expensive, and radiate EMI; resonance ringing risksHigh-current buck converter outputs, power supply filtering
Bench Rule: If your next stage is an ADC input or an op-amp buffer (input impedance >1MΩ), stick to the passive RC. If you are driving a 50Ω transmission line or a low-impedance motor driver directly, the passive RC will fail due to voltage divider droop. Switch to an active buffer.

Component Behavior and Failure Extremes

Understanding how component drift or catastrophic failure affects the circuit is critical for troubleshooting. Here is how the circuit behaves when parameters shift, followed by what happens at the absolute extremes.

Parameter Shift Behavior

ChangeEffect on Cutoff Frequency ($f_c$)Effect on Output RippleEffect on Step Response (Rise Time)
Increase RDecreasesDecreases (smoother DC)Slower (takes longer to reach target voltage)
Decrease RIncreasesIncreases (more PWM bleed-through)Faster
Increase CDecreasesDecreases (smoother DC)Slower
Decrease CIncreasesIncreases (more PWM bleed-through)Faster

Failure Extremes (What Breaks)

  • R1 Shorted: Cutoff frequency approaches infinity. The filter is bypassed entirely. Node B sees raw, unfiltered 5V/0V PWM square waves. No DC smoothing occurs.
  • R1 Open: The signal path is broken. Node B floats. If measured with a high-impedance multimeter, it will read 0V or pick up ambient 50/60Hz mains noise. No signal passes.
  • C1 Shorted: Node B is hard-grounded to Node C. The output is pinned at 0V regardless of the PWM duty cycle. The microcontroller GPIO pin may overheat or trigger overcurrent protection if it lacks a series current limit.
  • C1 Open: The shunt path to ground is removed. Cutoff frequency approaches infinity. Node B passes the raw PWM signal, minus any DC offset shifts caused by the missing capacitor charge storage.

Design Walkthrough: Sizing R and C for 5kHz PWM

Let's design a filter for an ESP32 outputting a 5kHz PWM signal (0-3.3V logic) that we want to smooth into a clean DC voltage for a data-logger analog input.

The governing equation for the -3dB cutoff frequency of a simple resistor capacitor circuit is:

f_c = 1 / (2 * π * R * C)

Step 1: Pick the Cutoff Frequency
A good rule of thumb for PWM smoothing is to set $f_c$ to at least 1/10th of the PWM frequency to achieve acceptable ripple attenuation. For a 5kHz PWM, we want $f_c \approx 500\text{Hz}$. Let's target 160Hz for even cleaner DC, accepting a slightly slower settling time.

Step 2: Pick the Resistor (R)
We need an R value high enough to keep the capacitor size physically small, but low enough to avoid excessive thermal noise and susceptibility to PCB leakage currents. 10kΩ is the industry sweet spot for signal-level filtering.

Step 3: Calculate the Capacitor (C)
Rearranging the formula: C = 1 / (2 * π * R * f_c)
C = 1 / (2 * 3.14159 * 10,000 * 160) = 9.94 * 10^{-8} Farads
This rounds perfectly to 100nF (0.1µF).

The Dielectric Trap (X7R vs C0G): Do not just grab any 100nF capacitor. Standard X7R MLCCs exhibit severe voltage coefficient (capacitance drops up to 50% at rated voltage) and piezoelectric microphonics. For precision DC smoothing, specify a C0G/NP0 dielectric. It is temperature-stable and linear.

Final BOM Picks:

  • Resistor: Yageo CFR-25JR-52-10K (10kΩ, 1/4W, 5% Carbon Film) - ~$0.01
  • Capacitor: Kemet C315C104J5G5TA (100nF, 50V, 5% C0G/NP0 MLCC) - ~$0.12

Decision Tree: Picking Your Exact Component Values

Use this decision matrix to finalize your component selection based on your specific microcontroller and load constraints.

Condition / ConstraintIf True...Concrete Component Pick
PWM Frequency is > 10kHz AND Load is > 100kΩStandard signal filteringR = 10kΩ, C = 100nF (C0G)
PWM Frequency is < 1kHz (e.g., 500Hz LED dimming)Need much lower $f_c$ to kill rippleR = 10kΩ, C = 1µF (X7R is fine here)
Load Impedance is < 10kΩ (e.g., driving a BJT base)Passive RC will droop; lower R requiredR = 470Ω, C = 2.2µF (or use Active Buffer)
Settling time must be < 1ms (fast DAC response)Must raise $f_c$ closer to PWM freqR = 1kΩ, C = 10nF (C0G)

Default Recommendation: If you are unsure of your load impedance but know it's going into another IC (like an op-amp or ADC), default to the 10kΩ / 100nF combination. It is the most robust starting point for 90% of maker and prototyping scenarios.

Step-by-Step Breadboard Testing and Verification

Don't just wire it and assume it works. Verify the ripple and settling time on your bench. For deeper theory on RC time constants and charging curves, refer to the SparkFun RC Circuit Tutorial or the classic Texas Instruments 'Filter Design in 30 Seconds' app note.

  1. Wire the Topology: Insert the 10kΩ resistor into the breadboard. Connect a jumper from your ESP32 GPIO (e.g., Pin 25) to one leg of the resistor. Insert the 100nF C0G capacitor so one leg shares the resistor's output node (Node B), and the other leg goes to the ground rail.
  2. Connect the Scope: Clip your oscilloscope probe ground spring to the breadboard ground rail. Touch the probe tip to Node B (the junction of R and C). Do not use the long ground alligator clip; it acts as an antenna and will show false high-frequency ringing.
  3. Configure the Signal: Flash your microcontroller to output a 5kHz PWM signal at a 50% duty cycle. This should yield a target DC voltage of 1.65V (assuming 3.3V logic).
  4. Set Scope Parameters: Set your oscilloscope to 500mV/div vertically and 500µs/div horizontally. Set the trigger to Auto or Normal at 1.0V.
  5. Measure Ripple: You should see a relatively flat line with a small sawtooth or triangular ripple. Use the scope's peak-to-peak measurement tool. With a 160Hz cutoff on a 5kHz signal, your ripple should be well under 50mV peak-to-peak.
  6. Test Step Response: Change your code to sweep the duty cycle from 0% to 100% instantly. Change the scope timebase to 2ms/div. Measure the time it takes for the voltage to reach 63.2% of its final value. This is your time constant ($\tau = R \times C$). For 10kΩ and 100nF, $\tau$ should measure exactly 1.0ms.
  7. Multimeter Sanity Check: Disconnect the scope and connect a standard DMM in DC Voltage mode. It should read the exact average voltage (e.g., 1.65V for 50% duty cycle) with the last digit stable, confirming the high-frequency AC component has been successfully rejected.

By following this exact topology, selecting a C0G dielectric, and verifying the time constant on your scope, you eliminate the guesswork from analog signal conditioning. The simple resistor capacitor circuit remains one of the most reliable tools in the electronics workbench when sized correctly for the load.