Hello,
I am running the code below to filter an analog sensor. The code implements (if I have not done any coding error) an exponential moving average filter. I run the very same code on and Arduino UNO and a Teensy 3.2. On the Teensy the algorithm work as expected, while on the Arduino UNO not really: the behaviour is not consistent (with some spikes happening here and there rather than following always the original signal) and there is a strange negative offset:
I am very surprised, I can't explain why this happen. Any idea? Both the Arduino UNO and the Teensy 3.2 do not have a floating point unit. So the same code should lead to exactly the same output.
The issue is independent of the sensor in input, I tested with a FSR and an accelerometer, the behaviour persist.
I am running the code below to filter an analog sensor. The code implements (if I have not done any coding error) an exponential moving average filter. I run the very same code on and Arduino UNO and a Teensy 3.2. On the Teensy the algorithm work as expected, while on the Arduino UNO not really: the behaviour is not consistent (with some spikes happening here and there rather than following always the original signal) and there is a strange negative offset:
I am very surprised, I can't explain why this happen. Any idea? Both the Arduino UNO and the Teensy 3.2 do not have a floating point unit. So the same code should lead to exactly the same output.
The issue is independent of the sensor in input, I tested with a FSR and an accelerometer, the behaviour persist.
Code:
#define PERIOD_MICROSECS 1000
static unsigned long lastRead = 0;
int analog_pin = 0;
int analog_input0 = 0;
int analog_input0_filtered_fixed_point = 0;
//For fixed point I need to approximate the alpha using integer arithmetics
// The general process is alpha * 2^EMA_multiplication_factor_fixed_point : e.g. for a wanted alpha = 0.26: 0.26*2^7 =~ 33
int EMA_multiplication_factor_fixed_point = 7;
int EMA_alpha_fixed_point = 33; // 0.26 = 33/128 = 33 >> 7
//Fixed-point implementation
int low_pass_EMA_fixed_point(int x, int y, int alpha_fixed_point, int EMA_multiplication_factor_fixed_point){
y = y << EMA_multiplication_factor_fixed_point;
x = x << EMA_multiplication_factor_fixed_point;
y += (x - y) * alpha_fixed_point >> EMA_multiplication_factor_fixed_point;
return y >> EMA_multiplication_factor_fixed_point;
}
// ************************* //
void setup() {
Serial.begin(115200);
analog_input0_filtered_fixed_point = analogRead(analog_pin); //set EMA y for t=1
}
void loop() {
if (micros() - lastRead >= PERIOD_MICROSECS) {
lastRead += PERIOD_MICROSECS;
analog_input0 = analogRead(analog_pin); // read the input pin
analog_input0_filtered_fixed_point = low_pass_EMA_fixed_point(analog_input0, analog_input0_filtered_fixed_point, EMA_alpha_fixed_point, EMA_multiplication_factor_fixed_point);
//Check the original and filtered signals with the serial plotter
Serial.print(analog_input0);
Serial.print(" ");
Serial.println(analog_input0_filtered_fixed_point);
}
}