【C#】【VISA】計測機器をPCから制御するVISA入門
計測機器をPCから制御
計測器インターフェース規格のVISA(Virtual Instrument Software Architecture)ライブラリを用いて、
PCから計測機器を制御することができる。
VISAライブラリを使えば計測機器(オシロスコープ、周波数発振器、安定化電源、などなど)をPCから制御できる。
簡単なサンプルコードをご紹介します。
VISAライブラリをインストールする
IVI.netを取得する。
インストールすると、デフォルトで下記のdllファイルが作成される。
C:\Program Files\IVI Foundation\VISA\VisaCom64\Primary Interop Assemblies\Ivi.Visa.Interop.dll
使用する計測機器によってそのメーカー毎にVISAライブラリがインストールできる。
・National Instruments製⇒NI-VISA
・菊水製⇒KI-VISA
・Keysight Technologies製⇒Keysight VISA
・Rohde & Schwarz製⇒R&S VISA
参照に追加する
C#.NETでプロジェクトの参照を追加するに上記のDLLライブラリファイルを追加する。

インターフェースのセットアップ
PCと繋ぐインターフェースを計測機器側で設定しておくこと。
RS232C,USB,GPIBなど、機器ごとに接続できるインターフェースが決まっている。
SCPIコマンド
基本のコマンドみたいなものがある。
IEEE488.2共通コマンド
*CLS | ステータスデータ構造体をクリアします。 |
---|---|
*ESE | イベントステータスイネーブルレジスタビットを設定します。 |
*ESR | イベントステータスレジスタを問い合わせます。 |
*IDN | 識別ストリングを問い合わせます。(製造業者の情報) |
*OPC | 待機中が検出された装置のすべての動作が終了すると、装置は操作完了メッセージをイベントステータスレジスタに生成します。 |
*RCL | メモリに保存した内容を読み出します。 |
*RST | 装置のリセット。 |
*SAV | 現在の設定をメモリに保存します。 |
*SRE | サービスリクエストイネーブルレジスタビットを設定します。 |
*STB | ステータスバイトとマスタサマリステータスビットを読み取ります。 |
*TRG | トリガコマンド |
*TST | 自己診断の実行 |
*WAI | 待機中の動作なしフラグが「真」になるまで、以降のコマンドやクエリを実行しないようにします。 |
この共通コマンド以外にその計測器の独自のコマンドがあります。
それは、取説やユーザーマニュアル等に記載されています。
サンプルコード
今回は、菊水製の電子負荷装置をUSB接続した場合のサンプルコードを載せます。
画面デザイン

ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
using Ivi.Visa.Interop; using System; using System.Data; using System.Globalization; using System.Linq; using System.Windows.Forms; namespace Sample_VISA { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public const string vid = "0x0B3E"; //ベンダーID 菊水 /// <summary> /// ロード オン /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { ResourceManager rm = new ResourceManager(); FormattedIO488 msg = new FormattedIO488(); //USB接続の場合で、I/Oリソースを探してリストの最初のものを接続できるようにした。 string[] instruments = rm.FindRsrc("USB[0-9]?*::INSTR"); var visaad = instruments.Where(usbid => usbid.Contains(vid)).ToList(); //ベンダーIDを元に指定検索 //Open msg.IO = (IMessage)rm.Open(visaad[0], AccessMode.NO_LOCK, 0, ""); //1つ目の計測機器visaad[0],2つ目visaad[1]・・・ //I/Oリソース表示 textBox1.Text = visaad[0]; //ID問合せ msg.WriteString("*IDN?"); //IEEE488.2共通コマンド *IDN?・・・ID(識別番号)問合せ //responseデータ取得 string response = msg.ReadString(); //読出し //response結果表示 textBox2.Text = response; //Close msg.IO.Close(); } /// <summary> /// ロードON /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { ResourceManager rm = new ResourceManager(); FormattedIO488 msg = new FormattedIO488(); string[] instruments = rm.FindRsrc("USB[0-9]?*::INSTR"); var visaad = instruments.Where(usbid => usbid.Contains(vid)).ToList(); //ベンダーIDを指定検索 msg.IO = (IMessage)rm.Open(visaad[0], AccessMode.NO_LOCK, 0, ""); msg.WriteString("FUNC:MODE CC"); //モード設定 msg.WriteString("CURR:RANG HIGH"); //レンジ設定 msg.WriteString("CURR 10.0"); //電流値設定 msg.WriteString("INP 1"); //ロードON msg.IO.Close(); } /// <summary> /// ロードOFF /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { ResourceManager rm = new ResourceManager(); FormattedIO488 msg = new FormattedIO488(); string[] instruments = rm.FindRsrc("USB[0-9]?*::INSTR"); var visaad = instruments.Where(usbid => usbid.Contains(vid)).ToList(); //ベンダーIDを指定検索 msg.IO = (IMessage)rm.Open(visaad[0], AccessMode.NO_LOCK, 0, ""); msg.WriteString("INP 0"); //ロードOFF msg.IO.Close(); } /// <summary> /// 電流、電力、電圧の測定 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button4_Click(object sender, EventArgs e) { ResourceManager rm = new ResourceManager(); FormattedIO488 msg = new FormattedIO488(); string[] instruments = rm.FindRsrc("USB[0-9]?*::INSTR"); var visaad = instruments.Where(usbid => usbid.Contains(vid)).ToList(); //ベンダーIDを指定検索 msg.IO = (IMessage)rm.Open(visaad[0], AccessMode.NO_LOCK, 0, ""); ////////////////////// /// SampleCommand //// ////////////////////// //電流値測定 msg.WriteString("MEAS:CURR?"); //書込み string response_curr = msg.ReadString(); //読出し //電力値測定 msg.WriteString("MEAS:POW?"); //書込み string response_pow = msg.ReadString(); //読出し //電圧値測定 msg.WriteString("MEAS:VOLT?"); //書込み string response_volt = msg.ReadString(); //読出し //Close msg.IO.Close(); //実数(指数)で返ってくる場合は、整数に変換する。 decimal res_curr = decimal.Parse(response_curr, NumberStyles.Float); decimal res_pow = decimal.Parse(response_pow, NumberStyles.Float); decimal res_volt = decimal.Parse(response_volt, NumberStyles.Float); //Result textBox3.Text = res_curr.ToString(); textBox4.Text = res_pow.ToString(); textBox5.Text = res_volt.ToString(); } } } |
*IDNコマンドを送信すると、
(例) 形名PLZ164W、製造番号AB123456、ROMバージョン1.00の場合
KIKUSUI,PLZ164W,AB123456,1.00
というレスポンス結果が返ってきます。
おまけ 接続インターフェース別の接続子方法
GPIB | GPIB[board]::PrimaryAddress[::SecondaryAddress][::INSTR]
例:GPIB0に接続されたプライマリアドレス3の計測器の場合 GPIB0::3::INSTR |
---|---|
シリアル (RS232C) |
ASRL[board][::INSTR]
例:シリアルポートCOM1に接続された計測器の場合 ASRL1::INSTR |
USB | USB[board]::VendorID::ProductID::SerialNumber[::InterfaceNumber][::INSTR]
例:ベンダーID(VID)2878、プロダクトID(PID)4121、シリアルナンバー”00000001”を持つUSNTMC計測器の場合 USB0::0x0B3E::0x1019::00000001::INSTR |
msg = rm.Open(“GPIB0::1::INSTR”, AccessMode.NO_LOCK, 0, “”) ‘GPIBの書き方例
‘msg = rm.Open(“ASRL1::INSTR”, AccessMode.NO_LOCK, 0, “”) ‘RS232Cを使用した例
‘msg = rm.Open(“USB0::0x0B3E::0x1019::00000001::INSTR”, AccessMode.NO_LOCK, 0, “”) ‘USBを使用した例
‘msg = rm.Open(“MYDEV1”, AccessMode.NO_LOCK, 0, “”) ‘VISAエイリアスを使用した例
まとめ
今回は、計測機器をPCから制御するVISA規格のSCPIコマンドについてご紹介しました。
業務で計測機器を使用することが多い人は、PCからの制御を作って置けば、簡単に計測が出来て、データもいちいちUSBなどで機器から吸い出さなくても、PCに飛んでくるのですぐに保存できたり、CSV出力できるようにプログラムを組んでおけばデータ分析も簡単になり、業務効率UPできますよ。