From d7983c9d437e44ce5cbdac6ed68575e5af47b36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Thu, 28 Dec 2017 12:43:54 +0100 Subject: [PATCH] Changed filters to use arrays instead of vectors --- code/espurna/filters/BaseFilter.h | 41 +++-------------- code/espurna/filters/MaxFilter.h | 21 ++++++++- code/espurna/filters/MedianFilter.h | 52 +++++++++++++++++----- code/espurna/filters/MovingAverageFilter.h | 47 +++++++------------ code/espurna/sensor.ino | 6 +++ 5 files changed, 89 insertions(+), 78 deletions(-) diff --git a/code/espurna/filters/BaseFilter.h b/code/espurna/filters/BaseFilter.h index ac693bb8..f337c7a3 100644 --- a/code/espurna/filters/BaseFilter.h +++ b/code/espurna/filters/BaseFilter.h @@ -7,45 +7,18 @@ #pragma once -#include - class BaseFilter { public: - - BaseFilter() { - } - - ~BaseFilter() { - } - - virtual void add(double value) { - _data.push_back(value); - } - - virtual unsigned char count() { - return _data.size(); - } - - virtual void reset() { - _data.clear(); - } - - virtual double max() { - double max = 0; - for (unsigned char i = 1; i < _data.size(); i++) { - if (max < _data[i]) max = _data[i]; - } - return max; - } - - virtual double result() { - return 0; - } + virtual void add(double value); + virtual unsigned char count(); + virtual void reset(); + virtual double result(); + virtual void resize(unsigned char size); + unsigned char size() { return _size; }; protected: - - std::vector _data; + unsigned char _size; }; diff --git a/code/espurna/filters/MaxFilter.h b/code/espurna/filters/MaxFilter.h index 4121787d..bf660322 100644 --- a/code/espurna/filters/MaxFilter.h +++ b/code/espurna/filters/MaxFilter.h @@ -7,17 +7,34 @@ #pragma once -#include #include "BaseFilter.h" class MaxFilter : public BaseFilter { public: + void add(double value) { + if (value > _max) _max = value; + } + + unsigned char count() { + return 1; + } + + void reset() { + _max = 0; + } + double result() { - return max(); + return _max; } + void resize(unsigned char size) {} + + protected: + + double _max = 0; + }; #endif // SENSOR_SUPPORT diff --git a/code/espurna/filters/MedianFilter.h b/code/espurna/filters/MedianFilter.h index 06295c85..98376e3f 100644 --- a/code/espurna/filters/MedianFilter.h +++ b/code/espurna/filters/MedianFilter.h @@ -13,23 +13,37 @@ class MedianFilter : public BaseFilter { public: - virtual void reset() { + ~MedianFilter() { + if (_data) delete _data; + } - // When resetting we get the last value - // and make it the first of the new series - double last = _data.empty() ? 0 : _data.back(); - _data.clear(); - add(last); + void add(double value) { + if (_pointer <= _size) { + _data[_pointer] = value; + _pointer++; + } + } + + unsigned char count() { + return _pointer; + } + void reset() { + if (_pointer > 0) { + _data[0] = _data[_pointer-1]; + _pointer = 1; + } else { + _pointer = 0; + } } - virtual double result() { + double result() { double sum = 0; - if (_data.size() > 2) { + if (_pointer > 2) { - for (unsigned char i = 1; i <= _data.size() - 2; i++) { + for (unsigned char i = 1; i <= _pointer - 2; i++) { // For each position, // we find the median with the previous and next value @@ -47,11 +61,11 @@ class MedianFilter : public BaseFilter { } - sum /= (_data.size() - 2); + sum /= (_pointer - 2); - } else if (_data.size() > 0) { + } else if (_pointer > 0) { - sum = _data.front(); + sum = _data[0]; } @@ -59,6 +73,20 @@ class MedianFilter : public BaseFilter { } + void resize(unsigned char size) { + if (_size == size) return; + _size = size; + if (_data) delete _data; + _data = new double[_size+1]; + for (unsigned char i=0; i<=_size; i++) _data[i] = 0; + _pointer = 0; + } + + protected: + + unsigned char _pointer = 0; + double * _data = NULL; + }; #endif // SENSOR_SUPPORT diff --git a/code/espurna/filters/MovingAverageFilter.h b/code/espurna/filters/MovingAverageFilter.h index ce00dea7..beb08c55 100644 --- a/code/espurna/filters/MovingAverageFilter.h +++ b/code/espurna/filters/MovingAverageFilter.h @@ -15,49 +15,36 @@ class MovingAverageFilter : public BaseFilter { public: void add(double value) { - - // If we are at the end of the vector we add a new element - if (_pointer >= _data.size()) { - _sum = _sum + value; - _data.push_back(value); - - // Else we substract the old value at the current poisiton and overwrite it - } else { - _sum = _sum + value - _data[_pointer]; - _data[_pointer] = value; - } - - _pointer++; - + _sum = _sum + value - _data[_pointer]; + _data[_pointer] = value; + _pointer = (_pointer + 1) % _size; } - void reset() { - - // I assume series length to be the number of data points since last reset, - // so I zero-ed old data points from this point on - for (unsigned char i=_pointer; i<_data.size(); i++) { - _data[i] = 0; - } - - _pointer = 0; - + unsigned char count() { + return _pointer; } - double result() { - - // At this point we want to return the sum since last request - for (unsigned char i=_pointer; i<_data.size(); i++) { - _sum = _sum - _data[i]; - } + void reset() {} + double result() { return _sum; + } + void resize(unsigned char size) { + if (_size == size) return; + _size = size; + if (_data) delete _data; + _data = new double[_size]; + for (unsigned char i=0; i<_size; i++) _data[i] = 0; + _pointer = 0; + _sum = 0; } protected: unsigned char _pointer = 0; double _sum = 0; + double * _data = NULL; }; diff --git a/code/espurna/sensor.ino b/code/espurna/sensor.ino index c100825c..41423b35 100644 --- a/code/espurna/sensor.ino +++ b/code/espurna/sensor.ino @@ -439,6 +439,11 @@ void _sensorConfigure() { _sensor_temperature_units = getSetting("tmpUnits", SENSOR_TEMPERATURE_UNITS).toInt(); _sensor_temperature_correction = getSetting("tmpCorrection", SENSOR_TEMPERATURE_CORRECTION).toFloat(); + // Update filter sizes + for (unsigned char i=0; i<_magnitudes.size(); i++) { + _magnitudes[i].filter->resize(_sensor_report_every); + } + // Save settings delSetting("pwrExpectedP"); delSetting("pwrExpectedC"); @@ -477,6 +482,7 @@ void _magnitudesInit() { } else { new_magnitude.filter = new MedianFilter(); } + new_magnitude.filter->resize(_sensor_report_every); _magnitudes.push_back(new_magnitude); DEBUG_MSG_P(PSTR("[SENSOR] -> %s:%d\n"), _magnitudeTopic(type).c_str(), _counts[type]);