0
$\begingroup$

I am attempting to implement a cascaded IIR filter in MATLAB. I used fdatool to design the filter and exported it as an object, Hd.

In my script, I import a log file of data I captured and store my data in a vector called serial. I then use MATLAB's filter(Hd,serial) to filter it and plot the results. The filter works well.

In order to check and improve my understanding of how to implement this filter in real life (before I attempt to embed it using C) I want to filter my data using my own code and compare the results with those obtained using MATLAB's filter function

My Hd object consists of the following parameters: SOSMatrix:

0.25, 0.5, 0.25, 1, -1.9513, 0.95189
0.25, 0.5, 0.25, 1, -1.9584, 0.95907
0.25, 0.5, 0.25, 1, -1.9718, 0.97246
0.25, 0.5, 0.25, 1, -1.9896, 0.99024

Scale Values:

1.4055e13
1
1
1
1

In order to implement my filter I have stored each line of my SOS matrix under the following titles:

    Section1 = [0.25 0.5 0.25 1 -1.9513 0.95189]
    Section2 = [0.25 0.5 0.25 1 -1.9584 0.95907]
    Section3 = [0.25 0.5 0.25 1 -1.9718 0.97246]
    Section4 = [0.25 0.5 0.25 1 -1.9896 0.99024]

My attempt at implementing the filter is given below (as I said earlier, my input data is called "serial"

First I initialize the outputs from each of the 4 stages to zeros...

    output_section_1=zeros(size(serial,1),1);
    output_section_2=zeros(size(serial,1),1);
    output_section_3=zeros(size(serial,1),1);
    output_section_4=zeros(size(serial,1),1);

I multiply my input (serial) by the first scale factor. As the rest of the values are 1, I don't bother multiplying any of the other sections.

    serial=serial*1.4055e13;

Then I run a loop for my filter...

    for i=10:size(serial,1)

% Section 1
output_section_1(i)=Section1(1)*serial(i) + Section1(2)*serial(i-1) + Section1(3)*serial(i-2) - Section1(5)*serial(i-1) - Section1(6)*serial(i-2);

% Section 2
output_section_2(i)=Section2(1)*output_section_1(i) + Section2(2)*output_section_1(i-1) + Section2(3)*output_section_1(i-2) - Section2(5)*output_section_1(i-1) - Section2(6)*output_section_1(i-2);

% Section 3
output_section_3(i)=Section3(1)*output_section_2(i) + Section3(2)*output_section_2(i-1) + Section3(3)*output_section_2(i-2) - Section3(5)*output_section_2(i-1) - Section3(6)*output_section_2(i-2);

% Section 4
output_section_4(i)=Section4(1)*output_section_3(i) + Section4(2)*output_section_3(i-1) + Section4(3)*output_section_3(i-2) - Section4(5)*output_section_3(i-1) - Section4(6)*output_section_3(i-2);
    end

The output obtained using MATLAB's filter function looks good and is nice and smooth as would be expected.

The output obtained using my own implementation looks just like the input (noisy) except that the values have changed and there is an initialization at the beginning.

I'm sure I've made a very schoolboy mistake but I cannot see where I have gone wrong.

Any advice anyone could give me would be much appreciated.

$\endgroup$
0
$\begingroup$

You did not implement a recursive filter, but a non-recursive filter. Note that in your implementation each output only depends on possibly delayed input values, whereas in a recursive filter, the output depends on delayed input and output values.

If the coefficients of one second-order section are given by $[b_0, b_1, b_2, 1, a_1, a_2]$, then if $x[n]$ is the input sequence, the output sequence $y[n]$ is computed as

$$y[n]=b_0x[n]+b_1x[n-1]+b_2x[n-2]-a_1y[n-1]-a_2y[n-2]$$

$\endgroup$
  • 1
    $\begingroup$ Ha ha, yes indeed, I knew it would be a silly mistake. Thank you for spotting my error. I changed it to include the outputs and it works correctly. $\endgroup$ – David Graham Jun 8 '15 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.