マイコンでアナログデジタル変換(ADC)を行うとき、ローパスフィルタを入れたち時がある。でも部品が増えるの微妙ってときもある。
また、デジタルフィルタだと、特定の区間だけサンプリングしてフィルタするなどが容易である。
nをフィルタに使う整数、xを入力データとして、x1, x2, x3・・・・とあるものとします。y1=x1として、あとは上記の式に従って計算するとi番目の出力データyiが計算できます。
なお、整数演算する場合などは丸め誤差に注意が必要です。浮動小数点を問題なく扱えるマイコンなら、この限りではありません。
実際にこのフィルタを使った事例について。
関数は初期値30、途中から80になるというステップ関数に、±5の範囲でノイズを与えています(ただしエクセルのrand()関数なので分布が正規分布ではありません)。
関数だと、y=30+50*stepFunction(x) + (rand()-0.5)*10 といった感じ。
n=1は要するにフィルタなしです。上記の式にn=1を入れるとyi=xiとなります。
n=2~n=64まで比較するとアナログフィルタのように、応答が遅れ、終端部が平滑になることがわかります。
最後の100個分のデータを見ると次のよう担っています。
100データの標準偏差をとってみるとわかりますがnが大きいほどばらつきが少なくなります。
8bitマイコンではADCは10bitか8bitくらいなので、16bit変数を用意しておき、
z[i] = (n -1)y[i-1] + x[i] = ny[i-1] - y[i-1] + x[i] = z[i-1] - y[i-1] + z[i]
y[i] = z[i]/n
と、中間にz[i]というn倍大きな値の変数を入れておくと演算の負荷が多少すくなるなる(浮動小数点演算よりは計算がかんたん)。
たとえば2, 4, 8, 16, 32など2^nのサンプリングの場合はビットシフトで掛け算が済むので、すこし早く処理ができます。