0
0
Signal Processingdata~7 mins

Low-pass FIR filter design in Signal Processing

Choose your learning style9 modes available
Introduction

A low-pass FIR filter lets low frequencies pass and blocks high frequencies. It helps clean signals by removing noise or unwanted fast changes.

You want to remove high-frequency noise from a sound recording.
You need to smooth sensor data that has sudden spikes.
You want to prepare data by keeping only slow trends and removing fast fluctuations.
You are designing a system that only needs signals below a certain frequency.
You want to reduce data size by removing details that change too fast.
Syntax
Signal Processing
from scipy.signal import firwin

# firwin(numtaps, cutoff, window='hamming', pass_zero=True)
# numtaps: number of filter taps (length)
# cutoff: cutoff frequency (0 to 1, where 1 is Nyquist frequency)
# window: type of window to shape filter
# pass_zero=True means low-pass filter

The cutoff frequency is given as a fraction of the Nyquist frequency (half the sampling rate).

The number of taps controls filter sharpness and length; more taps mean better filtering but more delay.

Examples
This creates a simple low-pass filter using the default Hamming window.
Signal Processing
from scipy.signal import firwin

# Create a low-pass FIR filter with 31 taps and cutoff at 0.3 (30% of Nyquist)
filter_coefs = firwin(31, 0.3)
This creates a low-pass filter with 51 taps and a Blackman window for smoother edges.
Signal Processing
filter_coefs = firwin(51, 0.2, window='blackman')
Explicitly sets the filter as low-pass with cutoff at 40% of Nyquist frequency.
Signal Processing
filter_coefs = firwin(21, 0.4, pass_zero=True)
Sample Program

This program creates a low-pass FIR filter with a cutoff at 100 Hz for a 1000 Hz sampling rate. It filters a signal made of a slow 5 Hz wave and a fast 300 Hz wave. The plots show the original signal, the filtered signal (where the 300 Hz part is removed), and the filter's frequency response.

Signal Processing
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import firwin, lfilter, freqz

# Sampling frequency
fs = 1000  # 1000 Hz

# Design low-pass FIR filter
numtaps = 51
cutoff = 100  # 100 Hz cutoff frequency

# Normalize cutoff frequency to Nyquist frequency (fs/2)
normalized_cutoff = cutoff / (fs / 2)

# Get filter coefficients
fir_coeff = firwin(numtaps, normalized_cutoff)

# Create a sample signal: 5 Hz + 300 Hz sine waves
t = np.linspace(0, 1.0, fs, endpoint=False)
signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 300 * t)

# Apply the filter to the signal
filtered_signal = lfilter(fir_coeff, 1.0, signal)

# Frequency response of the filter
w, h = freqz(fir_coeff, worN=8000)

# Plot results
plt.figure(figsize=(12, 8))

plt.subplot(3, 1, 1)
plt.plot(t, signal)
plt.title('Original Signal (5 Hz + 300 Hz)')
plt.xlabel('Time [seconds]')
plt.ylabel('Amplitude')

plt.subplot(3, 1, 2)
plt.plot(t, filtered_signal)
plt.title('Filtered Signal (Low-pass FIR)')
plt.xlabel('Time [seconds]')
plt.ylabel('Amplitude')

plt.subplot(3, 1, 3)
plt.plot(w * fs / (2 * np.pi), 20 * np.log10(abs(h)))
plt.title('Frequency Response of the Filter')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Gain [dB]')
plt.ylim(-100, 10)
plt.grid(True)

plt.tight_layout()
plt.show()
OutputSuccess
Important Notes

More taps mean better filtering but slower processing and more delay.

Choosing the right window affects the filter's sharpness and ripple.

Always normalize cutoff frequency by Nyquist frequency (half the sampling rate).

Summary

Low-pass FIR filters keep slow changes and remove fast changes in signals.

Use firwin to design filters by specifying taps and cutoff frequency.

Test filters by applying them to signals and checking frequency response.