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