Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Digital filter code - what are the input variables?

Status
Not open for further replies.

julian403

Full Member level 5
Joined
Feb 28, 2014
Messages
254
Helped
1
Reputation
2
Reaction score
1
Trophy points
18
Location
Argentina
Activity points
2,105
Hello All. I got this code from filter solution. Its a low pass filter of 4 order but I dont understand what is the states pointer.

float states [];

thats the function that I want to filter?

I get from the input ten values that I want to filter. I've to pass it to the filter by the array states? and what is invar??

This is the code

Code:
float DigFil(invar, states)
float invar, *states;
/******************************************************************************/
/* Filter Solutions Version 2015                 Nuhertz Technologies, L.L.C. */
/*                                                            www.nuhertz.com */
/*                                                            +1 602-279-2448 */
/* 4th Order Low Pass Butterworth                                             */
/* Bilinear Transformation with Prewarping                                    */
/* Sample Frequency = 50.00 KHz                                               */
/* Standard Form                                                              */
/* Arithmetic Precision = 4 Digits                                            */
/*                                                                            */
/* Pass Band Frequency = 10.00 KHz                                            */
/*                                                                            */
/******************************************************************************/
/*                                                                            */
/* Input Variable Definitions:                                                */
/* Inputs:                                                                    */
/*   invar    float       The input to the filter                             */
/*   *states  float       Pointer to array holding the filter states          */
/*                        (Minimum array dimension: 4)                        */
/*                                                                            */
/* Option Selections:                                                         */
/* Standard C;   Externally Initialized;   External States;   Optimized;      */
/*                                                                            */
/******************************************************************************/
/*                                                                            */
/* This software is automatically generated by Filter Solutions               */
/* no restrictions from Nuhertz Technologies, L.L.C. regarding the use and    */
/* distributions of this software.                                            */
/*                                                                            */
/******************************************************************************/

{
    float sumnum=0.0, sumden=0.0;  int i=0;
    static float znum[3] = {
        4.658e-02,
        .1863,
        .2795
    };
    static float zden[4] = {
        3.012e-02,
        -.1827,
        .68,
        -.7821
    };
    sumnum = sumden = 0.0;
    for (i=0;i<4;i++){
        sumden += states[i]*zden[i];
        sumnum += states[i]*znum[i<3?i:4-i];
        if (i<3) states[i] = states[i+1];
    }
    states[3] = invar-sumden;
    sumnum += states[3]*znum[0];
    return sumnum;
}

thanks for all in advance!
 

What do you mean with "ten values you want to filter"? The filter function has to be called continuously, each call gets one data sample in in invar. The state vector isn't stored internal to the function, instead an external array is connected by a pointer.

- - - Updated - - -

You'll notice that the Filter Solutions code generator has different options for the handling of state variables. I presume you know that a digital filter uses a number of state variables according to the filter order.

- - - Updated - - -

You'll also notice that the code implements an IIR filter of the controllable canonical form.
 
Thanks I didnt know that but I dont know what state to use. Where I can or How I can find them?

this is the code with initialize capability

Code:
float DigFil(invar, initval, setic)
float invar, initval; int setic;
/******************************************************************************/
/* Filter Solutions Version 2015                 Nuhertz Technologies, L.L.C. */
/*                                                            www.nuhertz.com */
/*                                                            +1 602-279-2448 */
/* 10th Order Low Pass Butterworth                                            */
/* Bilinear Transformation with Prewarping                                    */
/* Sample Frequency = 100.0 KHz                                               */
/* Standard Form                                                              */
/* Arithmetic Precision = 4 Digits                                            */
/*                                                                            */
/* Pass Band Frequency = 8.000 KHz                                            */
/*                                                                            */
/******************************************************************************/
/*                                                                            */
/* Input Variable Definitions:                                                */
/* Inputs:                                                                    */
/*   invar    float       The input to the filter                             */
/*   initvar  float       The initial value of the filter                     */
/*   setic    int         1 to initialize the filter to the value of initvar  */
/*                                                                            */
/* Option Selections:                                                         */
/* Standard C;   Initializable;            Internal States;   Optimized;      */
/*                                                                            */
/* There is no requirement to ever initialize the filter.                     */
/* The default initialization is zero when the filter is first called         */
/*                                                                            */
/******************************************************************************/
/*                                                                            */
/* This software is automatically generated by Filter Solutions               */
/* no restrictions from Nuhertz Technologies, L.L.C. regarding the use and    */
/* distributions of this software.                                            */
/*                                                                            */
/******************************************************************************/

{
    float sumnum=0.0, sumden=0.0;  int i=0;
    static float states[10] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
    static float znum[6] = {
        2.442e-07,
        2.442e-06,
        1.099e-05,
        2.93e-05,
        5.127e-05,
        6.153e-05
    };
    static float zden[10] = {
        3.845e-02,
        -.508,
        3.045,
        -10.91,
        25.92,
        -42.64,
        49.28,
        -39.55,
        21.12,
        -6.789
    };
    if (setic==1){
        for (i=0;i<10;i++) states[i] = 4000.0*initval;
        return initval;
    }
    else{
        sumnum = sumden = 0.0;
        for (i=0;i<10;i++){
            sumden += states[i]*zden[i];
            sumnum += states[i]*znum[i<6?i:10-i];
            if (i<9) states[i] = states[i+1];
        }
        states[9] = invar-sumden;
        sumnum += states[9]*znum[0];
        return sumnum;
    }
}

If I got for the first time a value from ADC
Code:
float value, output; 
value = ADCgetFunction(); 
output=DigFil(value, initval,1);  //I dont know what I must set at initval 
theVector.push_back(output);  //in this vector I store the filter's output 

while(condition){ 
value=ADCgetFunction(); 
output=DigFil(value, initval,0);  //agai I dont know whats to set at initval
theVector.push_back(output);
qcustomplotFunction(theVector);

}
 

I dont know what state to use.

The variable state refers to the initial value stored in the filter, such as if an input was present there before you inject the signal to be filtered. You could arbitrate any initial values for this variable, as for example the average value of the input signal of your AD converter; note that you've defined the option "Externally Initialized" therefore the argument is present at the function. This entry could even be ommited in the code for most the applications where data streams are continuously processed.
 
The variable state refers to the initial value stored in the filter, such as if an input was present there before you inject the signal to be filtered. You could arbitrate any initial values for this variable, as for example the average value of the input signal of your AD converter; note that you've defined the option "Externally Initialized" therefore the argument is present at the function. This entry could even be ommited in the code for most the applications where data streams are continuously processed.

Thanks. So, do you mean the the filter function (called float DigFil(invar, states)) just can gets as input invar and the output sumnum can be store in another array (witch will be the filter output).

The vector (float *state), will gets the previous ADC values, right?

state[0] = invar1
state[1] = invar2
stat[2] = invar3


where the variable invar1 is the one before invar, invar2 is the one before invar1, etc.
this is correct?
 

Both filters that you posted are different not only in their behavior but also in the frequency of sampling that I particularly consider somewhat high for general purpose microcontrollers; by the way, the usage of the function is as follows:

Precisely for each interval equal to the sampling rate (20us = 1/50KHz in the first filter), you must call the function, which can be triggered by a Timer interrupt:

Code:
FilteredValue = DigFil (ADConverterResult(), states);

Where states can be an array of 4 numbers of type float, initializing with value 0 for example. Keep in mind that in real-time processing, you put one value and take another at the same rate, that is, each value coming from AD, this will generate a result to be loaded in FilteredValue.
 

It working in a worst way, the filter. Im doing something wrong.

Code:
 private double DigFil(double invar)
    {
        double sumnum, sumden;  int i=0;

        double [] znum = {0.0000002442, 0.000002442, 0.00001099, 0.0000293,0.00005127, 0.00006153 };
        double [] zden = { 0.03845, -0.508, 3.045, -10.91, 25.92, -42.64, 49.28, -39.55,21.12,-6.789 };

        sumnum = sumden = 0.0;
        for (i=0;i<10;i++){
            sumden += states[i]*zden[i];
            sumnum += states[i]*znum[i<6?i:10-i];
            if (i<9) states[i] = states[i+1];
        }
        states[9] = invar-sumden;
        sumnum += states[9]*znum[0];
        return sumnum;
    }

And this is the function which is call when there is a change in the sensor (an event, something like an interrup in the up abstraction level programing):

Code:
 public void onSensorChanged(SensorEvent event) {

    

        if(flag==0) //just to see if this is the first time
        {
            for(int i=0;i<10;i++)
            {
                states[i]=event.values[SensorManager.DATA_X];
            }
            flag=1;
        }
        else {
            double value;
            valor = DigFil((double) event.values[SensorManager.DATA_X]); //event.values[SensorManager.DATA_X]just get the sensor value
            this.tv1.setText("X = " + value);
            this.tv2.setText("X = "+event.values[SensorManager.DATA_X]);
        }
    }

value shows more variation than event.values[SensorManager.DATA_X] which its the sensor output
 

It is not yet clear whether you are performing a post-processing, or doing it in realtime. At first sight, the object oriented language you're using, suggest that could have an operacional system underneath, and worse, at a desktop computer. You might be aware that if you run this code within some multi thread environment, it should be able to instantiate this routine precisely at the interval defined in the specified sampling rate whenever the result is directed to the output interface.
 
thanks andre. What do you mean by post-processing?

It could be for example the case of processing the data stored at an input file, and saving the result in another file or redirecting to the output interface, that is, all this happening offline, instead of the datastream being filtered in realtime.
 

The vector (float *state), will gets the previous ADC values, right?

state[0] = invar1
state[1] = invar2
stat[2] = invar3
No, not with the controllable canonical form implemented in this filter.
Respectively your method of reloading state[] can't be expected to give useful results.

Controllable form.png

This code line clarifies what is loaded to state variable

Code:
states[3] = invar-sumden;

Usually state[] is zeroed on initialization, fits perfectly the steady state with zero input. You can nevertheless calculate init values for non-zero steady state, but you avoid it by simply running the filter with constant input over a number of cycles and let it settle.

- - - Updated - - -

You can calculate that preloading state[] with invar/(1 + ∑zden) gives a new steady state.
 
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top