--- author: email: mail@petermolnar.net image: https://petermolnar.net/favicon.jpg name: Peter Molnar url: https://petermolnar.net copies: - http://web.archive.org/web/20111116141901/http://petermolnar.eu:80/sysadmin-blog/weighted-average-calculator-code-in-c/ lang: en published: '2011-08-23T10:11:04+00:00' summary: A short code to achieve a very fast weighted filter calculator with integers, using few resources. tags: - programming title: weighted average calculator code in C --- This filter was needed for a task that is polled at every 5. millisecond during the runtime. tUI8, -16, -32 are integer types of 8, 16 and 32 bits. ``` {.c} /* this is for a task that runs at a 5 ms frequency */ tUI8 weighted_filter(int new_sample) { #define FILTER_CONST_WEIGHT 128U /* total weights */ #define FILTER_CONST_WEIGHT_SAMPLE 3U /* weight of new sample */ #define FILTER_CONST_SHIFT 8U /* shift by */ #define FILTER_CONST_SHIFT_VAL 256U /* shift value */ #define FILTER_CONST_WEIGHT_SHIFT 7U /* shift value of weight */ static tUI32 sample_weighted = 0U; /* store previous weighted */ static tBOOL sample_first_run = 1; /* first run flag */ tUI8 sample_output = 0; /* return value */ tUI32 sample_tmp = 0U; /* temporary value, needed for calculation */ /* if first run, set initial values to immediately reach input * method would be too slow without this */ if (sample_first_run == 1) { sample_first_run = 0; /* no more first runs */ sample_output = new_sample; /* return the input value */ sample_weighted = (tUI32)(new_sample ) << FILTER_CONST_SHIFT; /* weighted initial value with offset */ } else { sample_tmp = new_sample; /* add offset temperature to be in unsigned range */ sample_tmp = sample_tmp >> FILTER_CONST_WEIGHT_SHIFT; /* divide by total weights */ sample_tmp = (sample_weighted + (FILTER_CONST_SHIFT_VAL>>1) -1 ) >> FILTER_CONST_SHIFT; /* round and divide by shift | need to be kept in one row! */ sample_output = (tUI8)sample_tmp; /* output value */ } return (sample_output); } ```