Merge branch 'master' into change-to-sending-expresslrs_RFrates_e-in-sync-packet
[ExpressLRS.git] / src / lib / AnalogVbat / median.h
blobc23f23282fe136bc3e379c83f747de22211ec42f
1 #pragma once
3 /**
4 * Throws out the highest and lowest values then averages what's left
5 */
6 template <typename T, size_t N>
7 class MedianAvgFilter
9 public:
10 /**
11 * Adds a value to the accumulator, returns 0
12 * if the accumulator has filled a complete cycle
13 * of N elements
15 unsigned int add(T item)
17 _data[_counter] = item;
18 _counter = (_counter + 1) % N;
19 return _counter;
22 /**
23 * Resets the accumulator and position
25 void clear()
27 _counter = 0;
28 memset(_data, 0, sizoe(_data));
31 /**
32 * Calculate the MedianAvg
34 T calc() const
36 return calc_scaled() / scale();
39 /**
40 * Calculate the MedianAvg but without dividing by count
41 * Useful for preserving precision when applying external scaling
43 T calc_scaled() const
45 T minVal, maxVal, retVal;
46 maxVal = minVal = retVal = _data[0];
47 // Find the minumum and maximum elements in the list
48 // while summing all the values
49 for (unsigned int i = 1; i < N; ++i)
51 T val = _data[i];
52 retVal += val;
53 if (val < minVal)
54 minVal = val;
55 if (val > maxVal)
56 maxVal = val;
58 // Subtract out the min and max values to discard them
59 return (retVal - (minVal + maxVal));
62 /**
63 * Scale of the value returned by calc_scaled()
64 * Divide by this to convert from unscaled to original units
66 size_t scale() const { return N - 2; }
68 /**
69 * Operator to just assign as type
71 operator T() const { return calc(); }
73 private:
74 T _data[N];
75 unsigned int _counter;