Skip to main content
JKhal
Associate III
June 18, 2020
Question

Low pass filter on ongoing samples.

  • June 18, 2020
  • 1 reply
  • 2480 views

Hi all,

My application requires to sample a sensor and send the samples out in real time, without saving the samples.

I am required to run a low pass filter on the samples, but here is the problem cause if I want to do it on 20 samples for example then I will not be able to send out the samples each after I got it as required, and when I send them immediately each after I got it I use an ongoing average on 10 samples but that wasn't enough.

what low pass filter algorithm is the best for this application?

what is the accepted way to do this ?

Best regards

JK

    This topic has been closed for replies.

    1 reply

    JElli.1
    Visitor II
    October 6, 2020

    Try the Exponential, or First-order filter:

    Y[n] = dY[n-1] + (1-d)X[n]

    ·              Y[n] is the current output

    ·              Y[n-1] is the previous output

    ·              X[n] is the current input

    ·              d is the damping factor

    The damping factor is a number between 0 and 1. If d = 0, the output is just equal to the input, and no filtering (smoothing) takes place.

    The closer d is to 1, the greater the amount of filtering (smoothing).

      

    Here is an example:

    The input signal is a Sine function with amplitude +- 100, added to that is random noise of +-10.

    To filter out the noise we run the data through the filter equation first with d = 0.5 and then d = 0.8

    0693W000004Jo9CQAS.jpg 

     Code to reproduce the above >>

    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "math.h"
    #include "stdlib.h"
     
    // ......
     
    /* USER CODE BEGIN PV */
    int R;
    float d, Xin, Yout, Yprev, X[37], Y[37];
    float e, f, g;
     
     
    // ......
     
     /* USER CODE BEGIN 2 */
     
     // FIRST ORDER DIGITAL FILTER
     d = 0.5; // Damping factor (adjust as needed)
     srand(123);
     R = (rand() % 20) - 10; // random number from -10 to +10
     Xin = 100*sin(0) + R; // Input 0 (Sine function with noise)
     Yprev = Xin; // Initial value for previous output
     X[0] = Xin; // for plotting only
     Y[0] = Xin; // for plotting only
     
     for (int n = 1; n < 37; n++) // This will be a "while (1)"- infinite loop in final project
     {
     	R = (rand() % 20) - 10; // random number from -10 to +10
     	Xin = 100*sin(n*M_PI/18) + R; // Input n (Sine function with noise)
     	Yout = d*Yprev + (1-d)*Xin; // Output n (Filtered)
     	Yprev = Yout; // Save previous output
     
     	X[n] = Xin; // saving data in arrays just for plotting the ..
     	Y[n] = Yout; // graph afterwards (not needed in final project)
     }
     

    If you need stronger filtering, you can go to a second or even third order digital filter:

    Second-order:

    Y[n] = eY[n-1] + fY[n-2] + (1-e-f)X[n]

     

    ·              e = 2*d   (where d is the damping factor as before)

    ·              f = -d*d

     

     Third-order:

    Y[n] = eY[n-1] + fY[n-2] + gY[n-3] + (1-e-f-g)X[n]

     

    ·              e = 3*d   (where d is the damping factor as before)

    ·              f = -3*d*d

    ·              g = d*d*d

    Add the following code, below the previous, to try the second and third order filters.

    We just use the data already in the X[n] array as input to generate a new Y[n] output array. >>

    // SECOND ORDER DIGITAL FILTER
     d = 0.5; // Damping factor (adjust as needed)
     e = 2*d;
     f = -d*d;
     Y[0] = X[0];
     Y[1] = X[0];
     
     for (int n = 2; n < 37; n++)
     {
     	Y[n] = e*Y[n-1] + f*Y[n-2] + (1-e-f)*X[n];
     }
     
     // THIRD ORDER DIGITAL FILTER
     d = 0.5; // Damping factor (adjust as needed)
     e = 3*d;
     f = -3*d*d;
     g = d*d*d;
     Y[0] = X[0];
     Y[1] = X[0];
     Y[2] = X[0];
     
     for (int n = 3; n < 37; n++)
     {
     Y[n] = e*Y[n-1] + f*Y[n-2] + g*Y[n-3] + (1-e-f-g)*X[n];
     }
     

    Here is a real world example:

    Noisy pressure sensor – data; filtered with first order and third order filter, both with d=0.8

    0693W000004Jk2cQAC.jpg