A digital filter low pass is a mathematical algorithm applied to a sequence of sampled data points to attenuate high-frequency noise while preserving lower-frequency signal trends. Unlike a physical capacitor-resistor (RC) network that alters actual electron flow, a digital filter operates entirely in the memory of your microcontroller, processing an array of integers or floats to output a smoothed data stream. It changes the data representation of the signal, which subsequently dictates how downstream logic—like a PID controller, a DAC output, or a serial display—reacts to the physical world.
What a Digital Low-Pass Filter Actually Changes in Your Code
When you wire a sensor to a microcontroller, the physical voltage on the pin is whatever the sensor and the environment dictate. If you have 50mV of high-frequency switching noise from a nearby buck converter riding on your 2.5V sensor signal, an analog RC filter physically shorts that high-frequency energy to ground.
A digital filter low pass does not touch the physical wire. Instead, your Analog-to-Digital Converter (ADC) samples that noisy 2.5V signal, digitizing the noise right along with the base voltage. The digital filter then takes those raw, jittery integer values and applies a recursive or non-recursive equation to calculate a new, smoothed value.
- Analog vs. Digital: Beginners often think adding a digital filter means they can skip the hardware decoupling capacitor. You cannot. If high-frequency noise exceeds the ADC's Nyquist limit, it aliases into the low-frequency band, and no digital low-pass filter can remove it. Always use a basic hardware RC anti-aliasing filter first.
- IIR vs. FIR: Makers often confuse Infinite Impulse Response (IIR) filters with Finite Impulse Response (FIR) filters. IIR uses previous outputs in its calculation (recursive, low CPU cost, introduces phase shift). FIR uses only previous inputs (non-recursive, high CPU cost, linear phase).
The Math: A Worked Numeric Example (First-Order IIR)
The most common digital filter low pass you will write on an Arduino, ESP32, or STM32 is the first-order IIR filter, also known as an Exponential Moving Average (EMA). It requires almost zero RAM and executes in a few clock cycles.
The governing equation is:
y[n] = α * x[n] + (1 - α) * y[n-1]
- y[n] = The new filtered output value.
- x[n] = The current raw ADC reading.
- y[n-1] = The previous filtered output value.
- α (alpha) = The smoothing factor, a float between 0.0 and 1.0. A smaller α means heavier filtering (more lag).
Let us run a worked numeric example. Assume your sensor settles at a true value of 150, but your first reading starts at 100. We will set α = 0.2 (meaning we trust the new raw reading 20%, and our previous filtered history 80%).
| Iteration (n) | Raw Input (x[n]) | Calculation | Filtered Output (y[n]) |
|---|---|---|---|
| 0 | 100 | (Initialization) | 100.0 |
| 1 | 150 | 0.2(150) + 0.8(100) | 110.0 |
| 2 | 150 | 0.2(150) + 0.8(110) | 118.0 |
| 3 | 150 | 0.2(150) + 0.8(118) | 124.4 |
| 4 | 150 | 0.2(150) + 0.8(124.4) | 129.5 |
| 5 | 150 | 0.2(150) + 0.8(129.5) | 133.6 |
Notice how the output asymptotically approaches the true value of 150. It never quite hits it in a single step; it glides toward it. This glide is the trade-off for eliminating noise.
Where You Meet This in Practice
You will implement a digital filter low pass in almost every embedded project that interfaces with the physical world. Common applications include:
- Microcontroller ADCs: The ESP32 ADC is notoriously noisy, often exhibiting +/- 40 counts of jitter on a 12-bit scale even with a stable reference voltage. A digital low pass is mandatory for usable readings.
- Motor Encoders and Tachometers: Calculating RPM from a Hall effect sensor pulse train introduces high-frequency quantization noise at low speeds. Filtering the calculated RPM stabilizes the speed control loop.
- Audio DSP: In projects using I2S DACs (like the MAX98357A), digital low-pass filters remove ultrasonic quantization noise and shape the frequency response before the signal hits the analog amplifier stage.
- IMU Sensor Fusion: Accelerometers pick up high-frequency mechanical vibration. A low-pass filter isolates the low-frequency gravity vector for tilt calculation, which is then fused with gyroscope data.
For a deeper theoretical background on designing these algorithms for DSP chips, Analog Devices provides excellent primers on digital filter topologies that bridge the gap between abstract math and silicon implementation.
Real-World Scenario Walkthrough: The ESP32 ADC Jitter Disaster
To understand the hidden costs of digital filtering, let us look at a real-world bench failure involving an ESP32-WROOM-32, a 10kΩ linear potentiometer, and a DC motorized ball valve.
1. The Setup
The goal was to use the 10kΩ potentiometer as a position feedback sensor for the valve. The wiper was wired to GPIO34 (ADC1_CH6). The ESP32 was configured for 12-bit resolution (0 to 4095). The control logic used a standard PID (Proportional-Integral-Derivative) loop to drive the motor until the valve matched a target setpoint of 2048 (exactly 50% open).
2. The Numbers
With the potentiometer physically locked at 2048, the raw ADC readings bounced erratically between 2012 and 2088. This +/- 36 count jitter was caused by internal ESP32 ADC non-linearity and 50Hz mains hum coupling into the unshielded wiper wire. If fed directly into the PID loop, the Derivative (D) term would spike violently on every noise edge, causing the motor to chatter and overheat.
3. The Outcome (Applying the Filter)
We implemented the first-order IIR filter shown above, setting α = 0.05 for aggressive smoothing. The jitter dropped beautifully to +/- 2 counts. The PID Derivative term stabilized, and the motor stopped chattering. The code was deployed to the field.
4. What Went Wrong (The Phase Lag Trap)
Two days later, the valve was reported as 'hunting'—constantly oscillating back and forth past the 50% mark without ever settling.
The culprit was phase lag. Because α was set so low (0.05), the filter introduced a group delay of roughly 45ms at the sampling rate of 100Hz. The PID loop was tuned on the bench assuming instantaneous feedback. In the field, by the time the filtered data reported that the valve had reached 2048, the physical valve had already overshot to 2150. The PID controller, seeing the delayed error, reversed the motor, causing an endless oscillation.
5. The Fix
We could not simply remove the filter, or the D-term chatter would return. Instead, we applied a two-part fix:
- Hardware: Added a physical 100nF ceramic capacitor between the wiper and GND to handle the highest frequency noise, allowing us to increase α to 0.2 in software (reducing the digital phase lag to ~10ms).
- Software: Retuned the PID loop, specifically lowering the Derivative gain and adding a small deadband (+/- 5 counts) where the integral term stops accumulating.
Frequently Asked Questions
Can I just use a moving average instead of an IIR filter?
Yes, a Simple Moving Average (SMA) is a type of Finite Impulse Response (FIR) low-pass filter. However, an SMA requires storing an array of the last N samples in RAM. If you need a deep filter (e.g., averaging the last 50 samples), an IIR filter only requires storing a single previous float variable, making IIR vastly superior for memory-constrained 8-bit AVR microcontrollers like the ATmega328P.
How do I choose the right alpha (α) value?
Alpha dictates your cutoff frequency. The relationship between α, the sampling frequency ($f_s$), and the cutoff frequency ($f_c$) is approximately $f_c = \frac{\alpha \cdot f_s}{2\pi}$. If you are sampling at 1000Hz and want a 10Hz cutoff, α should be roughly 0.062. For quick bench prototyping, start with α = 0.1 and adjust by observing the step response on a serial plotter.
Why does my filtered signal still have sharp spikes?
A standard IIR low-pass filter is highly susceptible to single-sample outliers (like an ADC misread caused by an ESD event). If one raw sample spikes to 4095, the filter will pull the output toward 4095, and it will take many iterations to recover. To fix this, place a median filter or a simple outlier-rejection algorithm (e.g., 'ignore any sample that jumps more than 20% from the previous reading') before the IIR low-pass filter.
Do digital filters consume a lot of battery power?
The math itself (a multiply and an add) consumes negligible power. However, if your low-pass filter requires a very high sampling rate to capture the signal before filtering, the ADC and CPU must wake up more frequently, which destroys battery life in sleep-cycle applications. In low-power IoT nodes, it is almost always more power-efficient to use a hardware analog RC filter to band-limit the signal, allowing the microcontroller to sample at a much lower, battery-friendly rate.






