Moving average#
This module implements a moving average filter which calculates the unweighted mean of the previous \(k\) data points (sampling window). The number of data points \(k\) is adjustable during run-time with a maximum filter length which is determined during initialization of the filter.
with the data points \(p\) and the number of entries in the ring buffer \(n\) [[1]].
To speed up the calculation and prevent looping through every member of the circular buffer a different approach is used.
Thus, for each function call the oldest value in the circular buffer (circularBuffer
array) will be deleted and the newest one will be added.
Setup#
Configuration#
-
typedef struct uz_movingAverageFilter_t uz_movingAverageFilter_t#
Object definition for uz_movingAverageFilter_t.
-
struct uz_movingAverageFilter_config#
Configuration struct for movingAverageFilter. Accessible by the user.
Public Members
-
uint32_t filterLength#
Length of the filter. Must be larger than 0 and smaller or equal to the length of the cirucularBuffer array
-
uint32_t filterLength#
-
uz_movingAverageFilter_t *uz_movingAverageFilter_init(struct uz_movingAverageFilter_config config, uz_array_float_t circularBuffer)#
Initialization of the moving Average Filter object.
- Parameters:
config – uz_movingAverageFilter_config configuration struct
circularBuffer – circularBuffer array. The length of the array will be the MAX_LENGTH of the filter
- Returns:
uz_movingAverageFilter_t* pointer to uz_movingAverageFilter_t instance
The circularBuffer
array has to be initialized by using the UltraZohm Array module.
The length of the array will automatically be the maximum possible length of the filter.
I.e. if the array has 50 entries, the filter length can’t be higher than 50, otherwise an assertion triggers.
However, it is possible for the filter length to be lower than the maximum length.
1#include "uz/uz_movingAverageFilter/uz_movingAverageFilter.h"
2int main(void) {
3 struct uz_movingAverageFilter_config config_SMA = {
4 .filterLength = 30U
5 };
6 float data [50] = {0};
7 uz_array_float_t circularBuffer = {
8 .length = UZ_ARRAY_SIZE(data),
9 .data = &data[0]
10 };
11}
Init function#
During the initialization the config struct as well as the circularBuffer
array have to be function arguments of the init function.
1int main(void) {
2 uz_movingAverageFilter_t* SMA_instance = uz_movingAverageFilter_init(config_SMA, circularBuffer);
3}
Warning
Each instance of the moving average filter requires it’s own circularBuffer
array!
Example of initialization for two independent moving average filters:
1#include "uz/uz_movingAverageFilter/uz_movingAverageFilter.h"
2int main(void) {
3 float data_1 [50] = {0};
4 uz_array_float_t circularBuffer_1 = {
5 .length = UZ_ARRAY_SIZE(data_1),
6 .data = &data_1[0]
7 };
8
9 float data_2 [20] = {0};
10 uz_array_float_t circularBuffer_2 = {
11 .length = UZ_ARRAY_SIZE(data_2),
12 .data = &data_2[0]
13 };
14
15 struct uz_movingAverageFilter_config config_SMA_1 = {
16 .filterLength = 30U
17 };
18
19 struct uz_movingAverageFilter_config config_SMA_2 = {
20 .filterLength = 20U
21 };
22
23 uz_movingAverageFilter_t* SMA_instance_1 = uz_movingAverageFilter_init(config_SMA_1, circularBuffer_1);
24 uz_movingAverageFilter_t* SMA_instance_2 = uz_movingAverageFilter_init(config_SMA_2, circularBuffer_2);
25}
Sample-functions#
Two versions are implemented:
- float uz_movingAverageFilter_sample(uz_movingAverageFilter_t *self, float sample)#
Calculates one sample of the moving average filter with fixed filter length.
- Parameters:
self – pointer to uz_movingAverageFilter_t instance
sample – sample input of the moving average filter
- Returns:
float output of the filter
- float uz_movingAverageFilter_sample_variable_length(uz_movingAverageFilter_t *self, float sample)#
Calculates one sample of the moving average filter. The filter length can be changed dynamically during runtime. It uses different approaches to calculate the result with the least amount of loop-iterations possible.
- Parameters:
self – pointer to uz_movingAverageFilter_t instance
sample – sample input of the moving average filter
- Returns:
float output of the filter
1int main(void) {
2 float sample = 23.4f;
3 float output_fixed_length = uz_movingAverageFilter_sample(SMA_instance, sample);
4 float output_variable_length = uz_movingAverageFilter_sample_variable_length(SMA_instance, sample);
5}
Set filter length#
-
void uz_movingAverageFilter_set_filterLength(uz_movingAverageFilter_t *self, uint32_t new_filterLength)#
Sets a new filter length.
- Parameters:
self – pointer to uz_movingAverageFilter_t instance
new_filterLength – new value for the filter length
Changes the filter length to the input value. Filter length has to be equal or lower to the MAX_LENGTH and larger than 0. Otherwise an assertion triggers.
1int main(void) {
2 uint32_t new_filter_length = 5U;
3 uz_movingAverageFilter_set_filterLength(SMA_instance, new_filter_length);
4}
Reset#
Resets the movingAverageFilter module. All elements of the circularBuffer will be reset to 0.0f.
1int main(void) {
2 uz_movingAverageFilter_reset(SMA_instance);
3}