EnigmaIOT  0.9.8
Secure sensor and gateway platform based on ESP8266 and ESP32
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Filter.cpp
Go to the documentation of this file.
1 
9 #include "Filter.h"
10 #include "EnigmaIOTdebug.h"
11 
12 float FilterClass::addValue (float value) {
13  switch (_filterType) {
14  case AVERAGE_FILTER:
15  return aveFilter (value);
16  break;
17  case MEDIAN_FILTER:
18  return medianFilter (value);
19  break;
20  default:
21  return value;
22  }
23 }
24 
25 float FilterClass::addWeigth (float coeff) {
26  float sumWeight = 0;
27 
28  for (int i = _order - 1; i > 0; i--) {
29  _weightValues[i] = _weightValues[i - 1];
30  }
31  _weightValues[0] = coeff;
32 
33  for (int i = 0; i < _order; i++) {
34  sumWeight += _weightValues[i];
35  }
36 
37  //DEBUG_VERBOSE ("SumWeight: %f", sumWeight);
38 
39  return sumWeight;
40 }
41 
42 
43 float FilterClass::aveFilter (float value) {
44  float sumValue = 0;
45  float sumWeight = 0;
46  float procValue;
47  int left, right;
48 
49  for (int i = 0; i < _order - 1; i++) {
50  _rawValues[i] = _rawValues[i + 1];
51  }
52  _rawValues[_order - 1] = value;
53 
54  DEBUG_VERBOSE ("Value: %f\n", value);
55 
56  DEBUG_VERBOSE ("Raw values:");
57  for (int i = 0; i < _order; i++) {
58  DEBUG_VERBOSE (" %f", _rawValues[i]);
59  }
60 
61  DEBUG_VERBOSE ("Coeffs:");
62  for (int i = 0; i < _order; i++) {
63  DEBUG_VERBOSE (" %f", _weightValues[i]);
64  }
65 
66  if (_index < _order) {
67  _index++;
68  left = _order - _index;
69  right = _order - 1;
70  } else {
71  left = 0;
72  right = _order - 1;
73  }
74  DEBUG_VERBOSE ("Index: %d , left: %d , right: %d\n", _index, left, right);
75 
76  for (int i = left; i <= right; i++) {
77  sumValue += _rawValues[i] * _weightValues[i];
78  sumWeight += _weightValues[i];
79  //DBG_OUTPUT_PORT.printf("Raw value %d: %f\n", (i + 1), _rawValues[_order - (i+1)]);
80  }
81  DEBUG_VERBOSE ("Sum: %f", sumValue);
82  DEBUG_VERBOSE (" SumWeight: %f\n", sumWeight);
83 
84  procValue = sumValue / sumWeight;
85 
86  DEBUG_VERBOSE ("Average: %f\n", procValue);
87 
88  return procValue;
89 }
90 
91 int FilterClass::divide (float* array, int start, int end) {
92  int left;
93  int right;
94  float pivot;
95  float temp;
96 
97  pivot = array[start];
98  left = start;
99  right = end;
100 
101  // While indexes do not cross
102  while (left < right) {
103  while (array[right] > pivot) {
104  right--;
105  }
106 
107  while ((left < right) && (array[left] <= pivot)) {
108  left++;
109  }
110 
111  // If indexes have not crossed yet we continue doing exchanges
112  if (left < right) {
113  temp = array[left];
114  array[left] = array[right];
115  array[right] = temp;
116  }
117  }
118 
119  // Indexes have crossed. We put the pivot on place
120  temp = array[right];
121  array[right] = array[start];
122  array[start] = temp;
123 
124  // NEw pivot position
125  return right;
126 }
127 
129  for (int i = 0; i < _order; i++) {
130  _rawValues[i] = 0;
131  _orderedValues[i] = 0;
132  //_weightValues[i] = 1;
133  }
134  _index = 0;
135 }
136 
138  free (_rawValues);
139  free (_orderedValues);
140  free (_weightValues);
141 }
142 
143 void FilterClass::quicksort (float* array, int start, int end) {
144  float pivot;
145 
146  if (start < end) {
147  pivot = divide (array, start, end);
148 
149  // Ordeno la lista de los menores
150  quicksort (array, start, pivot - 1);
151 
152  // Ordeno la lista de los mayores
153  quicksort (array, pivot + 1, end);
154  }
155 }
156 
157 float FilterClass::medianFilter (float value) {
158  float procValue;
159  int medianIdx;
160  int left, right, tempidx;
161  bool even;
162 
163  if (_index < _order) {
164  _index++;
165  left = _order - _index;
166  right = _order - 1;
167  even = ((right - left) % 2) == 1;
168  DEBUG_VERBOSE ("%d: ", (right - left) % 2);
169  if (even) {
170  tempidx = (right - left - 1) / 2;
171  DEBUG_VERBOSE ("even\n");
172  } else {
173  tempidx = (right - left) / 2;
174  DEBUG_VERBOSE ("odd\n");
175  }
176  medianIdx = right - _index + 1 + tempidx;
177  } else {
178  left = 0;
179  right = _order - 1;
180  even = (_order % 2) == 0;
181  if (even)
182  tempidx = (right - 1) / 2;
183  else
184  tempidx = right / 2;
185  medianIdx = right - _index + 1 + tempidx;
186  }
187  DEBUG_VERBOSE ("Index: %d , left: %d , right: %d , even: %s , tempidx: %d , medianidx: %d\n", _index, left, right, (even ? "even" : "odd"), tempidx, medianIdx);
188 
189  // Shift raw values
190  for (int i = 0; i < _order - 1; i++) {
191  _rawValues[i] = _rawValues[i + 1];
192  }
193  // Add new raw value
194  _rawValues[_order - 1] = value;
195 
196  DEBUG_VERBOSE ("Raw values:");
197  for (int i = 0; i < _order; i++) {
198  DEBUG_VERBOSE (" %f", _rawValues[i]);
199  }
200 
201  // copy to array before ordering
202  for (int i = 0; i < _order; i++) {
203  _orderedValues[i] = _rawValues[i];
204  }
205 
206  // order values
207  quicksort (_orderedValues, left, right);
208 
209  DEBUG_VERBOSE ("Ordered values:");
210  for (int i = 0; i < _order; i++) {
211  DEBUG_VERBOSE (" %f", _orderedValues[i]);
212  }
213 
214  // select median value
215  if (!even) {
216  procValue = _orderedValues[medianIdx];
217  } else { // there is no center value
218  procValue = (_orderedValues[medianIdx] + _orderedValues[medianIdx + 1]) / 2.0F;
219  }
220 
221  DEBUG_VERBOSE ("Median: %f\n", procValue);
222  return procValue; // return mid value
223 }
224 
225 FilterClass::FilterClass (FilterType_t type, uint8_t order) {
226  _filterType = type;
227 
228  if (order < MAX_ORDER)
229  if (order > 1)
230  _order = order;
231  else
232  _order = MIN_ORDER;
233  else
234  _order = MAX_ORDER;
235 
236  _rawValues = (float*)malloc (_order * sizeof (float));
237  for (int i = 0; i < _order; i++) {
238  _rawValues[i] = 0;
239  }
240 
241  _orderedValues = (float*)malloc (_order * sizeof (float));
242  for (int i = 0; i < _order; i++) {
243  _orderedValues[i] = 0;
244  }
245 
246  _weightValues = (float*)malloc (_order * sizeof (float));
247  for (int i = 0; i < _order; i++) {
248  _weightValues[i] = 1;
249  }
250 
251 }
252 
FilterClass::medianFilter
float medianFilter(float value)
Median filter calculation of next value.
Definition: Filter.cpp:157
FilterClass::_order
uint8_t _order
Filter order. Numbre of samples to store for calculations.
Definition: Filter.h:32
MEDIAN_FILTER
@ MEDIAN_FILTER
Definition: Filter.h:25
FilterClass::addValue
float addValue(float value)
Pushes a new value for calculation. Until the buffer is filled up to filter order,...
Definition: Filter.cpp:12
FilterClass::~FilterClass
~FilterClass()
Frees up dynamic memory.
Definition: Filter.cpp:137
FilterClass::FilterClass
FilterClass(FilterType_t type, uint8_t order)
Creates a new filter class.
Definition: Filter.cpp:225
FilterType_t
FilterType_t
Type of filter.
Definition: Filter.h:24
FilterClass::addWeigth
float addWeigth(float coeff)
Adds a new weighting value. It is pushed on the array so latest value will be used for older data.
Definition: Filter.cpp:25
FilterClass::aveFilter
float aveFilter(float value)
Average filter calculation of next value.
Definition: Filter.cpp:43
FilterClass::clear
void clear()
Resets state of the filter to an initial value.
Definition: Filter.cpp:128
MAX_ORDER
#define MAX_ORDER
Definition: Filter.h:18
MIN_ORDER
#define MIN_ORDER
Definition: Filter.h:19
FilterClass::quicksort
void quicksort(float *array, int start, int end)
Sorting function that uses QuickSort algorythm.
Definition: Filter.cpp:143
FilterClass::_orderedValues
float * _orderedValues
Values ordered for median calculation.
Definition: Filter.h:34
FilterClass::divide
int divide(float *array, int start, int end)
Divide function to be used on Quick Sort.
Definition: Filter.cpp:91
EnigmaIOTdebug.h
Auxiliary functions for debugging over Serial.
FilterClass::_index
uint _index
Used to point latest entered value while number of values less than order.
Definition: Filter.h:36
FilterClass::_weightValues
float * _weightValues
Weight values for average calculation. By default all them have value of 1 for arithmetic average.
Definition: Filter.h:35
FilterClass::_filterType
FilterType_t _filterType
Filter type from FilterType_t.
Definition: Filter.h:31
AVERAGE_FILTER
@ AVERAGE_FILTER
Definition: Filter.h:26
FilterClass::_rawValues
float * _rawValues
Raw values store.
Definition: Filter.h:33
Filter.h
Filter to process message rate or other values.