digital low pass filter
ManAtWork
Posts: 2,176
in Propeller 1
Until now, I have used simple moving average filtering to suppress noise from sensor signals because it is easy to implement. Although it is good for signal processing because it has no overshot and constant phase delay its transfer function is not ideal. It has large "humps" in the stop band.
I think a well designed FIR or IIR filter can do much better and give better stop band attenuation for the same delay. Unfortunatelly, the propeller is not the best choice for general FIR or IIR filters because multiplications are expensive, at least for PASM implementations required for high speed.
Does anybody know a good "trick" for improved low pass filtering? Cascade multiple moving average filters? Clever adjustment of the coefficiens of an IIR filter so that only a few shifts/adds would do?
I have a PID control loop with a noisy sensor input signal. A larger averaging window size reduces the noise but also adds delay which is not good for the stability of the PID loop. I have to find the best compromise of low noise vs. delay. I have no influence on the analogue side of the sensor circuit. The sensor is "digital" i.e. has a built-in ADC. I receive the values via serial communication with 20kHz sample rate and 12 bits resolution.
I think a well designed FIR or IIR filter can do much better and give better stop band attenuation for the same delay. Unfortunatelly, the propeller is not the best choice for general FIR or IIR filters because multiplications are expensive, at least for PASM implementations required for high speed.
Does anybody know a good "trick" for improved low pass filtering? Cascade multiple moving average filters? Clever adjustment of the coefficiens of an IIR filter so that only a few shifts/adds would do?
I have a PID control loop with a noisy sensor input signal. A larger averaging window size reduces the noise but also adds delay which is not good for the stability of the PID loop. I have to find the best compromise of low noise vs. delay. I have no influence on the analogue side of the sensor circuit. The sensor is "digital" i.e. has a built-in ADC. I receive the values via serial communication with 20kHz sample rate and 12 bits resolution.
Comments
1. Peak suppression: Collect n samples like your moving average, throw away the largest and smallest and compute the average for the remaining values. This eliminates any peaks (in both directions) which otherwise can only be suppressed by a long averaging filter.
2. "Trend filter": This is good for slow changing noisy signals, e.g temperature. Compare the newest value with the last. If it is larger for at least N samples take it (or the an average of this and the old one). The same for the newest being lower than the last for N samples. If the direction of change was not stable for N samples, just keep the old value.
If you have noisy data, this will keep the noise out because changes continuously go in both directions. If there is a trend in one direction, this will follow this trend quickly.
1 and 2 can be combined.
If there is a strong "trend" (change per sample higher than noise) the newest sample will always be the lowest or highest, so filter 1. is completely ineffective. Same for 2. the filter doesn't suppress anything if the change is higher than the noise component.
This becomes even worse when the noise is not "white" but has dominating frequencies (resonances, 50/60Hz and harmonic EMI...). Then, the slope of the signal becomes lower/higher periodically so that the filter response flips forth and back (latch effect). This makes the noise actually worse for the PID control loop because a smooth waveform is transformed into a stair shape with steep slopes and more energy in the high order harmonics.
I think the peak and/or trend filter should be combined with a standard (bessel type or similar) low pass filter. The latch effect could possibly be avoided if the filter is applied to the differentiation of the signal and the output is integrated to restore the original signal.
http://www.pulsedpower.net/Info/RC/RC_Filter.htm#Numerical_Low-Pass_RC_Filter
If you are getting a stream of data, just pick an alpha factor like .25 and then:
Current value = .75*old value +.25* new sample
I think anything that does a "hard decision" of dropping a sample or not is "evil" and should be avoided. Each sample is composed of a true signal part and a noise part. If we completely drop a sample we also throw away the signal part producing unwanted artefacts in the signal shape.
A dynamic limiter would be much better. If we have a robot and a distance sensor, for example, we know that the robot or the sensed object can't jump but has inertia and therefore limited velocity and acceleration. If there is a sudden jump in the sensed distance we can limit the velocity and acceleration to realistic values. This way we cancel out unrealistic peaks but still keep the trend without adding too much delay.
there are some available online
design a filter you like.
then you can approximate the constant filter coefficients by power of 2 factors
which allow shift/add implementation to a level you like.
Being a compromise between exact representation of the filter coefficients and the effort to implement it.
You can even check the resulting approximation by using the
approximated coefficients in the filter simulation.
Of course this is them 'hard-coded'. No easy change of filter coefficients.
I read a very good example long ago using an ATtiny as a digital filter processor
for a current regulator in a ~8 A power supply.
- can't find it a.t.m. sorry
here it is - found it on my disk: .... hmmm ... how do I make an attachment?
here the link:
ww1.microchip.com/downloads/en/DeviceDoc/current_supply.pdf
just had a look again ... it is not really a FIR / IIR application here but maybe give you a hint
https://forums.parallax.com/discussion/133173/fir2pasm-automatic-fir-filter-code-generator/p1
-Phil
"My wife thinks I'm cheating on her with a woman at work, but I told her, there's virtually nothing between us... so she has virtually nothing worry about"
My boss caught the two of us on the security camera. I explained it wasn't what it looked like. We were virtually fully clothed.
I applied for unemployment, but the unemployment department turned me down. They said losing my job was my own fault. I'm going to appeal because I was virtually blameless.
My wifes divorce lawyer got my car, my house and even my dog. Now I'm living in a cardboard box and eating out of the trash. I'm virtually homeless and virtually penniless.
The guy in the box next to mine said he knew a guy who would pay me a bunch of money to bring something back from Mexico for him. It was virtually risk free.
I was accused of smuggling 50kg of cocain across the Mexican border in the gas tank of my old pickup truck, but I'm virtually innocent"
I was convicted and sentenced to 30 years in a federal prison, but I'll be out in virtually no time at all.
The word "virtually" can make quite a difference...
-Phil
Could be moved, but being in the wrong thread made me smile also.
And basically Michael_Michalski made a very valid statement here...
Enjoy
Mike
That will approach a Gaussian filter, which might be exactly what you want. :cool:
Long moving average filters can be efficiently computed by a difference equation. If you wanted to average 100 samples, add the new sample to an accumulator and subtract the sample you added 100 steps ago. You could start with 4 filters of length 4. I don't know if it's worth it to do the difference equation for filters that short.
Here's a quick Octave script to simulate a filter like this:
their responses, if you ever played with Python's matplotlib and numpy you'll realise this makes it pretty
easy to experiment with filter design.