「てつ缶」の応用編です。
FFT で V/F 変換器の出力周波数を計測する、その応用のシミュレーションを始めました。
DFT 周波数スペクトラムの広がり
サンプリング周波数を fs、DFT サンプル数を N とします。
入力周波数が 0 〜 (k/N) * fs であって k が整数のとき、DFT 結果はとても正確に見えます。 (0 ≦ k ≦ N/2)
しかし k が整数でないとき、周波数スペクトラムが広がって見えます。
この広がりの形は、k が整数の最寄の周波数との差の 2 乗に反比例します。
これを bin splatter と呼ぶことがあります。
ここでは、上記のようなスペクトラムの広がりを前提として、V/F 変換器出力周波数を計測する方法を考えます。
普通の V/F 変換器の出力は準方形波です。 正弦波に近似させるような波形整形は必要だろうか? 基本周波数の
125.6789 倍の cos() 波 (半端な周波数) をノイズで PM 変調 (*2) し、これを実数の符号を調べる関数 sgn()
で方形波化したデータを FFT してみました。
ノイズの最大振幅は ±0.393 (約 ±π/ 8) ラジアンです。
(*2) PM 変調とは位相変調のことです。 FM 変調の変調波を微分したもので FM 変調すると、PM
変調したのと同等になります。
グラフの横軸は周波数で、直線目盛りです。 1024 点 FFT を行いましたので、横軸の最大は基準周波数の 511 倍です。 縦軸は相対振幅で、これも直線目盛りです。 薄く見えているのは元の時間領域波形で、縦軸中央が 0 です。
sgn(cos(125.x)) PM ノイズなし
右半分に大きく見えているのは、方形波の第 3 次高調波とかです。
sgn(cos(125.x)) PM ノイズなし、ハニング窓
sgn(cos(125.x)) PM ノイズあり、ハニング窓
これを見ると、窓関数は不要かもしれません。 周波数分析能力が最大なのは矩形窓であるとか、どこかで読んだ気がします。
さらに、正弦波近似などの波形整形処理は不要だろうと思いました。
スペクトラムの広がりを計算して、入力電圧換算の分解能を高められるか?
中心の前後、どの程度の範囲を見るか、というのは大きな問題です。 まずは前後それぞれ 4 点、中心を含めて 9 点のデータを補間に使いました。
4096 点 FFT を行いました。 入力は方形波で、基準周波数の 125±0.5、250±0.5、500±0.5、1000±0.5、2000±0.5 倍 (0.1 倍きざみ) の 5 種類を試しました。
もう一工夫すれば、10 進一桁くらいは分解能を高められそうです。(水増しと言うべきか?)
ピーク振幅 ±π/8 程度の位相ノイズを加えてみましたが、この程度では全く問題ありません。
少し欲張って、分解能を 100 倍にする補間を試してみました。
さすがに 100 倍はちょっと無理ですが、基準周波数の 0.01 倍の桁が 1 ないし 2 だけ違う程度におさまりました。 位相ノイズは加えていません。 中心の前後、合計 7 点のエネルギーを調べて補間しています。
ピーク振幅 ±π/8 程度の位相ノイズを加えると、基準周波数の 0.01 倍の桁が、せいぜい 5 程度異なるのが大部分で、まれに 0.15 程度の突発的ノイズになるようです。
実際に V/F 変換器の信号を受けた場合、アナログ入力電圧 0.0V 時の出力周波数を
10kHz 近辺とすれば、復調部分 (FFT + 補間処理) でおよそ 1 / (1000 * 50) の周波数分解能が得られます。
パーセントで表せば、0.002% です。
この分解能は V/F 変換器の直線性やドリフトが問題になるレベルです。
FFT のデータ点数を増やせば、周波数分解能はそれに比例して向上します。
但し入力計測時間は増大し、出力データレートは低く(小さく)なります。
「ぶりき缶」の調査もふまえて、入力の前処理が必要かどうか調べます。
前項で行った補間法が、高調波成分が減衰して崩れてしまった波形についても通用するか確認します。 まず上限に近い周波数ということで、1857.50 〜 1858.50 / 4096 を 0.01 ステップで調べました (44.1k sps として実周波数 20kHz 前後)。 8 倍オーバーサンプリングの方形波データを作成し、これを IIR のデジタルローパスフィルターで処理の後、8 つごとに取り出したデータを FFT + 補間処理し、入力周波数を求めます。
こんな波形です (左側が FFT 入力波形です)
結果は上々で、理想的な方形波と同じ方法で補間できることがわかりました。
グランド絶縁分離用のトランスによって、低い周波数成分の減少が起こります。 これについては、現在のところ全く心配していません。 仮に問題が出たとしても、対処は容易だと思います。
PC オーディオ入力と出力データレート
無理なく PC オーディオ入力を行って V/F 変換器の出力周波数を測定するにあたって、Win32
の低レベルウェーブフォームオーディオ入力 API を使いました。
(waveInOpen, waveInPrepareHeader, waveInAddBuffer, waveInStart など)
出力データレートを確定させるため、複数のバッファーを使って WHDR の BufferLength
をサンプリングレートに応じた適当な値に選びます (単位は byte)。
16 ビット 44.1ksps PCM と指定した場合、BufferLength を 44100 * 2 にすれば一秒に一回、4410 * 2
なら一秒に 10 回の割合で MM_WIM_DATA メッセージが送られて来るので、これを順次処理します。
出力データレートの正確さは PC オーディオのサンプリング周波数精度によって決まります。
ソースプログラム (1) 環境は Cygwin です。
ソースプログラム (2)
一秒間に 10 回の FFT と描画処理が可能かどうか不安だったのですが、CPU 性能さえあれば問題なさそうです。 もし無理であれば、まず表示負荷を軽くし、それでも無理ならデータ出力レートを小さくします。 (当方は Mobile Celeron 1.6GHz で、同時に "発振器" プログラムも動かしていました。)
周波数 11.025kHz (44.1kHz の 1/4) の方形波を "発振器" プログラムで発生させ、その漏洩成分を入力に見立てました。 したがって、かなりノイズの多い波形です。 画面表示はちょっと贅沢すぎますが、既存のものの流用です。
実行画面 (27KB PNG)
右側のリストボックスの値が測定値で、1024.00 が期待される値です。 カッコ内は実周波数です。 別の周波数の場合も試しました。
データ測定時刻を実時間と結び付ける
PC オーディオ入力は、音を飛ばしてしまっても知らん振りをする、というような話を聞いた気がします。 CPU 負荷が大きいとき、システム時刻をどれほど信用してよいものか。
簡単便利という方針だと、システム時刻は信用せざるを得ません。 測定結果をファイルに書き込むとすれば、それにシステム時刻情報も含めておけばよいでしょう。 もちろん、サンプリングレートの各回ごとにシステム時刻を取得する必要はありません。 測定結果を記録するルーチンが、ある変数を参照すると、そこにはいつでも最新のシステム時刻が入っている、という状態を作り出せば便利です。 タイマーを非周期的に使えば、そのような状態にすることができます。
注意しなくてはならない点は、V/F 変換器の入力時刻と、そのデータが MM_WIM_DATA メッセージで受け取られる時刻の間には、少なくとも BufferLength によって決まる 1 サンプル周期の遅れがあることです。
オフセットと利得の調整
目的は V/F 変換器に入力されている電圧を知ることです。 通常は 0V と、値がわかっている電圧を入力した場合の測定値を調べて、変換用一次関数の 2 つの係数を決めます。
連続して測定することが不必要なら、手動で済ませるのが簡単です。 プログラムを較正モードにして、今の入力電圧は 0V だぞ、とか今度は +1.000V だぞ、とか教えます。 周囲温度が大きく変わったりしたときは較正をやり直します。 用心のために例えば一時間ごとに較正を行ったりするのもよいでしょう。
連続測定が必要な場合や、較正なんて面倒だ、という場合は自動較正にします。 入力電圧をアナログマルチプレクサーで切り換えます。 44.1kHz PC オーディオで 4096 点 FFT、出力データレートが 1 秒に一回以下でよければ、 あるいは出力データレートが 1 秒に 10 回でも「較正のためにこの区間のデータはありません」が許されるなら、 V/F 変換器は 1 つで済みます。
連続測定で出力データレートは 1 秒に 10 回を厳守ということになると、V/F 変換器が 2 つ必要になります。
自動較正と多入力チャンネル化、周波数多重化
PC オーディオ入力は 2 チャンネルありますから、単純に V/F 変換器を 2 つ同時使用できます。 自動較正のために V/F 変換器を 2 つ使用するなら、入力チャンネル数は 1 になってしまいます。 そこで、18kHz 〜 10kHz と 9kHz 〜 5kHz とかに使用周波数帯域を分離すれば、PC オーディオ 1 入力に 2 つの V/F 変換器を接続できます。
但し、9kHz 〜 5kHz 帯を使用するチャンネルは電圧分解能が悪くなってしまいます。 この周波数帯は、V/F 変換器出力に 1/2 分周器を接続して較正時にのみ使用する方法も考えましたが、次項で説明する入力マルチプレクサー切り換えタイミング問題もあって、うまくいきません。
アナログ入力マルチプレクサーの切り換え
入力マルチプレクサーの切り換えは、パラレル・シリアルポートのほか、オーディオ出力によっても可能です。 問題は PC オーディオのサンプリング単位の切れ目を外部から知ることができない点にあります。 すると、較正状態のチャンネルを測定状態に戻すとき、どうしても両チャンネルを同時に測定状態にして別のオーディオ入力チャンネルに入力したくなります。 結果的に連続計測・10sps 厳守の場合、アナログ入力は 1 チャンネルしか使えません。 何かいい方法を思いつくかも知れませんが。
補助デジタル入力
実際の運用では補助的なデジタル入力が何ビットか必要なこともあるでしょう。 測定時刻のマーカーにも使えます。 FFT 後の周波数スペクトラムを見ていて気づいたのですが、使用するつもりがない 1 〜 2 kHz 以下の周波数帯を使って 3 とか 4 bit のデジタル信号が送れそうです。 それほど多くの追加部品は必要ないでしょう。
これの第一の使い道は、アナログ入力マルチプレクサーの状態を PC に知らせることにあります。 ソフトウェアは、このデータブロックは有効かどうか、入力マルチプレクサーがどの状態のときの出力かを確実に知ることができます。
PC オーディオ出力でアナログ入力マルチプレクサーを制御する
周波数変調もしくは PWM 変調で 2 bit くらいは可能か? このあたりは「ぶりき缶」に依頼します。
入力マルチプレクサー順次切換え方式
部品点数削減のため、入力マルチプレクサーが勝手に順次切換えられ、そのタイミングを示すトーン信号が送られてくる方式を検討することになりました。 この方法は自動較正を行ないながらも、最大のサンプリングレート (当面の目標 5sps) が実現できます。 加えて、低周波トランスを使わずに、フォトカプラーを使って受信側無電源の音声帯域信号の伝送ができそうだ、との検討結果もあります。
相手が勝手に動いて行く、それに同調する。 「Adaptive なんとか」とでも言うのでしょうか、けっこうめんどうです。 まず粗い位相調整をして、それが成功したら細かい位相調整 (Fine tunning) に入ります。
データ点数 4410 (100ms) の「フィールド」が 4 つ集まって点数 4 * 4410 (400ms) の「フレーム」を構成します。 粗調整は 1 フィールドにつき 4 回、位相をずらして 1024 点 FFT を行い、この結果が 4 * 4 個集まったところでもっともらしい位置を決めます。 Fine 位相調整は、タイミングトーンがあるとみなされたフィールドの直前と直後そして中央、合計 3 つの位相で 1024 点 FFT を行い、トーン振幅の比をもとに進み量・遅れ量を推定します。 これに基づいて次回のフィールド推定位置を求めますが、方法によっては振動的になったり、同期をはずしてしまうこともあって、充分な動作テストが必要です。
私の目的には Cygwin より MinGW のほうがよさそうです。
新方式の問題点
継続時間 100ms の 320Hz トーンバーストが 400ms 周期で送られて来て、これを頼りにアナログマルチプレクサーの状態を推定するシミュレーションを行いました。 トーンバーストの周期が±5% 程度変動しても追従はできますが、フレーム位相誤差の限度を超えてしまうことがあります。 ここで、フレーム位相誤差の限度とは ±(44100/10 - 4096)/2 サンプル相当、時間で言えば ±3.56ms です。 変動が予測できる、たとえば 400ms 周期の誤差のようなものであれば、対応することは可能です。
とはいっても、新方式では出力データレートの正確さは 320Hz トーン信号周波数の精度=入力マルチプレクサー切換え周期によって決まりますので、あまりにも誤差が多いと出力データレート 5sps とか言えなくなってしまいます。 トーン周波数・マルチプレクサー切換え周期を水晶・セラミック発振器から得るようにすれば、数パーセントもの誤差は考えなくてよいでしょう。 調整をするつもりなら LC 発振器でも平気です。 幸いなことに FFT + 補間プログラムで納得がいくまで調整できます。
トーン信号による V/F 出力周波数帯への妨害は問題ないだろうか。 320Hz の第 7, 9 次高調波の近くで、計測・補間処理への影響を調べました。 問題はないようですが、しらみつぶしの検証は、まだ行っていません。
調べていくうちに、V/F 出力周波数帯の高調波の折り返し雑音が、320Hz トーン信号の振幅判別に影響を与えて、フレーム同期処理に悪影響を及ぼしているらしい現象を見つけました。 測定結果に重大な影響を与えるほどではないのですが。
1 フレーム 8 フィールド方式
この方式は、320Hz タイミングトーン信号と V/F 周波数信号を原理的に分離するために考えました。
簡単にアナログ入力を 4CH 化できるという利点もあります。
CH-0 .. CH-3 に同じ入力を与えれば 1 チャンネル 5sps です。
0: アナログ CH-0 4: アナログ CH-2
1: 基準電圧 (1) 5: 基準電圧 (2)
2: アナログ CH-1 6: アナログ CH-3
3: 320Hz timming tone 7: 320Hz timming tone
これでトーン信号 → V/F 出力信号の干渉は避けられます。
しかし逆方向の妨害、つまり V/F 出力周波数の高調波折り返し雑音が 320Hz
トーン信号の振幅判別に影響を与えて同期を乱す問題は残ります。
資料 ― 現在、同期処理はどのような波形を見ているか
グラフの上段が同期フレーム直前 + 157、中段が中央、下段が直後 - 157 の時間軸波形です。 崩れたチェッカーフラグのように見えるのは 14593.3Hz の方形波です。 これの第 3 次高調波の折り返し雑音が 320Hz 付近に現れます。 小振幅のノイズは意識的に加えてたものです。
フレーム同期方法の改善
V/F 出力周波数の高調波がフレーム同期動作に与える影響を避けるため、第 3 の同期方法として、時間軸波形を直接調べて同期位相ずれを検出する処理を追加しました。 これは、以前の同期処理が全て成功して、本格的な計測に入ったときに使用します。 原理的にいって突発的なノイズには弱いですから、信じがたい結果が得られたときはすぐに前段の同期方法に戻るようにしています。 計測それ自体は継続できます。
フレーム同期処理をまとめます。
(1) 1 フィールドごとに位相をずらして 4 回の 1024 点 FFT を行い、
320Hz timming tone の振幅を頼りに、もっともらしい位相を求める。
(2) 320Hz tone 信号があると推測されたフィールドの直前・中央・直後、
合計 3 回の 1024 点 FFT を行い、320Hz 信号振幅の比を基に
位相ずれを推定して補正する。 失敗した場合は (1) に戻る。
(3) 時間軸波形を直接調べて同期位相ずれを検出し、補正する。
検出に失敗した場合は (2) に戻る。
(つづく)