Sensor Communication Library  0.4.0
Smoothed.h
1 /*
2  * Smoothed.h
3  * Store and calculate smoothed values from sensors.
4  * Created by Matt Fryer on 2017-11-17.
5  * Licensed under LGPL (free to modify and use as you wish)
6  */
7 
8 #pragma once
9 
10 #define SMOOTHED_AVERAGE 1
11 #define SMOOTHED_EXPONENTIAL 2
12 
13 using namespace std;
14 
15 // A class used to store and calculate the values to be smoothed.
16 template <typename T>
17 class Smoothed {
18  private:
19  byte smoothMode;
20  byte smoothReadingsFactor = 10; // The smoothing factor. In avergare mode, this is the number of readings to average.
21  byte smoothReadingsPosition = 0; // Current position in the array
22  byte smoothReadingsNum = 0; // Number of readings currently being averaged
23  T *smoothReading; // Array of readings
24  public:
25  Smoothed();
26  ~Smoothed(); // Destructor to clean up when class instance killed
27  bool begin (byte smoothMode, byte smoothFactor = 10);
28  bool add (T newReading);
29  T get ();
30  T getLast ();
31  bool clear ();
32 };
33 
34 // Constructor
35 template <typename T>
36 Smoothed<T>::Smoothed () { // Constructor
37 
38 }
39 
40 // Destructor
41 template <typename T>
42 Smoothed<T>::~Smoothed () { // Destructor
43  delete[] smoothReading;
44 }
45 
46 // Inintialise the array for storing sensor values
47 template <typename T>
48 bool Smoothed<T>::begin (byte mode, byte smoothFactor) {
49  smoothMode = mode;
50  smoothReadingsFactor = smoothFactor;
51 
52  switch (smoothMode) {
53  case SMOOTHED_AVERAGE : // SMOOTHED_AVERAGE
54 
55  smoothReading = new T[smoothReadingsFactor]; // Create the actual array of the required size
56 
57  // Initialise all the values in the array to zero
58  for (int thisReading = 0; thisReading < smoothReadingsNum; thisReading++) {
59  smoothReading[thisReading] = 0;
60  }
61 
62  return true;
63  break;
64 
65  case SMOOTHED_EXPONENTIAL : // SMOOTHED_EXPONENTIAL
66 
67  smoothReading = new T[2];
68  smoothReading[0] = 0;
69  smoothReading[1] = 0; // Second value in array used for storing last value added
70 
71  return true;
72  break;
73 
74  default :
75  return false;
76  break;
77  }
78 
79 }
80 
81 // Add a value to the array
82 template <typename T>
83 bool Smoothed<T>::add (T newReading) {
84  switch (smoothMode) {
85  case SMOOTHED_AVERAGE : // SMOOTHED_AVERAGE
86 
87  if(smoothReadingsNum < smoothReadingsFactor) { smoothReadingsNum++; } // Keep record of the number of readings being averaged. This will count up to the arrany saize then stay at that number
88 
89  smoothReading[smoothReadingsPosition] = newReading; // Add the new value
90 
91  if (smoothReadingsPosition == (smoothReadingsFactor - 1)) { // If at the end of the array
92  smoothReadingsPosition = 0; // Increment to the beginning of the array
93  } else {
94  smoothReadingsPosition++; // Increment to next array position position
95  }
96 
97  return true;
98  break;
99 
100  case SMOOTHED_EXPONENTIAL : // SMOOTHED_EXPONENTIAL
101 
102  if( smoothReadingsNum == 0 ) {
103  smoothReadingsNum++;
104  smoothReading[0] = newReading;
105  } else {
106  smoothReading[0] = (T)(((long double)smoothReadingsFactor/100) * newReading + (1 - ((long double)smoothReadingsFactor/100)) * smoothReading[0]);
107  }
108 
109  smoothReading[1] = newReading; // Update the last value added
110 
111  return true;
112  break;
113 
114  default :
115  return false;
116  break;
117  }
118 }
119 
120 // Get the smoothed result
121 template <typename T>
122 T Smoothed<T>::get () {
123  switch (smoothMode) {
124  case SMOOTHED_AVERAGE : { // SMOOTHED_AVERAGE
125  T runningTotal = 0;
126 
127  for (int x = 0; x < smoothReadingsNum; x++) {
128  runningTotal += smoothReading[x];
129  }
130 
131  return runningTotal / smoothReadingsNum;
132  }
133  break;
134 
135  case SMOOTHED_EXPONENTIAL : // SMOOTHED_EXPONENTIAL
136  return smoothReading[0];
137  break;
138 
139  default :
140  return false;
141  break;
142  }
143 }
144 
145 // Gets the last result stored
146 template <typename T>
148  switch (smoothMode) {
149  case SMOOTHED_AVERAGE : // SMOOTHED_AVERAGE
150  // Just return the last reading
151  if (smoothReadingsPosition == 0) {
152  return smoothReading[smoothReadingsFactor-1];
153  } else {
154  return smoothReading[smoothReadingsPosition-1];
155  }
156  break;
157 
158  case SMOOTHED_EXPONENTIAL : // SMOOTHED_EXPONENTIAL
159  return smoothReading[1];
160  break;
161 
162  default :
163  return false;
164  break;
165  }
166 }
167 
168 // Clears all stored values
169 template <typename T>
170 bool Smoothed<T>::clear () {
171  switch (smoothMode) {
172  case SMOOTHED_AVERAGE : // SMOOTHED_AVERAGE
173  // Reset the counters
174  smoothReadingsPosition = 0;
175  smoothReadingsNum = 0;
176 
177  // Set all the values in the array to zero. Not really needed
178  for (int thisReading = 0; thisReading < smoothReadingsNum; thisReading++) {
179  smoothReading[thisReading] = 0;
180  }
181  break;
182 
183  case SMOOTHED_EXPONENTIAL : // SMOOTHED_EXPONENTIAL
184  smoothReadingsNum = 0;
185  smoothReading[0] = 0;
186  smoothReading[1] = 0;
187  break;
188 
189  default :
190  return false;
191  break;
192  }
193 }