EnigmaIOT  0.9.8
Secure sensor and gateway platform based on ESP8266 and ESP32
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.