Posts

ASN Filter Designer’s ANSI C SDK framework, provides developers with a comprehensive C code framework for developing  AIoT filtering application on microcontrollers and embedded platforms. Although the framework has been primarily designed to support the just ASN filter Designer’s filter cascade, it is possible to create extra filter objects to augment the cascade.

Two common filtering methods used by AIoT developers are the Median and moving average (MA) filters. Although these fully integrated within the Framework’s filter cascade, it is often useful to have the flexibility of an additional filtering block to act as a post filter smoothing filter.

An extra median or MA filter may be easily added to main.c as shown below. Notice that data is filtered in blocks of 4 as required by the framework.

Median filter

The Median filter is non-linear filtering method that uses the concept of majority voting (i.e. calculating the median) to remove glitches and smooth data.  It is edge preserving, making it a good choice for enhancing square waves or pulse like data.
[code language=”cpp”]
#include "ASN_DSP/DSPFilters/MedianFilter.h"
float InputTemp[4];
float OutputTemp[4];

MedianFilter_t MyMedianfilter;

InitMedianFilter(&MyMedianfilter,7); // median of length 7

for (n=0; n<TEST_LENGTH_SAMPLES; n+=4)
{
InputTemp[0]=InputValues[n];
InputTemp[1]=InputValues[n+1];
InputTemp[2]=InputValues[n+2];
InputTemp[3]=InputValues[n+3];

MedianFilterData(&MyMedianfilter,InputTemp, OutputTemp);

OutputValues[n]=OutputTemp[0];
OutputValues[n+1]=OutputTemp[1];
OutputValues[n+2]=OutputTemp[2];
OutputValues[n+3]=OutputTemp[3];
}

[/code]

Moving Average filter

The moving average (MA) filter is optimal for reducing random noise while retaining a sharp step response, making it a versatile building block for smart sensor signal processing applications. It is perhaps one of the most widely used digital filters due to its conceptual simplicity and ease of implementation.
[code language=”cpp”]
#include "ASN_DSP/DSPFilters/MAFilter.h"
float InputTemp[4];
float OutputTemp[4];

MAFilter_t MyMAfilter;

InitMAFilter(&MyMAfilter,9); // MA of length 9

for (n=0; n<TEST_LENGTH_SAMPLES; n+=4)
{
InputTemp[0]=InputValues[n];
InputTemp[1]=InputValues[n+1];
InputTemp[2]=InputValues[n+2];
InputTemp[3]=InputValues[n+3];

MAFilterData(&MyMAfilter,InputTemp, OutputTemp);

OutputValues[n]=OutputTemp[0];
OutputValues[n+1]=OutputTemp[1];
OutputValues[n+2]=OutputTemp[2];
OutputValues[n+3]=OutputTemp[3];
}

[/code]

Download demo now

Licencing information


Author

  • Marty de Vries

    Marty is an applications engineer and embedded software expert at ASN. He has over 10 years experience in developing high performance embedded libraries and applications for Arm processors.

    View all posts

As discussed in a previous article, the moving average (MA) filter is perhaps one of the most widely used digital filters due to its conceptual simplicity and ease of implementation. The realisation diagram shown below, illustrates that an MA filter can be implemented as a simple FIR filter, just requiring additions and a delay line.

moving average filter, an MA filter can be implemented as a simple FIR filter, just requiring additions and a delay line. moving average FIR filter

Modelling the above, we see that a moving average filter of length \(\small\textstyle L\) for an input signal \(\small\textstyle x(n)\) may be defined as follows:

\( y(n)=\large{\frac{1}{L}}\normalsize{\sum\limits_{k=0}^{L-1}x(n-k)}\quad \text{for} \quad\normalsize{n=0,1,2,3….}\label{FIRdef}\tag{1}\)

This computation requires \(\small\textstyle L-1\) additions, which may become computationally demanding for very low power processors when \(\small\textstyle L\) is large. Therefore, applying some lateral thinking to the computational challenge, we see that a much more computationally efficient filter can be used in order to achieve the same result, namely:

\(H(z)=\displaystyle\frac{1}{L}\frac{1-z^{-L}}{1-z^{-1}}\tag{2}\label{TF}\)

with the difference equation,

\(y(n) =y(n-1)+\displaystyle\frac{x(n)-x(n-L)}{L}\tag{3}\)

Notice that this implementation only requires one addition and one subtraction for any value of \(\small\textstyle L\). A further simplification (valid for both implementations) can be achieved in a pre-processing step prior to implementing the difference equation, i.e. scaling all input values by \(\small\textstyle L\). If \(\small\textstyle L\) is a power of two (e.g. 4,8,16,32..), this can be achieved by a simple binary shift right operation.

Is it an IIR or actually an FIR?

Upon initial inspection of the transfer function of Eqn. \(\small\textstyle\eqref{TF}\), it appears that the efficient Moving average filter is an IIR filter. However, analysing the pole-zero plot of the filter (shown on the right for \(\small\textstyle L=8\)), we see that the pole at DC has been cancelled by a zero, and that the resulting filter is actually an FIR filter, with the same result as Eqn. \(\small\textstyle\eqref{FIRdef}\).

Moving average filter (MA filter). It appears that the efficient MA filter is an IIR filter. However, analysing the pole-zero plot of the filter, , we see that the pole at DC has been cancelled by a zero, and that the resulting filter is actually an FIR filter, with the same result as Eqn.

Notice also that the frequency spacing of the zeros (corresponding to the nulls in the frequency response) are at spaced at \(\small\textstyle\pm\frac{Fs}{L}\). This can be readily seen for this example, where an MA of length 8, sampled at \(\small\textstyle 500Hz\), results in a \(\small\textstyle\pm62.5Hz\) resolution.

As a final point, notice that the our efficient filter requires a delay line of length \(\small\textstyle L+1\), compared with the FIR delay line of length, \(\small\textstyle L\). However, this is a small price to pay for the computation advantage of a filter just requiring one addition and one subtraction. As such, the MA filter of Eqn. \(\small\textstyle\eqref{TF}\) presented herein is very attractive for very low power processors, such as the Arm Cortex-M0 that have been traditionally overlooked for DSP operations.

Implementation

The MA filter of Eqn. \(\small\textstyle\eqref{TF}\) may be implemented in ASN FilterScript as follows:

 
ClearH1;  // clear primary filter from cascade 
interface L = {2,32,2,4}; // interface variable definition 

Main() 
Num = {1,zeros(L-1),-1}; // define numerator coefficients 
Den = {1,-1}; // define denominator coefficients 
Gain = 1/L; // define gain 



Download demo now

Licencing information

The moving average (MA) filter is perhaps one of the most widely used FIR filters due to its conceptual simplicity and ease of implementation. As seen in the diagram below, notice that the filter doesn’t require any multiplications, just additions and a delay line, making it very suitable for many extreme low-power embedded devices with basic computational capabilities.

fir direct form

However, despite its simplicity, the moving average filter is optimal for reducing random noise while retaining a sharp step response, making it a versatile building block for smart sensor signal processing applications.

A moving average filter of length \(L\) for an input signal \(x(n)\) may be defined as follows:

\(y(n)=\large{\frac{1}{L}}\normalsize{\sum\limits_{k=0}^{L-1}x(n-k)}\) for \(\normalsize{n=0,1,2,3….}\)

Where, a simple rule of thumb states that the amount of noise reduction is equal to the square-root of the number of points in the average. For example, an MA of length 9 will result in a factor 3 noise reduction.

moving average filterFrequency response of an MA filter of length 9. Notice the poor stopband attentuation at around -20dB.

Advantages

  • Most commonly used digital lowpass filter.
  • Optimal for reducing random noise while retaining a sharp step response.
  • Good smoother (time domain).
  • Unity valued filter coefficients, no MAC (multiply and accumulate) operations required.
  • Conceptually simple to implement.

Disadvantages

  • Inflexible frequency response: nudging a conjugate zero pair results in non-unity coefficients.
  • Poor lowpass filter (frequency domain): slow roll-off and terrible stopband attenuation characteristics.

Implementation

The MA filter may be implemented in ASN FilterScript as follows:

ClearH1;  // clear primary filter from cascade
Main();
Hd=movaver(8,"symbolic");  // design an 8th order MA
Num = getnum(Hd);   // define numerator coefficients
Den = {1};          // define denominator coefficients
Gain = getgain(Hd); // define gain

A more computationally efficient implementation of the MA filter is discussed here.

Further reading

  • Understanding Digital Signal Processing, Chapter 5, R. G. Lyons
  • The Scientist and Engineer’s Guide to Digital Signal Processing, Chapter 15, Steven W. Smith

Download demo now

Licencing information