How to design and implement a digital low-pass filter on an Arduino

How to design and implement a digital low-pass filter on an Arduino

How to Design and Implement a Low-Pass Filter for Arduino Projects

Introduction to Signal Processing

  • In Arduino projects, sensor measurements often contain noise. This video demonstrates how to design and implement a low-pass filter suitable for such applications.
  • An artificial signal is created for testing the filter, consisting of a 2 Hz sine wave as the fundamental component and a 50 Hz sine wave representing unwanted noise.

Understanding Fourier Transform

  • The Discrete Fourier Transform (DFT) provides insight into the signal by displaying each sine curve as a peak in the Fourier domain.
  • A first-order low-pass filter is introduced, represented by the transfer function omega_0/s + omega_0 , which will be used to eliminate high-frequency noise while preserving lower frequencies.

Designing the Low-Pass Filter

  • The cutoff frequency ( omega_0 ) is set at 2pi times 5 radians per second (5 Hz), aimed at preserving the 2 Hz signal while attenuating the 50 Hz noise.
  • Testing shows that when passing through the filter, the 2 Hz signal remains largely unaffected, whereas the magnitude of the 50 Hz signal is significantly reduced.

Bode Plot Analysis

  • The Bode plot illustrates how different frequencies are affected by the filter; at 1 Hz, signals remain largely unchanged, while at 5 Hz they are attenuated to about half their original magnitude.
  • At higher frequencies like 50 Hz and beyond, only a small fraction of those signals remains after filtering—10% at 50 Hz and just 1% at 500 Hz.

Phase Delay Considerations

  • The phase plot indicates minimal delay at lower frequencies (1 Hz), but significant delays occur as frequency increases—up to about -90 degrees at higher frequencies.

Transitioning to Arduino Implementation

  • The continuous transfer function isn't suitable for real-time processing on Arduino; thus, conversion into discrete form is necessary for practical implementation.
  • A Python script has been prepared to handle complex calculations required for creating this digital filter.

Sampling Frequency and Discrete Transfer Function

  • To simplify processing on Arduino, sampling frequency is throttled down to one kilohertz. This affects how we derive our discrete transfer function using bilinear transformation methods.

Constructing Difference Equations

  • Coefficients from discrete transfer functions inform us about constructing difference equations needed for filtering in real-time applications.

Coding and Testing on Arduino

  • The code begins with defining test signals followed by implementing difference equations where new filtered values depend on previous raw values and filtered outputs.

Results of Filtering Process

  • Initial results show that high-frequency components have been effectively removed from test signals; however, some attenuation occurs along with slight delays in output response.

Evaluating Filter Performance

Low-Pass Filter Design and Implementation

Adjusting Cutoff Frequency and Test Signal

  • The cutoff frequency in the script is set to 30 Hz, preserving signals from 0 to 20 Hz. The main test signal is adjusted to 20 Hz.
  • The power spectrum of the test signal is displayed, followed by generating the continuous transfer function of the filter and its bode diagram.

Understanding Filter Performance

  • A low-pass filter has a broad transition band where frequencies near the cutoff are attenuated rather than completely removed.
  • The pass band (0-2 Hz for a 5 Hz cutoff) preserves signals, while the stop band (above 30 Hz) removes most content; between these ranges, attenuation occurs without complete removal.

Ideal vs. Real Filters

  • Ideally, a low-pass filter would perfectly pass all signals below the cutoff frequency with no transition band; however, real-world filters have limitations.
  • Higher-order filters like Butterworth provide better performance: a second-order offers greater attenuation and smaller transition bands compared to first-order filters.

Implementing Butterworth Filters

  • While higher-order Butterworth filters approach ideal performance, practical considerations limit their use due to complexity and potential drawbacks.
  • The Butterworth filter's transfer function resembles that of first-order filters but uses polynomial denominators based on order n.

Coding and Coefficient Calculation

  • Python code can compute coefficients for any order Butterworth filter using recursion formulas established since 1930.
  • After obtaining the continuous transfer function, discrete transfer functions can be computed for implementation on Arduino.

Comparing Filter Orders

  • Testing shows that while a second-order Butterworth filter retains lower frequencies better than first-order ones, it introduces more delay in filtered signals.
  • Bode plots reveal that higher orders increase delay significantly; for instance, a fourth-order may introduce up to 45 degrees of phase shift within its pass band.

Balancing Attenuation and Delay

  • When designing low-pass filters, one must balance attenuation characteristics against delays introduced by higher orders as shown in Bode plots.
  • Alternative high-order filters exist beyond Butterworth; if their characteristics do not suit your project needs, consider exploring other standard options.

Practical Application Insights

  • A comparison between first and second order low-pass filters applied to raw accelerometer readings indicates both effectively remove high-frequency components but differ in smoothness and delay effects.
Video description

In this video, you'll learn how a low-pass filter works and how to implement it on an Arduino to process signals in real-time. You don't have to be a mathematician to design your low-pass filter. You can use libraries to do the work for you. The python scripts linked below can help you to get started. https://github.com/curiores/ArduinoTutorials/blob/main/BasicFilters/Design/LowPass/LowPassFilter.ipynb https://github.com/curiores/ArduinoTutorials/blob/main/BasicFilters/Design/LowPass/ButterworthFilter.ipynb The Arduino examples are also available: https://github.com/curiores/ArduinoTutorials/tree/main/BasicFilters/ArduinoImplementations/LowPass/SimpleExamples There's also a high-pass version now: https://github.com/curiores/ArduinoTutorials/blob/main/BasicFilters/ArduinoImplementations/HighPass/HighPass.ino with a few details about the derivation here: https://github.com/curiores/ArduinoTutorials/tree/main/BasicFilters/Design/HighPass To use the Jupyter Notebook, start by following the instructions to download Python: https://wiki.python.org/moin/BeginnersGuide/Download and then follow the instructions to install Jupyter: https://jupyter.org/install.html Correction(s): @ 9:28, the Butterworth filter sum should be from 0 to n.