muwerk Scheduler Library
A low-resource cooperative scheduler with MQTT-like queues for Arduinos, ATtiny up to ESP32
Loading...
Searching...
No Matches
sensors.h
1#pragma once
2
3#include "ustd_platform.h"
4#include "ustd_array.h"
5
6namespace ustd {
7#define SENSOR_VALUE_INVALID -999999.0
8
51 public:
52 unsigned int noVals = 0;
53 unsigned int smoothInterval;
54 unsigned int pollTimeSec;
55 double sum = 0.0;
56 double eps;
57 bool first = true;
58 double meanVal = 0;
59 double lastVal = SENSOR_VALUE_INVALID;
60 unsigned long last;
61
62 sensorprocessor(unsigned int smoothInterval = 5, int unsigned pollTimeSec = 60,
63 double eps = 0.1)
64 : smoothInterval{smoothInterval}, pollTimeSec{pollTimeSec}, eps{eps} {
74 reset();
75 }
76
77 bool filter(double *pvalue) {
88 meanVal = (meanVal * noVals + (*pvalue)) / (noVals + 1);
89 if (noVals < smoothInterval) {
90 ++noVals;
91 }
92 double delta = lastVal - meanVal;
93 if (delta < 0.0) {
94 delta = (-1.0) * delta;
95 }
96 if (delta > eps || first) {
97 first = false;
98 lastVal = meanVal;
99 *pvalue = meanVal;
100 last = millis();
101 return true;
102 } else {
103 if (pollTimeSec != 0) {
104 if (timeDiff(last, millis()) > pollTimeSec * 1000L) {
105 *pvalue = meanVal;
106 last = millis();
107 lastVal = meanVal;
108 return true;
109 }
110 }
111 }
112 return false;
113 }
114
115 bool filter(long *plvalue) {
126 double tval = (double)*plvalue;
127 bool ret = filter(&tval);
128 if (ret) {
129 *plvalue = (long)tval;
130 }
131 return ret;
132 }
133
134 void reset() {
136 noVals = 0;
137 sum = 0.0;
138 first = true;
139 meanVal = 0;
140 lastVal = SENSOR_VALUE_INVALID;
141 last = millis();
142 }
143
144 void update(unsigned int _smoothInterval = 5, int unsigned _pollTimeSec = 60,
145 double _eps = 0.1) {
158 smoothInterval = _smoothInterval;
159 pollTimeSec = _pollTimeSec;
160 eps = _eps;
161 reset();
162 }
163};
164
213template <typename T_FLOAT> class numericFunction {
214 public:
215 ustd::array<T_FLOAT> x, y;
216 T_FLOAT minX, minY, maxX, maxY;
217 unsigned int len;
218 bool dir;
219 bool extrapolate;
220 numericFunction(const T_FLOAT px[], const T_FLOAT py[], unsigned int count,
221 bool _extrapolate = false) {
231 extrapolate = _extrapolate;
232 len = 0;
233 for (unsigned int i = 0; i < count; i++) {
234 if (i > 0) {
235 // enforce strict monotony:
236 if (px[i] <= x[len - 1])
237 continue;
238 if (py[i] == y[len - 1])
239 continue;
240
241 if (len == 1)
242 dir = (py[i] > y[len - 1]);
243 if ((py[i] > y[len - 1]) != dir)
244 continue;
245 }
246 x[len] = px[i];
247 y[len] = py[i];
248 if (i == 0 || minX > x[len])
249 minX = x[len];
250 if (i == 0 || minY > y[len])
251 minY = y[len];
252 if (i == 0 || maxX < x[len])
253 maxX = x[len];
254 if (i == 0 || maxY < y[len])
255 maxY = y[len];
256 ++len;
257 }
258 }
259
260 static T_FLOAT min(ustd::array<T_FLOAT> ar) {
264 T_FLOAT minVal = 0.0;
265 for (unsigned int i = 0; i < ar.length(); i++) {
266 if (i == 0 || ar[i] < minVal)
267 minVal = ar[i];
268 }
269 return minVal;
270 }
271
272 static T_FLOAT max(ustd::array<T_FLOAT> ar) {
276 T_FLOAT maxVal = 0.0;
277 for (unsigned int i = 0; i < ar.length(); i++) {
278 if (i == 0 || ar[i] > maxVal)
279 maxVal = ar[i];
280 }
281 return maxVal;
282 }
283
284 static void rescale(ustd::array<T_FLOAT> *par, T_FLOAT *pminX, T_FLOAT *pmaxX, T_FLOAT newMin,
285 T_FLOAT newMax) {
300 T_FLOAT dx;
301 T_FLOAT newMinX, newMaxX;
302 unsigned int len = (*par).length();
303 if (len < 2 || *pminX == *pmaxX)
304 dx = 1;
305 else
306 dx = (*pmaxX - *pminX);
307 T_FLOAT ndx = newMax - newMin;
308 for (unsigned int i = 0; i < len; i++) {
309 T_FLOAT xi = (*par)[i];
310 (*par)[i] = (xi - *pminX) / dx * ndx + newMin;
311 if (i == 0 || newMinX > xi)
312 newMinX = xi;
313 if (i == 0 || newMaxX < xi)
314 newMaxX = xi;
315 }
316 *pminX = newMinX;
317 *pmaxX = newMaxX;
318 }
319
320 void rescaleX(T_FLOAT newMin, T_FLOAT newMax) {
326 rescale(&x, &minX, &maxX, newMin, newMax);
327 }
328 void rescaleY(T_FLOAT newMin, T_FLOAT newMax) {
334 rescale(&y, &minY, &maxY, newMin, newMax);
335 }
336
337 static int linsearch(ustd::array<T_FLOAT> &ar, T_FLOAT x) {
346 int a = 0, b = ar.length() - 1, n;
347 while (b - a > 1) {
348 n = (a + b) / 2;
349 if (ar[n] == x)
350 return n;
351 if (x > ar[n])
352 a = n;
353 else
354 b = n;
355 }
356 return a;
357 }
358
359 T_FLOAT interpol(T_FLOAT xi) {
363 T_FLOAT dx1, dx2, dy;
364 if (len == 0)
365 return 0.0;
366 if (len == 1)
367 return x[0];
368 if (xi < minX) {
369 if (!extrapolate)
370 return y[0];
371 else {
372 dx1 = x[0] - xi;
373 dx2 = x[1] - x[0];
374 dy = y[1] - y[0];
375 return y[0] - dy / dx2 * dx1;
376 }
377 }
378 if (xi > maxX) {
379 if (!extrapolate)
380 return y[len - 1];
381 else {
382 dx1 = x[len - 1] - x[len];
383 dx2 = xi - x[len - 1];
384 dy = y[len - 1] - y[len - 2];
385 return y[len - 1] + dy / dx1 * dx2;
386 }
387 }
388 unsigned int n = linsearch(x, xi);
389 if (n >= len - 1)
390 return y[len - 1];
391 dx1 = x[n] - x[n + 1];
392 dx2 = xi - x[n];
393 dy = y[n + 1] - y[n];
394 float yi = y[n] - dy / dx1 * dx2;
395 return yi;
396 }
397
398 T_FLOAT operator()(T_FLOAT x) {
402 return interpol(x);
403 }
404};
405
406} // namespace ustd
muwerk numericFunction class
Definition sensors.h:213
static int linsearch(ustd::array< T_FLOAT > &ar, T_FLOAT x)
Definition sensors.h:337
void rescaleY(T_FLOAT newMin, T_FLOAT newMax)
Definition sensors.h:328
static void rescale(ustd::array< T_FLOAT > *par, T_FLOAT *pminX, T_FLOAT *pmaxX, T_FLOAT newMin, T_FLOAT newMax)
Definition sensors.h:284
T_FLOAT interpol(T_FLOAT xi)
Definition sensors.h:359
T_FLOAT operator()(T_FLOAT x)
Definition sensors.h:398
static T_FLOAT min(ustd::array< T_FLOAT > ar)
Definition sensors.h:260
static T_FLOAT max(ustd::array< T_FLOAT > ar)
Definition sensors.h:272
void rescaleX(T_FLOAT newMin, T_FLOAT newMax)
Definition sensors.h:320
numericFunction(const T_FLOAT px[], const T_FLOAT py[], unsigned int count, bool _extrapolate=false)
Definition sensors.h:220
muwerk sensorprocessor class
Definition sensors.h:50
void reset()
Definition sensors.h:134
bool filter(long *plvalue)
Definition sensors.h:115
void update(unsigned int _smoothInterval=5, int unsigned _pollTimeSec=60, double _eps=0.1)
Definition sensors.h:144
bool filter(double *pvalue)
Definition sensors.h:77
sensorprocessor(unsigned int smoothInterval=5, int unsigned pollTimeSec=60, double eps=0.1)
Definition sensors.h:62
The muwerk namespace.
Definition console.h:15
unsigned long timeDiff(unsigned long first, unsigned long second)
Definition muwerk.h:44