前回は同じ構成のIIRフィルタの計算をFloat型からDouble型にするだけで問題が消える件を勉強しました。今回はFloat型のままでOKという話。だったら最初から言ってよ、とは言わず、一歩一歩手習ひいたしとうございます。なぜOKになるのか、ブロックダイアグラムを見ればどこが違うかは分かりまする。でも何故?
※「手習ひデジタル信号処理」投稿順 Indexはこちら
※アイキャッチ画像のボード上に収まる「JRC」印のオペアンプは、来月合併で社名が変わる新日本無線のNJU3031Dであります。
さて、勝手に手習ひさせていただいております教科書は以下です。
三上直樹先生著、工学社『「Armマイコン」プログラムで学ぶデジタル信号処理』
プログラム・ソースの引用等いたしませんが、Arm社のMbed環境上で公開されています(要無料登録。)
継続(カスケード接続)IIRフィルタとな
今回、手習ひさせていただきますのは、カスケード接続されたIIRフィルタです。こんな感じ。
前回までの直接形と比べると、1個のデカい(次数の多い)フィルタから、小さいフィルタを複数接続するかたちに改めたと。これで、直接形の計算精度の問題が回避できるようになる、らしいです。やってみます。論より証拠、見る前に跳べ(違うか。)
例によってビルドの結果
係数ファイルについては、直接形とは構造が違うので、Cascade型用のものと入れ替えないとなりません。
main.cppについては、アップロードはさけ、直接形のものを「手で」書き換えながら、何処をどうしているのかシミジミと読ませていただきました。
小さな構造体1個で、さらっと美しく書かれておりますな。私のようなものが書くと、きっと力任せに書き散らしてこうは綺麗に収まりません。コードを読ませていただくだけで勉強になります。
実質変更はフィルタ部のみ。割り込みサービス・ルーチン内でフィルタを呼んでいるので、関数名の変更こそありますが、割り込みとメインはずっと同じで済んでいます。
実験結果
実験の段取りはこのところずっと同じです。入力に 365Hz、振幅1V、オフセット0Vの正弦波を入れ、フィルタがかかって出てくる出力を観察すると。フィルタそのものはローパスで、遮断周波数355Hzという設定なので、この周波数の入力があれば、出力の振幅が入力より小さくなり、また、フラフラせずに安定して出てくるというのが期待です。
まず時間波形はこんな感じ。黄色C1が入力、青色C2が出力です。
振幅半減、波形もブレてないようです。前々回の直接形のFloat計算では、出力波形がいかにも不安定な感じでのたくる動きを見せていたとは段違い。流石だなカスケード接続。
前々回のFloat型のバラツキの様子を観察したときにつかったPersistenceウインドウでも調べてみます。下は1000回以上のトレースを重ねています。バラツキが分からないです。ピタリ賞(古いな。)
さて続いて、お楽しみの振幅特性を測ってみます。10Hzから5kHz(サンプリング周波数10kHzのため)です。三上先生本が、横軸リニア設定なので、当方も対数でなくリニアです。Floatのくせに?通過域はほぼ平で、変なピークもなくスパッとな。