# Lynn's integer filter has a linearly increasing trend

I have a PPG signal sampled at 50Hz and I want to filter the signal using Lynn's integer filter. I.e

$$H(z)=\frac{(1-1/z^m)^2}{(1-1/z)^2}$$

Cutoff frequency is 5Hz, so this gives value of $m \approx 3$ (it's a 3db cutoff) and hence the difference equation is

$$y[n]-2y[n-1]+y[n-2]=x[n]-2x[n-3]+x[n-6]$$

Now applying this filter to the signal, my signal is filtered but there is some linear component that's making baseline to increase linearly.

Any suggestion where I am going wrong?

Data is processed on cortex M0 based bluetooth module and transmitted to phone. I am plotting csv file in Matlab.

Code of cortex M0:

float process_ppg_iir(uint16_t raw_data_ppg)
{
int b0=1, b1=-2, b2=1, a1=-2;
int a2 = 1;

if( global_sample_counter <= 7-1 )
{
ppg_raw[global_sample_counter] = raw_data_ppg;
if(global_sample_counter <=3-1)
ppg_processed[global_sample_counter] = raw_data_ppg;
global_sample_counter++;
}
else
{
// sfit values to left

int i=0;

for(i=0 ;i <=5;i++)
{
ppg_raw[i] = ppg_raw[i+1];
}

ppg_processed[0] = ppg_processed[1];
ppg_processed[1] = ppg_processed[2];

ppg_raw[6] = raw_data_ppg;
ppg_processed[2] = (b0*ppg_raw[6]+b1*ppg_raw[3]+b2*ppg_raw[0])- a1*ppg_processed[1]-a2*ppg_processed[0];

}
return ppg_processed[2];
}

• What does your input signal look like? You might include the MATLAB code for your simulation since it looks like that's what you're using. – Jason R Sep 24 '15 at 12:43
• input signal is a noisy ppg signal , data is processed on cortex M0 based bluetooth module and transmitted to phone , i am just plotting csv file on matlab – Mohit Maheshwari Sep 24 '15 at 13:14

Your lowpass filter is the cascade of two 3-point moving average filters each implemented as recursive running sum filters. (It's gain at 5 Hz is -2.4 dB.) I can't interpret your code but I'm guessing your feedback operations are incorrect. To test your code, make sure all accumulator variables are set to zero. Then apply a unit impulse to your filter and see if its impulse response is [1, 2, 3, 2, 1, 0, 0, 0, ...] as it should be. If you change your $H(z)$ exponents from $2$ to $1$, then your filter's impulse response should be [1, 1, 1, 0, 0,0, ...]. If your impulse responses do not agree with the above, then finding out why they don't will solve your problem.

This is a FIR filter implemented as a recursive filter (rather than a transversal filter with all 9 coefficients).

Note that $H(z)$ can be written as the cascade of two backward differences and two accumulators:

$$H(z) = (1-z^{-3}) \cdot (1-z^{-3}) \cdot \frac{1}{1-z^{-1}} \cdot \frac{1}{1-z^{-1}}$$

There are two zero-pole cancellations at $z=1$, which make the overall system stable (by removing the poles introduced by the accumulators).

In this case, it is very important to start the filter with the correct initial conditions (for example, $y[n]=0 \; \forall n<0$).

You are starting your filter with arbitrary values for the unit delays. This is inside the if statement, where you fill initial conditions with the actual incoming data (e.g. ppg_processed[] = raw_data_ppg). This is wrong.

• i tried putting y(n) = 0 it's still showing a linear trend – Mohit Maheshwari Sep 29 '15 at 14:29
• How are the state variables ppg_raw[] and ppg_processed[] declared? I see that your input sample is of type unsigned (uint16), and the output is cast to float. The state variables should be signed integers. Do you get any warnings from the compiler? – Juancho Sep 30 '15 at 18:30
• yes the sensor gives uint16 value , and ppg_raw[] and ppg_processed[] are the zero initialised 32 bit float array . no warnings from compiler – Mohit Maheshwari Oct 1 '15 at 7:57