// EWMA.ino: demo of noisy sine wave and EWMA smoothing on serial plotter
// Be sure to try the serial plotter graph while running.
// See https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
// DaveX 2022-02-17 CC BY-SA
//
// Wokwi deno at https://wokwi.com/arduino/projects/323865952429015635
// The Wokwi serial plotter is the graph icon in the lower right corner
// of the simulation window.
//global adjustables:
// EWMA Alpha parameter 0-1,
// smaller alpha is more smoothing,
// larger alpha is more repsonsive
float default_alpha = 0.1; // 0-1 smaller is more smoothing
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
const long repInterval = 10;
static unsigned long lastReport= - repInterval;
unsigned long now = millis();
const float alpha = default_alpha;
float x; // simulated process varaible
static float s = 0; //smoothed varaible
static float s2 = 0; //smoothed varaible
// 0.2Hz sinusoid + noise:
x = sin(2*PI*now/5000.0)+random(100)/100.0;
// Exponential Weighted Moving Average (EWMA):
// See https://en.wikipedia.org/wiki/Exponential_smoothing#Basic_(simple)_exponential_smoothing_(Holt_linear)
// or https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
// s = s + alpha * (x-s);
// FIR EWMA in one line:
// Fast Initial Response
// See https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
s = (s == 0.0 ? x : s + alpha * (x-s));
s2 = (s2 == 0.0 ? x : s2 + alpha*.1 * (x-s2));
if(now - lastReport >= repInterval){
lastReport += repInterval;
char buff[50];
//Serial.print(now );
//Serial.print( ' ');
Serial.print(x);
Serial.print( ' ');
Serial.print(s);
Serial.print( ' ');
Serial.print(s2);
Serial.println();
}
}