マイクロコントローラ上でアナログフィルタを実現する
はじめに
アナログフィルタは連続時間信号から特定の周波数範囲を取り除くのに使われる.フィルタの出力も連続時間信号である.
マイクロコントローラを使ってアナログフィルタを実現するためには,フィルタを離散化する必要がある.これはマイクロコントローラがデジタルデバイスであるからである.マイクロコントローラへのアナログ入力も離散化しなければならない.フィルタ出力はマイクロコントローラのPWM(Pulse Width Modulation)チャンネルまたは他の利用できる任意のバスに送ることができる.
このプロジェクトでは,バターワース(Butterworth)フィルタを離散化し,それをArduino Unoマイクロコントローラボードに配備する.マイクロコントローラはシリアルバスでデータを送受信するように設定する.デバイスのフレームワークを使ってノイズを含んだ信号を送り,フィルタされた信号を受け取る.
フィルタの離散化と配備
遮断周波数が2 Hzの三次のバターフワースフィルタ.
tfmc = ButterworthFilterModel[{3, 2}]モデルを0.4秒のサンプリング周期で離散化する.
τ = 0.4;
tfmd = ToDiscreteTimeModel[tfmc, τ]//Chopパッケージをロードする.
Needs["MicrocontrollerKit`"]モデルを埋込,シリアル接続を使ってデータを送受信するように設定する.
ℳ = MicrocontrollerEmbedCode[tfmd, <|"Target" -> "ArduinoUno", "Inputs" -> "Serial", "Outputs" -> "Serial"|>, "/dev/cu.usbmodem14101"]データの送受信
デバイスへのシリアル接続を開く.
dv = DeviceOpen["Serial", "/dev/tty.usbmodem14101"]入力信号を指定し,開始時間とフィルタされた信号のリストを初期化する.
u = With[{ω = 0.5}, Sin[ω t] - (1/4)Sin[10 ω t] + (1/8)Sin[5 ω t]];
𝓉 = 0;
Subscript[y, rt] = {};データの送受信タスクを設定する.
task = SessionSubmit@ScheduledTask[
If[DeviceExecute[dv, "SerialReadyQ"],
AppendTo[Subscript[y, rt], {𝓉, DeviceReadBuffer[dv, "ReadTerminator" -> ℳ["Serial"]["EndByte"]]}];DeviceExecute[dv, "ReadFlush"];
𝓉 += τ;
DeviceWrite[dv, ℳ["Serial"]["StartByte"]];
DeviceWrite[dv, ToString[u /. t -> 𝓉]];
DeviceWrite[dv, ℳ["Serial"]["EndByte"]];
],
τ];フィルタされた信号をプロットする.
Dynamic[Short[res = Quiet@Check[MapAt[ToExpression[FromCharacterCode[Rest[#]]]&, Subscript[y, rt], {All, 2}], {}]], SaveDefinitions -> True]Dynamic[ListLinePlot[res], SaveDefinitions -> True]しばらくしたら,タスクを削除し,デバイスを閉じる.
TaskRemove[task];
DeviceClose[dv];信号の比較
入力信号と,フィルタされた実時間信号を比較する.
ListLinePlot[{Table[{t, u}, {t, 0, Subscript[y, rt][[-1, 1]], τ}], res}, PlotLegends -> {"Input", "Real-time"}]フィルタ応答のシミュレーションを行う.
Subscript[y, sim] = OutputResponse[tfmc, u, {t, 0, Subscript[y, rt][[-1, 1]]}];フィルタされた信号と比較する.
ListLinePlot[{Table[{t, Subscript[y, sim]}, {t, 0, Subscript[y, rt][[-1, 1]], τ}], res}, PlotLegends -> {"Simulated", "Real-time"}]離散化されたフィルタの性能がシミュレーションされたフィルタと同等であるために,サンプリング周期が十分であったことがわかる.
発展
- サンプリング区間を増減するとどうなるだろうか.
- 他のマイクロコントローラでこれを再現するのは簡単だろうか.
- 入力信号がアナログであったり,I2Cバスから入ってきたりするとどうなるだろうか.
- 出力信号を送信するのに,他にどのような方法があるだろうか.