mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2026-08-18 18:32:30 +02:00
Convert class <movingAvg> to accept flexible data types
This commit is contained in:
@@ -66,8 +66,8 @@ void sensorTask(void *param){
|
|||||||
const int avgsize = 300;
|
const int avgsize = 300;
|
||||||
constexpr int arrayBatV{avgsize};
|
constexpr int arrayBatV{avgsize};
|
||||||
constexpr int arrayBatC{avgsize};
|
constexpr int arrayBatC{avgsize};
|
||||||
movingAvg batV(arrayBatV);
|
movingAvg<int> batV(arrayBatV);
|
||||||
movingAvg batC(arrayBatC);
|
movingAvg<int> batC(arrayBatC);
|
||||||
batV.begin();
|
batV.begin();
|
||||||
batC.begin();
|
batC.begin();
|
||||||
|
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
// Arduino Moving Average Library
|
|
||||||
// https://github.com/JChristensen/movingAvg
|
|
||||||
// Copyright (C) 2018 by Jack Christensen and licensed under
|
|
||||||
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
|
|
||||||
|
|
||||||
#include <movingAvg.h>
|
|
||||||
|
|
||||||
// initialize - allocate the interval array
|
|
||||||
void movingAvg::begin()
|
|
||||||
{
|
|
||||||
m_readings = new int[m_interval];
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a new reading and return the new moving average
|
|
||||||
int movingAvg::reading(int newReading)
|
|
||||||
{
|
|
||||||
// add each new data point to the sum until the m_readings array is filled
|
|
||||||
if (m_nbrReadings < m_interval) {
|
|
||||||
++m_nbrReadings;
|
|
||||||
m_sum += newReading;
|
|
||||||
}
|
|
||||||
// once the array is filled, subtract the oldest data point and add the new one
|
|
||||||
else {
|
|
||||||
m_sum = m_sum - m_readings[m_next] + newReading;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_readings[m_next] = newReading;
|
|
||||||
if (++m_next >= m_interval) m_next = 0;
|
|
||||||
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
|
|
||||||
}
|
|
||||||
|
|
||||||
// just return the current moving average
|
|
||||||
int movingAvg::getAvg()
|
|
||||||
{
|
|
||||||
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the average for a subset of the data, the most recent nPoints readings.
|
|
||||||
// for invalid values of nPoints, return zero.
|
|
||||||
int movingAvg::getAvg(int nPoints)
|
|
||||||
{
|
|
||||||
if (nPoints < 1 || nPoints > m_interval || nPoints > m_nbrReadings) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
long sum{0};
|
|
||||||
int i = m_next;
|
|
||||||
for (int n=0; n<nPoints; ++n) {
|
|
||||||
if (i == 0) {
|
|
||||||
i = m_interval - 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
sum += m_readings[i];
|
|
||||||
}
|
|
||||||
return (sum + nPoints / 2) / nPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// start the moving average over again
|
|
||||||
void movingAvg::reset()
|
|
||||||
{
|
|
||||||
m_nbrReadings = 0;
|
|
||||||
m_sum = 0;
|
|
||||||
m_next = 0;
|
|
||||||
}
|
|
||||||
@@ -3,27 +3,37 @@
|
|||||||
// Copyright (C) 2018 by Jack Christensen and licensed under
|
// Copyright (C) 2018 by Jack Christensen and licensed under
|
||||||
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
|
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
|
||||||
|
|
||||||
|
// Extended to template class for handling of multiple data types
|
||||||
|
|
||||||
#ifndef MOVINGAVG_H_INCLUDED
|
#ifndef MOVINGAVG_H_INCLUDED
|
||||||
#define MOVINGAVG_H_INCLUDED
|
#define MOVINGAVG_H_INCLUDED
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
class movingAvg
|
class movingAvg
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
movingAvg(int interval)
|
movingAvg(int interval)
|
||||||
: m_interval{interval}, m_nbrReadings{0}, m_sum{0}, m_next{0} {}
|
: m_interval{interval}, m_nbrReadings{0}, m_sum{0}, m_next{0}, m_readings{nullptr} {}
|
||||||
|
~movingAvg() { delete[] m_readings; }
|
||||||
void begin();
|
void begin();
|
||||||
int reading(int newReading);
|
T reading(T newReading);
|
||||||
int getAvg();
|
T getAvg();
|
||||||
int getAvg(int nPoints);
|
T getAvg(int nPoints);
|
||||||
int getCount() { return m_nbrReadings; }
|
int getCount() { return m_nbrReadings; }
|
||||||
void reset();
|
void reset();
|
||||||
int* getReadings() {return m_readings;}
|
T* getReadings() { return m_readings; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_interval; // number of data points for the moving average
|
int m_interval; // number of data points for the moving average
|
||||||
int m_nbrReadings; // number of readings
|
int m_nbrReadings; // number of readings
|
||||||
long m_sum; // sum of the m_readings array
|
// Sum type adapts to T: long for integers, T for floating point
|
||||||
|
using SumType = typename std::conditional<std::is_floating_point<T>::value, T, long>::type;
|
||||||
|
SumType m_sum;
|
||||||
int m_next; // index to the next reading
|
int m_next; // index to the next reading
|
||||||
int* m_readings; // pointer to the dynamically allocated interval array
|
T* m_readings; // pointer to the dynamically allocated interval array
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Include the implementation to satisfy template instantiation requirements
|
||||||
|
#include "movingAvg.tpp"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
// Arduino Moving Average Library
|
||||||
|
// https://github.com/JChristensen/movingAvg
|
||||||
|
// Copyright (C) 2018 by Jack Christensen and licensed under
|
||||||
|
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
|
||||||
|
|
||||||
|
// Extended to template class for handling of multiple data types
|
||||||
|
|
||||||
|
//template <typename T>
|
||||||
|
//movingAvg<T>::movingAvg(int interval)
|
||||||
|
// : m_interval{interval}, m_nbrReadings{0}, m_sum{0}, m_next{0}, m_readings{nullptr}
|
||||||
|
//{}
|
||||||
|
|
||||||
|
// initialize - allocate the interval array
|
||||||
|
template <typename T>
|
||||||
|
void movingAvg<T>::begin()
|
||||||
|
{
|
||||||
|
m_readings = new T[m_interval];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add a new reading and return the new moving average
|
||||||
|
template <typename T>
|
||||||
|
T movingAvg<T>::reading(T newReading)
|
||||||
|
{
|
||||||
|
// add each new data point to the sum until the m_readings array is filled
|
||||||
|
if (m_nbrReadings < m_interval) {
|
||||||
|
++m_nbrReadings;
|
||||||
|
m_sum += newReading;
|
||||||
|
}
|
||||||
|
// once the array is filled, subtract the oldest data point and add the new one
|
||||||
|
else {
|
||||||
|
m_sum = m_sum - m_readings[m_next] + newReading;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_readings[m_next] = newReading;
|
||||||
|
if (++m_next >= m_interval) m_next = 0;
|
||||||
|
return getAvg();
|
||||||
|
}
|
||||||
|
|
||||||
|
// just return the current moving average
|
||||||
|
template <typename T>
|
||||||
|
T movingAvg<T>::getAvg()
|
||||||
|
{
|
||||||
|
if (m_nbrReadings == 0) return 0;
|
||||||
|
|
||||||
|
// Apply rounding for integers only
|
||||||
|
if (std::is_floating_point<T>::value) {
|
||||||
|
return m_sum / m_nbrReadings;
|
||||||
|
} else {
|
||||||
|
return (m_sum + (SumType)m_nbrReadings / 2) / m_nbrReadings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the average for a subset of the data, the most recent nPoints readings.
|
||||||
|
// for invalid values of nPoints, return zero.
|
||||||
|
template <typename T>
|
||||||
|
T movingAvg<T>::getAvg(int nPoints)
|
||||||
|
{
|
||||||
|
if (nPoints < 1 || nPoints > m_interval || nPoints > m_nbrReadings) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SumType sum{0};
|
||||||
|
int i = m_next;
|
||||||
|
for (int n=0; n<nPoints; ++n) {
|
||||||
|
if (i == 0) {
|
||||||
|
i = m_interval - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
sum += m_readings[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::is_floating_point<T>::value) {
|
||||||
|
return sum / nPoints;
|
||||||
|
} else {
|
||||||
|
return (sum + (SumType)nPoints / 2) / nPoints; //
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the moving average over again
|
||||||
|
template <typename T>
|
||||||
|
void movingAvg<T>::reset()
|
||||||
|
{
|
||||||
|
m_nbrReadings = 0;
|
||||||
|
m_sum = 0;
|
||||||
|
m_next = 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user