ESP-DSP Series 2 | Building Efficient Digital Filters with FIR
ESP-DSP FIR Module: A Core Component in Digital Signal Processing.The FIR (Finite Impulse Response) filter is a cornerstone in digital signal processing (DSP), known for its stability and linear phase characteristics. It is widely used in audio processing, communication systems, and sensor data filtering. This article focuses on the FIR module provided by Espressif’s ESP-DSP library, demonstrating how to leverage its high performance to implement stable and practical digital filters

Contents
Principles of FIR Filtering
A key feature of FIR filters is that their output depends only on a finite number of past input samples, which guarantees system stability and allows precise linear phase implementationโavoiding phase distortion. The computation involves multiplying a set of input samples with corresponding coefficients and summing the results to produce each output sample. By adjusting the filter order (number of taps) and coefficients, various effects like low-pass, high-pass, band-pass, and band-stop can be achieved.
ESP-DSP FIR Features
ESP-DSP is a high-performance DSP library designed by Espressif for chips like the ESP32 and ESP32-S3. It includes mathematical operations and filter implementations. Key features of the FIR module include:
- Floating-point and Fixed-point Support: Provides flexibility for various performance and precision needs.
- Decimation Support: Enables efficient downsampling for signal processing pipelines.
- Structured Management: Uses data structures to manage filter states, including coefficients and delay lines, making initialization and processing efficient.
- Optimized Performance: Some functions are written in assembly for maximum performance on ESP32 architectures.
- Simple API: Initialization and processing functions are easy to useโjust supply the coefficients and delay line, and you’re ready to go.
Development Environment
Before starting your programming, make sure to complete the following preparations:
- Install ESP-IDF (version 5.x or higher): ESP-IDF is the official development framework for programming the ESP32, and it supports multiple operating systems such as Windows, macOS, and Linux.
- ESP32 Development Board: An ESP32 board is required.
- Install the ESP-DSP library.
Project Structure
This follows a typical ESP-IDF project structure. If you use idf.py create-project or the official ESP-IDF VS Code extension, you’ll see something like this:
esp32-fir-filter/
โโโ CMakeLists.txt
โโโ main/
โ โโโ CMakeLists.txt
โ โโโ fir_filter_example.c
โโโ sdkconfig
- CMakeLists.txt: Main build configuration file
- main/: Contains application source code
- fir_filter_example.c: Core example demonstrating the FIR filter logic
- sdkconfig: Auto-generated configuration file managed by
menuconfig
This structure is modular, maintainable, and aligned with Espressifโs best practices.
Code
This example demonstrates how to implement a simple FIR filter using the ESP-DSP library to smooth a square wave input signal.
#include <stdio.h>
#include "esp_log.h"
#include "esp_dsp.h"
#include "dsp_filter_fir.h"
#define FILTER_TAP_NUM 32
#define SIGNAL_LENGTH 128
// Define log tag for this module
static const char *TAG = "FIR_FILTER_EXAMPLE";
// Simplified low-pass filter coefficients (replace as needed)
float filter_coeffs[FILTER_TAP_NUM] = {
0.03125, 0.03125, 0.03125, 0.03125,
0.03125, 0.03125, 0.03125, 0.03125,
0.03125, 0.03125, 0.03125, 0.03125,
0.03125, 0.03125, 0.03125, 0.03125,
0.03125, 0.03125, 0.03125, 0.03125,
0.03125, 0.03125, 0.03125, 0.03125,
0.03125, 0.03125, 0.03125, 0.03125,
0.03125, 0.03125, 0.03125, 0.03125
};
float input_signal[SIGNAL_LENGTH];
float output_signal[SIGNAL_LENGTH];
float delay_line[FILTER_TAP_NUM];
dsps_fir_t fir; // FIR filter structure
void app_main(void) {
esp_err_t ret;
ESP_LOGI(TAG, "ESP-DSP FIR filter example started");
// Initialize FIR filter
ret = dsps_fir_init_f32(&fir, filter_coeffs, delay_line, FILTER_TAP_NUM);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "FIR initialization failed");
return;
}
// Generate square wave input signal
for (int i = 0; i < SIGNAL_LENGTH; i++) {
input_signal[i] = (i % 20 < 10) ? 1.0f : -1.0f;
}
// Apply FIR filter
for (int i = 0; i < SIGNAL_LENGTH; i++) {
output_signal[i] = dsps_fir_process_f32(&fir, input_signal[i]);
ESP_LOGD(TAG, "Input: %.2f\tOutput: %.2f", input_signal[i], output_signal[i]);
}
ESP_LOGI(TAG, "Filtering completed");
// Free FIR memory (optional)
dsps_fir_free_f32(&fir);
}
Code Explanation
- Filter Parameters
#define FILTER_TAP_NUM 32
#define SIGNAL_LENGTH 128
FILTER_TAP_NUMdefines the filter order (number of taps).SIGNAL_LENGTHspecifies the number of signal samples to process.
- Initialization
Initializes the FIR filter structure using predefined coefficients and a delay line.
dsps_fir_init_f32(&fir, filter_coeffs, delay_line, FILTER_TAP_NUM);
- Input Signal Generation
Creates a synthetic square wave alternating every 10 samples between +1.0 and -1.0.
input_signal[i] = (i % 20 < 10) ? 1.0f : -1.0f;
- Filtering
Processes each input sample through the FIR filter, printing both input and output for inspection.
output_signal[i] = dsps_fir_process_f32(&fir, input_signal[i]);
- Resource Cleanup
Frees internal FIR structuresโoptional but good practice.
dsps_fir_free_f32(&fir);
Compile and Flash
After writing the code, you can use the ESP-IDF tools to build, flash, and monitor:
In the VS Code lower-left ESP-IDF toolbar:
- Click Build project
- Click Flash device
- Click Monitor device
Output and Test Results
As the FIR convolution accumulates, output values gradually smooth out the square wave transitions. Example logs:
I (0) FIR_FILTER_EXAMPLE: ESP-DSP FIR filter example started
D (10) FIR_FILTER_EXAMPLE: Input: 1.00 Output: 0.03
D (20) FIR_FILTER_EXAMPLE: Input: 1.00 Output: 0.06
D (30) FIR_FILTER_EXAMPLE: Input: 1.00 Output: 0.09
...
D (310) FIR_FILTER_EXAMPLE: Input: -1.00 Output: 0.00
D (320) FIR_FILTER_EXAMPLE: Input: -1.00 Output: -0.03
...
I (900) FIR_FILTER_EXAMPLE: Filtering completed
Each line shows a real-time filtered output, clearly demonstrating the smoothing effect of a low-pass filter.
Conclusion
This tutorial demonstrates how to implement a stable and efficient FIR filter using the ESP-DSP library on the ESP32. With simple initialization and per-sample processing, real-time signal filtering becomes straightforwardโwhether for noise reduction, smoothing, or frequency shaping.
FIR filters are widely used in:
- Audio processing
- Communication systems
- Image filtering
- Sensor data conditioning
- Industrial and control systems
- Embedded and IoT applications
With this foundation, you can expand furtherโdesign custom filter coefficients with tools like MATLAB, Python (SciPy), or FIR Designer, and implement high-pass, band-pass, or band-stop filters. Combine FIR with FFT for more advanced preprocessing pipelines.
With this knowledge, you’re now equipped to design customized FIR filters and integrate them into your real-time DSP workflows.









