ファンジェネを操る

先週から取り組んでるのは「ファンクション・ジェネレータに発生させる周波数を,ユーザ指定の任意関数に従って掃引する」というタスクだ(「任意関数」は病的なものではない: exp(-at)とかユーザが指定した点を通る補間多項式とか,その類).やりたい掃引の典型的な例では,10分で30 MHzから0MHzまで落とすことになる.そこまでは確定しているが,その具体的な途中経過こそ実験で試行錯誤する内容である.全体構成は,使いやすいGUIを備えた,PCで走るプログラムからファンジェネにコマンドを送る形になる(GPIBという規格で通信できるファンジェネを使う; プログラム側ではGPIBをしゃべるライブラリを使う; PCのUSB端子にUSB-GPIB変換ケーブルを挿す).
こう書くと簡単そうに思える.つーか私は簡単だと思った.「ユーザ指定の任意関数を適当に離散化して得た点列をファンジェネに教えてやるだけじゃね? 手間と言えばGUIに凝る程度じゃね?」と思った.しかし離散化における時間および出力周波数の確度と,実時間性という制約がかなりの困難を投げかける.
Windowsの備えるタイマ(普通のより細粒度の「マルチメディアタイマ」)では1 ms単位が限界らしい.

timeGetTime minimum resolution は, マルチメディア・タイマーを起動すると 1 ms になります。

LabVIEWのタイマは1 ms単位なので,多分これを使ってるんだろう.
30 MHzのlinear sweepをすると思うと10分は約3E4 sなので1 kHz/s = 1 Hz/msとなる.これなら十分に丁寧だ(おまけに実際には指数関数とかを使うので終盤のsweep rateは小さくなる)...が,本当に処理が1 ms毎に実行されるかと言えば,それは多分されない.ちょっと実験してみると,LabVIEWではループ内のタイマの待ち時間が10 msを切ると誤差が0.1 msくらい出てくる.待ち時間を1 msにしても実際の処理は2 ms毎にしか行われず,何の意味もなくなっている.10 ms毎でがまんすると10 Hz/(10 ms).まぁこれでも十分に丁寧かな.しかしまだ油断はできなくて,本当にこの速度でファンジェネと通信できるか,ファンジェネは通信で受け取ったコマンドにこの速度で従えるか,こういう問題が出てくる.これらはまだ試してない.
他に,任意関数の離散化をファンジェネに予め伝えて覚えさせておいて,後の動作はファンジェネの掃引/変調機能に任せるという手もある.これなら実時間性はファンジェネの担当となり,餅は餅屋で安心だ.しかし覚えておける点の数が問題になる(大抵,点と点とは折れ線でなく階段状に結ばれる).SRS DS345の「任意関数による正弦波の変調」機能では覚えられるのは1500点まで.10 MHzを10分でlinear sweepするプロセスを1000点で離散化するとすると10 kHz/点,36 s/点の階段,これは微妙だ...

><