I have quite a few variables in my code that i need to average the value of(around 12), from various sensors.
So i made this simple moving average function which works, the problems began when i added new things to the code which required calling this function more times and now it has gotten quite slow, results need around 5 seconds to stabilize which is too much.
In it's arguments i add the variable to be averaged, the array to use and number of samples.
uint16_t calculateAverage(uint16_t variable,
uint16_t *valueArray,
uint16_t num_samples)
{
valueArray[index1] = variable; // Store the current sensor value in the array
index1++; // Increment the index
if (index1 >= num_samples)
{
index1 = 0; // Reset the index when it reaches the window size
}
uint64_t sum = 0; // Calculate the moving average for the current window
for (int i = 0; i < num_samples; i++)
{
sum += valueArray[i];
}
double movingAverage = static_cast<double>(sum) / num_samples;
return static_cast<uint16_t>(movingAverage);
}
So i want to improve this function and i discovered that i could speed up the code by using a circular buffer.
I made this function which works, but now i need to modify it so i can call it for averaging multiple different variables
without the results getting mixed up.
uint16_t circularAvg(uint16_t variable,
uint16_t *valueArray,
uint16_t num_samples)
{
static CircularBuffer<uint16_t, 128> buffer; // Create a circular buffer of size 'num_samples' to store the sensor values. The type int can be changed according to your requirement (uint16_t or any other).
if (buffer.isFull())
{
buffer.shift(); // If the array is full, remove the oldest element before adding a new one. This ensures that we are always considering 'num_samples' elements for calculating average.
}
else
{
++index1; // Increment index if buffer isnβt yet at its maximum size β so it wraps around to zero when full, just like your original code
}
buffer.push(variable); // Add the current sensor value into circular buffer using push() function instead of add(). This will automatically shift elements if necessary.
uint64_t sum = 0; // Calculate moving average for the current window by adding all elements in array and dividing it with number of samples β just like your original code but using CircularBuffer methods instead.
for (int i = 0; i < num_samples && num_samples != 0; ++i)
{ // Check if the window size is not zero to avoid division by zero error
sum += buffer[i]; // Add the 'ith' element in circular buffer to sum variable. This will be equal to current moving average if num_samples is 1, or a weighted average otherwise.
}
uint16_t movingAverage = (num_samples != 0) ? round(sum / num_samples) : 0; // Calculate the rounded-off value of moving average from sum and divide it by number of samples, but only if num_samples is not zero to avoid division by zero error
return movingAverage;
}
Probably if i would create separate instances of the CircularBuffer for each variable and then i would pass them as function arguments it could work?
Would really appreciate some help on how i could achieve this.
Using STM32 bluepill.