Hello,
I am trying to implement a butterworth lowpass filter with a circular buffer. The code below does not really filter as intended and I am not really able to understand what is wrong. Any suggestion?
#define PERIOD_MICROSECS 1000
static uint32_t lastRead = 0;
int analog_pin = 0;
int32_t analog_input0 = 0;
double analog_input0_lp_filtered = 0;
// The coefficients are calculated offline. I set the sample frequency to 1000 Hz, the cutoff to 50 Hz.
// The filter has order = 4.
double c[] = {0.000416599204407, 0.001666396817626, 0.002499595226440, 0.001666396817626, 0.000416599204407};
double d[] = {1.000000000000, -3.180638548875, 3.861194348994, -2.112155355111, 0.438265142262};
int m = 10;
double x[10];
double y[10];
int n = 0;
double lp_butterworth(double input_sample, double *x, double *y, int m, int n)
{
x[n] = input_sample;
y[n] = d[0] * x[n] + d[1] * x[(n-1+m)%m] + d[2] * x[(n-2+m)%m] + d[3] * x[(n-3+m)%m] + d[4] * x[(n-4+m)%m]
- c[1] * y[(n-1+m)%m] - c[2] * y[(n-2+m)%m] - c[3] * y[(n-3+m)%m] - c[4] * y[(n-4+m)%m];
return y[n];
}
// ************************* //
void setup() {
Serial.begin(115200);
}
void loop() {
if (micros() - lastRead >= PERIOD_MICROSECS) {
lastRead += PERIOD_MICROSECS;
analog_input0 = analogRead(analog_pin);
analog_input0_lp_filtered = lp_butterworth(analog_input0, x, y, m, n);
n = (n + 1) % m;
//Check the original and filtered signals with the serial plotter
Serial.print(analog_input0);
Serial.print(" ");
Serial.println(analog_input0_lp_filtered);
}
}