Digital noise filtering by use of Expotential Moving Average (EMA)Expotential Averaging is actually a standard 1-pins IIR filter. Its quite easy to use because there is only one parameter - in this page named alpha - to adjust. Starting with the algorithm
Its also known as a low-pass single pole IIR filter or a first order IIR filter (similar to an analog RC filter) Letting alpha …
Higher order digital filters - a commentHigher order digital filters is rather complicated. Another way to do it is by setting requirements to your freqyency response Here is a link to very pro homepage for designing digital filters: http://t-filter.engineerjs.com/ You can design rather complex filters but here we will stick to a low pass filter Here can shall
Result:
#ifndef SAMPLEFILTER_H_
#define SAMPLEFILTER_H_
/*
h file interface
FIR filter designed with
http://t-filter.appspot.com
sampling frequency: 2000 Hz
* 0 Hz - 400 Hz
gain = 1
desired ripple = 4 dB
actual ripple = 2.527326551960596 dB
* 500 Hz - 1000 Hz
gain = 0
desired attenuation = -40 dB
actual attenuation = -42.12980699449226 dB
*/
#define SAMPLEFILTER_TAP_NUM 25
typedef struct {
double history[SAMPLEFILTER_TAP_NUM];
unsigned int last_index;
} SampleFilter;
void SampleFilter_init(SampleFilter* f);
void SampleFilter_put(SampleFilter* f, double input);
double SampleFilter_get(SampleFilter* f);
#endif
//
#include "SampleFilter.h"
static double filter_taps[SAMPLEFILTER_TAP_NUM] = {
0.01750204006655566,
0.04104493059368818,
0.034156830746668504,
-0.0049733241015522045,
-0.03612243937234474,
-0.006716324848775206,
0.044618218414176056,
0.032288748464243164,
-0.05514177396520813,
-0.08478411312672213,
0.06134889205109059,
0.3112128706221355,
0.4355976849007708,
0.3112128706221355,
0.06134889205109059,
-0.08478411312672213,
-0.05514177396520813,
0.032288748464243164,
0.044618218414176056,
-0.006716324848775206,
-0.03612243937234474,
-0.0049733241015522045,
0.034156830746668504,
0.04104493059368818,
0.01750204006655566
};
void SampleFilter_init(SampleFilter* f) {
int i;
for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i)
f->history[i] = 0;
f->last_index = 0;
}
void SampleFilter_put(SampleFilter* f, double input) {
f->history[f->last_index++] = input;
if(f->last_index == SAMPLEFILTER_TAP_NUM)
f->last_index = 0;
}
double SampleFilter_get(SampleFilter* f) {
double acc = 0;
int index = f->last_index, i;
for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) {
index = index != 0 ? index-1 : SAMPLEFILTER_TAP_NUM-1;
acc += f->history[index] * filter_taps[i];
};
return acc;
}
NOTE: the code is open for optimization and there are many float operations. But an impressive tool Links - just garbage can
For the interested people some links
|