IoT機器でセンサを扱うときに、センサの値のノイズを除去する技術はとても重要です。
そんな時に役立つのがLPF(ローパスフィルタ)です。
UIFlow2でも、簡単にLPF(ローパスフィルタ)を実装することができます。
本記事では、UIFlow2でLPFを実装する方法について解説していきます。
LPF(ローパスフィルタ)のフロー概要
LPF(ローパスフィルタ)のテスト用フローの完成形を示します。

プログラムの流れは次の通り。
Setupブロック
- LPF(ローパスフィルタ)のイニシャライズ
Loopブロック
- フィルタに入力する値を生成します
ここでは、ボタンを押すと「1」、ボタンを離すと「0」とします。 - 100msecで繰り返します。
Timer Callbackブロック
- ローパスフィルタの演算を実行します
LPF(ローパスフィルタ)の実行結果

元の値に対して、LPF後の値はフィルタがかかって滑らかになっていることがわかります。
LPF(ローパスフィルタ)の計算式
デジタルローパスフィルタの計算式
LPF(ローパスフィルタ)は、入力信号から高周波成分(ノイズ)を除去し、滑らかな出力を得るための処理です。
一次デジタルローパスフィルタの基本式は以下の式を使います。
y = α ・x + ( 1 - α )・yprev
y : 出力値
x : 入力値
yprev : 前回の出力値
α : フィルタ係数 ( 0 < α < 1 )
αの求め方
サンプリング周期 T [s] と 時定数 Ti を使うと、αは次の式となります。
α = T / ( T + Ti )
T : サンプリング周期 [s]
Ti : 時定数 [s]
この式をUIFlowで実装することで、LPFを実現することが可能です。
LPF(ローパスフィルタ)の時定数とは?
LPF(ローパスフィルタ)の特性を決定づけるパラメータが時定数 Ti です。
時定数の役割
- 時定数が小さい:急激な変化に追従しやすく、反応が早いがノイズに弱い
- 時定数が大きい:滑らかになるが、変化に追従しにくい(応答が早い)
時定数は、入力がステップ状に変化したときに、出力が約63.2%に到達するまでの時間を表します。

この図はステップ入力に対する時定数 Ti [sec] の一次ローパスフィルタの出力応答を示す図です。
ステップ入力から、時間 Ti、Ti×2、Ti×3秒後の出力は、
- Ti × 1:63.2%
- Ti × 2:86.5%
- Ti × 3:95.0%
このように、時間が経つにつれて指数的に入力値に近づいていき、およそTi × 3秒後の時点で95%に達するのが特徴です。
サンプリング周期の目安
サンプリング周期はどうやって決めればいいのかな?
サンプリング周期は、早ければ早いほど正確に計算できますが、M5Stackの能力には限界があります。
目安として次の値を参考にしてください。
T sampling ≦ Ti / 5
つまり、時定数の時間の間に5回以上サンプリングすると実用的な結果が得られることが多いです。
例:時定数 Ti が 0.5秒の場合
T sampling ≦ 0.5 / 5 = 0.1秒
つまり、時定数 Ti が 0.5秒の場合、サンプリング周期は 100msec程度が望ましいです。
タイマーコールバック関数の使い方
先ほどの式で示したように、LPF(ローパスフィルタ)を実装するためには、計算を一定周期(サンプリング周期)で実行する必要があります。
一定周期で処理を実行するためには、タイマーコールバック関数という機能を使うと簡単です。
タイマーコールバック関数を使うと、設定した周期で関数内の処理を実行することが可能。
タイマーコールバック関数は、デフォルトではコマンドパネルに表示していない場合があります。
UIFlowのResourceパネルから、Hardware --> Timer を追加することで使えるようになります。

タイマーコールバック関数について、詳しく知りたい方は、こちらの記事もご参考に。
関連記事
UIFlow2|タイマーコールバック関数 一定周期で処理を実行する方法
LPF(ローパスフィルタ)のフロー詳細

LPF(ローパスフィルタ)の詳細について解説していきます。
Setupブロック
事例では、関数 InitLpfを実行します。
関数InitLpfの中では、ローパスフィルタのイニシャライズ処理を行います。
今回は、サンプリング周期100msec、時定数0.5秒のローパスフィルタを実装します。

LPF(ローパスフィルタ)の計算に使用する変数の初期値を設定します。
- 変数 T[sec]:サンプリング周期
- 変数 Ti[sec]:時定数
- 変数 alpha: T / ( T + Ti )
- 変数 value:LPFに入力する値
- 変数 lpf_value_prev:前回のLPF出力値

タイマーコールバック関数の初期設定の部分です。
timer0のインスタンスを生成して、100msecのサンプリング周期で繰り返し実行するように設定します。
Loopブロック

Loopブロックでは、
- ボタンを押している時は、1
- ボタンを離している時は、0
となるように値を設定します。
この処理を100msec周期で繰り返します。
タイマーコールバック関数

100msec周期で実行するコールバック関数の処理を記述します。
ローパスフィルタの式は、ブロックで表現するよりも、コードで表現した方が理解しやすいので、Python実行ブロックで数式を記述します。
y = α ・x + ( 1 - α )・yprev
次に、今回の計算結果を、変数 lpf_value_prevに保存します。
次のprintブロックは、計算結果確認のデバッグ用に追加しているだけですので、なくてもOKです。
実行結果

- 赤色:入力信号
- 青色:LPF出力信号
時定数0.5秒のLPFが動作していることが確認できます。
グラフ表示アプリ
上の図は、Visual Code Studioの拡張機能 TelePlot を使って表示しています。
シリアルに数値を出力しておくだけで、リアルタイムでグラフ表示できます。
とても便利なので一度試してみて下さい!