diff --git a/libraries/Filter/AverageFilter.h b/libraries/Filter/AverageFilter.h new file mode 100644 index 0000000000..df9305a745 --- /dev/null +++ b/libraries/Filter/AverageFilter.h @@ -0,0 +1,82 @@ +// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- +// +// This is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the +// Free Software Foundation; either version 2.1 of the License, or (at +// your option) any later version. +// + +/// @file AverageFilter.h +/// @brief A class to provide the average of a number of samples +/// +/// DO NOT CREATE AND DESTROY INSTANCES OF THIS CLASS BECAUSE THE ALLOC/MALLOC WILL LEAD TO MEMORY FRAGMENTATION + +#ifndef AverageFilter_h +#define AverageFilter_h + +#include +#include + +// 1st parameter is the type of data being filtered. +// 2nd parameter is a larger data type used during summation to prevent overflows +template +class AverageFilter : public Filter +{ + public: + AverageFilter(uint8_t requested_size) : Filter(requested_size) {}; + + // apply - Add a new raw value to the filter, retrieve the filtered result + virtual T apply(T sample); + + // reset - clear the filter + virtual void reset(); + + private: + uint8_t _num_samples; +}; + +// Typedef for convenience (1st argument is the data size, 2nd argument is a datasize that's bigger to handle overflows) +typedef AverageFilter AverageFilterInt8; +typedef AverageFilter AverageFilterUInt8; +typedef AverageFilter AverageFilterInt16; +typedef AverageFilter AverageFilterUInt16; +typedef AverageFilter AverageFilterInt32; +typedef AverageFilter AverageFilterUInt32; + +// Public Methods ////////////////////////////////////////////////////////////// + +template +T AverageFilter::apply(T sample) +{ + U result = 0; + + // call parent's apply function to get the sample into the array + Filter::apply(sample); + + // increment the number of samples so far + _num_samples++; + if( _num_samples > Filter::filter_size || _num_samples == 0 ) + _num_samples = Filter::filter_size; + + // get sum of all values - there is a risk of overflow here that we ignore + for(int8_t i=0; i::filter_size; i++) + result += Filter::samples[i]; + + return (T)(result / _num_samples); +} + +// reset - clear all samples +template +void AverageFilter::reset() +{ + // call parent's apply function to get the sample into the array + Filter::reset(); + + // clear our variable + _num_samples = 0; +} + +#endif + + +