I want to filter deviations from an ADC over time (low pass), not very critical. So I first tried exponential averaging, something like y= (7*y+x)/8. That gave useful results, but there is an obvious rounding issue (no increase as long as x smaller than y+8, decrease if x smaller than y). Adding +4 doesn't really solve the problem.
So I implemented a fixed-point lowpass Butterworth third order filter, with various cutoff frequencies, based on coefficients extracted from http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html (unfortunately down since a few months).
The code looks as follows for 0.033 sampling cutoff
byte dtTI, // filter input (0 newest) dtTIFast; // filter output, =y, =8 bit decimals // dtTIFast[2,4,6]= previous filter outputs dtTIFast=dtTIFast; dtTIFast=dtTIFast; dtTIFast=dtTIFast; dtTIFast=dtTIFast; dtTIFast=dtTIFast; dtTIFast=dtTIFast; unsigned long modifier = 30UL*64*(dtTI + dtTI + 3*dtTI + 3*dtTI); modifier += 84739UL*(dtTIFast/4+64*dtTIFast); modifier -= 73839UL*(dtTIFast/4+64*dtTIFast); modifier += 21628UL*(dtTIFast/4+64*dtTIFast); dtTIFast=modifier>>21; dtTIFast=modifier>>13; // No need to add 2^12, 0.0004deg
The output seemed to give correct results at first, but if I iterate the filter 50 times with the same input(s), I see it keeps oscillating instead of converging to a steady value, and not centered around the x input. For other values (for example 0.001 cutoff), its way worse !
Can you tell me where I'm wrong ? I checked that the sum of my coefficient is 32768, and it looks like there can't be any overflow. I use 14bits y values now, and the real values of coeffs are 2.586028659, -2.253398256 0.660048953 and 0,000915081. Should I need more precision ?
Thanks for your help