You might be overthinking this.
The math notation is sometimes different from the source code.
Calculating the average with a low-pass filter is like this:
Average(T) = 0.99 * Avarage(T-1) + 0.01 * newValue
The newValue influences the average for 1%.
In the source code, the existing average can be taken, then add 1% of the new value and then store it in the same average variable.
average = 0.99 * average + 0.01 * newValue;
That average can be seen as the DC-offset, so the result is:
result = newValue - average;
Add a setup() and loop() and the sketch is finished:
float average;
const float strength = 0.99;
void setup()
{
}
void loop()
{
float newValue = (float) analogRead(A0);
average = (strength * average) + ((1.0-strength) * newValue);
float result = newValue - average;
delay(10);
}
To make it visual, the Serial Plotter of the Arduino IDE can be used. I used the Wokwi simulator with this sketch:
// Forum: https://forum.arduino.cc/t/gettin-low-pass-filter-into-arduino-sketch/1105548
// This Wokwi project:
//
// The heart beat sensor is not released yet, it may change.
//
// Not using:
// w(t)=x(t)+∝∗w(t−1)
// y(t)=w(t)−w(t−1)
// y(t): is the output of the filter
// x(t): current input/value
// w(t): intermediate value, acts like the history of the DC value
// α: is the response constant of the filter
// If α = 1 then everything passes through
// If α = 0 then nothing passes through
//
// Using a standard low-pass filter instead:
// average = strength * average + (1 - strength) * newVale
float average;
const float strength = 0.995;
void setup()
{
Serial.begin(115200);
// Print 1 second where all the signals are zero.
// This is only to make it look better on the Serial Plotter.
// Not for the real application.
for(int i=0; i<100; i++)
{
Serial.println( "0.0,0.0,0.0,0.0");
delay(10);
}
}
void loop()
{
float newValue = (float) analogRead(A0);
average = (strength * average) + ((1.0-strength) * newValue);
float result = newValue - average;
Serial.print( "0.0"); // Green, show where the X-axis is
Serial.print( ",");
Serial.print( newValue); // Orange
Serial.print( ",");
Serial.print( average); // Violet
Serial.print( ",");
Serial.print( result); // Cyan
Serial.println();
// A quick and dirty way to sample at regular intervals
delay(10);
}
Try the sketch in Wokwi:
Green line: X-axis
Orange line: Heart Beat
Pink line: Average
Cyan line: Result: Heart Beat without DC-offset.
