0
$\begingroup$

I use the FDAtool package to work with digital filters. I have always worked with coefficients in float format. I noticed that FDAtool always makes the b coefficients as integers. It also always adds gain before each filter section.

Here is an example of coefficients generated by FDAtool for a 4th order low pass filter, sampling frequency 1 kHz, cutoff frequency 100 Hz:

Section 1:
B0=1
B1=2
B2=1
A1= -1.320913434
A2= 0.6327387691
Gain= 0.07795634121
Section 2:
B0=1
B1=2
B2=1
A1= -1.048599601
A2= 0. 296140343
Gain= 0.06188519672

Next, this is how I implemented this filter on the microcontroller:

float   lp100_sek1_x[3],lp100_sek1_y[3],lp100_sek1_a[2]={-1.320913434, 0.6327387691},
        lp100_sek2_x[3],lp100_sek2_y[3],lp100_sek2_a[2]={-1.048599601, 0. 296140343};

//function call
        lp_filter(lp100_sek1_x,lp100_sek1_y,lp100_sek1_a,0.07795634121,((float)res_adc));
        lp_filter(lp100_sek2_x,lp100_sek2_y,lp100_sek2_a,0.06188519672,lp100_sek1_y[0]);

void lp_filter_one_section (float *x ,float *y ,float *aa ,float g ,float in)
{
    x[2]=x[1];
    x[1]=x[0];
    x[0]=in*g;
    y[2]=y[1];
    y[1]=y[0];
    y[0]=(x[0] + x[1]+x[1] + x[2] - aa[0]*y[1] - aa[1]*y[2]); //b0=1 b1=2 b2=1
}

Now I need to work with integer coefficients, and I don’t understand how to make the FDAtool package generate the integer coefficients I need, as well as generate coefficients without gain. The FDAtool package has a “Filter Arithmetic” tab, where you can configure parameters for generating integer coefficients, but I can’t figure out all the parameters that can be configured there (it’s not clear to me what the Input/Output and Filter Internals tabs are responsible for). I also don’t understand how to configure this package so that it does not generate gain before each filter section. With an integer implementation of the filter, this is very important for me, since when I multiply the input signal by gain and then shift it, I will lose the values after the decimal point every time.

$\endgroup$
5
  • $\begingroup$ uhm, so outside the lp_filter_one_section() function call, you are drawing the output sample from y[0] and putting it where it's supposed to go? $\endgroup$ Dec 11, 2023 at 22:55
  • $\begingroup$ @robert bristow-johnson I've added some clarifying information to the code. The output value for this filter will be stored in the variable lp100_sek2_y[0] $\endgroup$
    – red15530
    Dec 12, 2023 at 4:47
  • $\begingroup$ I can convert these coefficients to Q2.30 format, but because the FDAtool package always generates filter sections with gain, I have to multiply the input signal by gain and shift it to the right by 30 and lose decimal values before calculating the y[0] $\endgroup$
    – red15530
    Dec 12, 2023 at 4:53
  • $\begingroup$ You can apply the gain on the numerators directly. For example, a filter with coefficients [b0, b1, b2, a1, a2] and gain g is the same as a filter with coefficients [b0*g, b1*g, b2*g, a1, a2]. Is that what you are looking for? $\endgroup$
    – ZR Han
    Dec 12, 2023 at 6:31
  • $\begingroup$ @ZR Han Yes, exactly, I understood that. My problem is different. When I switched to integer mathematics, after calculating the new value of y[0], I discarded the fractional part by shifting to the right by 30 bits (Q2.30 format) to avoid overflow. In this example, I noticed that you can save these 30 bits of the fractional part and then add them when calculating the new y[0]. But I still see that my filters are not working correctly. $\endgroup$
    – red15530
    Dec 12, 2023 at 8:32

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.