Calculates moving averages. Operates in the integer domain.
moving-average
@/moving-average
Calculates moving averages. Operates in the integer domain.
INnumber
Adds new data point to the moving average.
NUMnumber
Specifies the interval (number of data points) for the moving average.
RSTpulse
Restarts the moving average. Zeros the interval array and associated data.
OUTnumber
Returns the new moving average value.
To use the node in your project you should have the andrey-doc/moving-average library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.
C++ implementation
// Based on the Arduino Moving Average Library
// https://github.com/JChristensen/movingAvg
node {
// Internal state variables defined at this level persists across evaluations
int m_interval; // number of data points for the moving average
int m_nbrReadings; // number of readings
long m_sum; // sum of the m_readings array
int m_next; // index to the next reading
int *m_readings; // pointer to the dynamically allocated interval array
// initialize - allocate the interval array
void init()
{
m_readings = new int[m_interval];
}
// add a new reading and return the new moving average
int 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 = 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 getAvg()
{
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
}
// start the moving average over again
void reset()
{
m_nbrReadings = 0;
m_sum = 0;
m_next = 0;
}
void evaluate(Context ctx) {
if (isSettingUp()) {
// This run once
m_interval = getValue<input_NUM>(ctx);
init();
}
if (isInputDirty<input_RST>(ctx))
reset();
emitValue<output_OUT>(ctx, reading(getValue<input_IN>(ctx)));
}
}