Contents
raw book

The average filter that is usually used for sensor initialisation, like setting zero of an electronic weighing scale, is basically a re-written average formula in recursive form. Starting with the intuitive average formula where the sum of the data points is divided by its count:

xk=x1+x2++xkk\overline{x}_k = \frac{x_1 + x_2 + \dots + x_k}{k}

Multiplying both sides by kk yields:

kxk=x1+x2++xkk \overline{x}_k = x_1 + x_2 + \dots + x_k

Dividing both sides by k1k-1 and split the last term yields:

kk1xk=x1+x2++xkk1=x1+x2++xk1k1+xkk1=xk1+xkk1\begin{array}{rl} \frac{k}{k-1}\overline{x}_k &= \frac{x_1 + x_2 + \dots + x_k}{k-1}\\ &= \frac{x_1+x_2+\dots+x_{k-1}}{k-1} + \frac{x_k}{k-1}\\ &= \overline{x}_{k-1} + \frac{x_k}{k-1} \end{array}

Dividing again both sides by kk1\frac{k}{k-1} results in the recursive formula for the average:

xk=k1kxk1+1kxk\overline{x}_k = \frac{k-1}{k}\overline{x}_{k-1} + \frac{1}{k}x_k

This form is similar to a low-pass filter with α:=k1k=11k\alpha:= \frac{k-1}{k} = 1 - \frac{1}{k} from which follows that 1k=1α\frac{1}{k} = 1 - \alpha and therefore

xk=αxk1+(1α)xk\overline{x}_k = \alpha\overline{x}_{k-1} + (1 - \alpha)x_k

Software implementation

let x = read_value() // initial value

for (let k = 1; ; k++) {
  let α = (k - 1) / k
  x = α * x + (1 - α) * read_value()

  write_value(x)
}

Plot

Measuring a 5V reading over the period of 60s with a STD of 3V can be smoothed out quite quickly with an average filter:

-10-6-226101418222630343842465054586266-10-6-226101418