- リンクを取得
- ×
- メール
- 他のアプリ
- リンクを取得
- ×
- メール
- 他のアプリ
こんにちはドルフィンシステム福島です。
時折、ソフトウェア無線機ではなく普通のファンクションジェネレータやシグナルジェネレータから信号を出力するときがあります。
ファンクションジェネレータやSGをプログラム的に制御したい場合は、通常はSCPIコマンドを送信して制御します。だいたいの測定機に用意されている「プログラミングマニュアル」は、つまるところ当該測定機がサポートしているSCPIコマンドについて解説しています。
SCPIコマンドを送るためのライブラリと物理的なインターフェイス
SCPIコマンドはテキストの命令セットであり、これを送信するための物理的なインタフェースは昔はGPIBで今はイーサネットやUSBが主流です。
プログラムからSCPIコマンドを送信するためには、便利なライブラリが用意されておりVISAと呼ばれています。VISAライブラリは各種測定機メーカーからリリースされていて、NI-VISA、Keysight VISA、TEKVISA等があります。
VISAライブラリを使用してSCPIコマンドを送信する場合、測定機とPCを接続する物理的なインタフェースの違い(GPIBやイーサネット、RS-232C等など)はVISAライブラリが吸収してくれるので便利です。
例えば以下の様に接続しているインターフェイス毎にリソース名を変えて接続します。
TCP/IPで接続する場合
TCPIP0::192.168.0.111::inst0::INSTR
シリアルポートで接続する場合
COM1
USBで接続する場合
USB0::0x0B3E::0x1029::WD000061::0::INSTR
VXI-11通信プロトコルの紹介
https://qiita.com/mmake/items/ee837fd1b8f43e464856
SCPIコマンドについて
SCPIコマンド自体は、基本的にはテキストの文字列を送信します。
*RST
を送信すると、測定機の設定はリセットされ。
OUTPUT ON
とすると出力がオンになる。
SCPIコマンドでは、テキストだけでなくバイナリデータも送信することが出来ます。
多くSGには送信信号のデータパターン(Arb)を送るコマンドが用意されていて、SGの出力パターンをPCで生成し、イーサネットで送り込み、SGから出力する事がプログラム的に可能になります。
テキストバイナリ混在SCPIコマンドを送信する面倒のない方法
結論を申し上げておくと、テキストとバイナリ混在のSCPIコマンドを送信する際には、SCPIコマンドのテキスト部分をu8配列にしてバイナリデータの配列の先頭に結合し、writeでひとまとまりのバイナリデータとして送信する方法が最良です。
テキストとバイナリを別々に送信すると、送信時の不手際により受信側でテキストとバイナリ2つのコマンドが来たと認識してしまうトラブルになりかねません。
どの様なことかは以下で解説します。
バイナリデータを送信する際の例と注意事項
以下は、Tektronix AFG31000ファンクションジェネレータのプログラミングマニュアルに記載されているバイナリデータ(Arb)を送信する際のコード例です(言語はVB)。
01 : Tvc1.FormattedIO.WriteLine("*RST")
02 : Dim num_points = 3000
03 : Dim base = 9000
04 : Dim offset = 6000
05 : Dim SinePoint As Integer
06 : Dim SineWaveData(num_points) As Byte
07 :
08 : For i = 0 To num_points
09 : 'Build sine wave
10 : SinePoint = Int(base + offset * Math.Sin(i / 120))
11 : SineWaveData(i) = SinePoint / 256
12 : Next i
13 :
14 : 'Transfer waveform
15 : 'Transfer arbitrary block data to edit memory
16 : Tvc1.SendEndEnabled = False
17 : Tvc1.FormattedIO.WriteLine("TRACE:DATA EMEM1, #43000")
18 : Tvc1.SendEndEnabled = True
19 : Tvc1.RawIO.Write(SineWaveData)
20 : 'Set CH1 output parameters
前半部は正弦波のバイナリデータを生成し、後半部ではSCPIコマンドでファンクションジェネレータにバイナリデータを送信しています
バイナリデータの送信は、16~19行目でWriteLineメソッドでTRACEコマンドを送信しています。
このTRACEコマンドは、SCPIでバイナリデータを送信する際の一般的な方法で、以下の様にテキストとバイナリデータが混じったSCPIコマンドを送信します。
TRACE:DATA EMEM1, #43000(以降U8バイナリデータ)
TRACEコマンドの#43000はバイナリデータ長を指定しています。
#43000をフォーマット的に表現すると
#nmmmmとなります。
mは、このコマンドで送信するバイナリデータのバイト数を指定する。上記のように3000なら、3000バイトのデータを指定するという意味です。
nは、mの桁数を指定します。
上記のように3000なら4桁なので、4を指定する。10なら2だし、999なら3です。
よって3000バイトのデータを送信する場合は、
#43000
となります。
SendEndEnabledについて
サンプルコードの
1行目で、
Tvc1.FormattedIO.WriteLine("*RST")
が実行されると、*RSTという文字列を含むSCPIコマンドが測定機に送信され、実行される。
これはVISAで一つのSCPIコマンドとして認識され送信されます。
VISAライブラリを使用してSCPIコマンドを送信する場合WriteやWriteLine命令を使用するが、この命令が一つの実行単位として一つのSCPIコマンドが送信されます。
1行目が実行されたら、一つのSCPIコマンドが送信される。1行目と同じ行が3行続いていたら、VISAライブラリにたいし3回実行され、3つのSCPIコマンドが送信されることになります。
TRACEコマンドのようにテキストとバイナリが混ざっている場合はどのように記述すれば良いか?
このサンプルでは、
17行目でテキストのSCPIコマンドを送信し、
19行目でバイナリデータ部分を送信している。
ここで問題なのは、一つのSCPIコマンドなのに、17行目と19行目に分けて実行されているので2つのSCPIコマンドとして送信されてしまいます。
SCPIコマンドを受信した測定機は、
17行目で、バイナリデータが無いTRACEコマンドを受信し、
19行目で、バイナリデータだけの無効なSCPIコマンドを受信することになります。
これでは一つのSCPIコマンドとして送れず都合が悪い。
そこで実行しているのが、
16行目のSendEndEnabled = False
18行目のSendEndEnabled = True
です。
通常、WriteやWriteLineを実行すると、VISAライブラリがSCPIコマンドを送信する際に「EOI (End Of Identify」を有効して送信する。EOIを有効にして送信すると、受信側は一つのSCPIコマンドとして認識します。
しかし
SendEndEnabled = False
としておくと、その後でWriteやWriteLineを実行してもEOIが立たないので、受信側は後続のデータを待つ。
そして、
以下の様に18行目でEOIを有効にし、19行目でデータ本体を送信することで、テキストもバイナリも混在したデータとして送っているのです。
18 : Tvc1.SendEndEnabled = True
19 : Tvc1.RawIO.Write(SineWaveData)
EOIについて
良くSCPIコマンド末尾に終端文字列(通常\n)を付与するかどうかを議論していることがあるが、EOIとは関係がありません。
Writeコマンドを使用して1文字ずつ分割して送信しても最後の文字がEOI = Trueであれば一つのSCPIコマンドとして認識される(はず)
バラバラの文字列として送信しても最後だけがEOI = Trueならば一つのSCPIコマンドになるし、分割した文字列にしてもすべてにEOI = Trueならそれぞれ別々のSCPIコマンドとして認識されてしまいます。
ちなみにEOIは、SCPIコマンド上の概念ではなくその一つ上のプロトコルVXI-11で取り扱う情報です。以下がEOI = true時とfalse時のパケットをWiresharkでキャプチャしたものです。
EOI有効時のイーサネットパケット
EOI無効時のイーサネットパケット
Message Based Settings:Send End Enable
以上、ドルフィンシステム福島でした。
- リンクを取得
- ×
- メール
- 他のアプリ
コメント
コメントを投稿