|
|
@@ -1,25 +1,16 @@
|
|
|
+#include <math.h>
|
|
|
#include "sensor_ema.h"
|
|
|
-
|
|
|
-void SensorEMA_setup(SensorEMA_t* ctx, float alpha, unsigned long interval_ms) {
|
|
|
+void SensorEMA_setup(SensorEMA_t* ctx, float alpha, unsigned long interval_ms, float sentinel)
|
|
|
+{
|
|
|
ctx->alpha = alpha;
|
|
|
- ctx->update_interval_ms = interval_ms;
|
|
|
- ctx->current_ema = 0.0;
|
|
|
- ctx->last_update_time = 0;
|
|
|
- ctx->has_valid_data = false;
|
|
|
+ ctx->interval_ms = interval_ms;
|
|
|
+ ctx->ema = 0.0;
|
|
|
+ ctx->last_write = 0;
|
|
|
+ ctx->sentinel = sentinel;
|
|
|
|
|
|
- // Run user init if provided
|
|
|
if (ctx->fn_init) {
|
|
|
ctx->fn_init();
|
|
|
}
|
|
|
-
|
|
|
- // Seed EMA with first reading if possible
|
|
|
- if (ctx->fn_read) {
|
|
|
- float val = ctx->fn_read();
|
|
|
- if (val >= 0) {
|
|
|
- ctx->current_ema = val;
|
|
|
- ctx->has_valid_data = true;
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
void SensorEMA_loop(SensorEMA_t* ctx, unsigned long now) {
|
|
|
@@ -27,17 +18,16 @@ void SensorEMA_loop(SensorEMA_t* ctx, unsigned long now) {
|
|
|
|
|
|
float raw = ctx->fn_read();
|
|
|
|
|
|
- if (raw >= 0.0) {
|
|
|
- if (!ctx->has_valid_data) {
|
|
|
- ctx->current_ema = raw;
|
|
|
- ctx->has_valid_data = true;
|
|
|
- } else {
|
|
|
- ctx->current_ema = (raw * ctx->alpha) + (ctx->current_ema * (1.0 - ctx->alpha));
|
|
|
- }
|
|
|
+ bool invalid = isnan(ctx->sentinel) ? isnan(raw) : raw == ctx->sentinel;
|
|
|
+
|
|
|
+ if (!invalid)
|
|
|
+ {
|
|
|
+ ctx->ema = (raw * ctx->alpha) + (ctx->ema * (1.0 - ctx->alpha));
|
|
|
}
|
|
|
|
|
|
- if (now - ctx->last_update_time >= ctx->update_interval_ms) {
|
|
|
- ctx->last_update_time = now;
|
|
|
- ctx->fn_write(ctx->current_ema);
|
|
|
+ if (now - ctx->last_write >= ctx->interval_ms) {
|
|
|
+ ctx->last_write = now;
|
|
|
+ ctx->fn_write(invalid ? ctx->sentinel : ctx->ema);
|
|
|
}
|
|
|
}
|
|
|
+
|