GPIB、PyVISAで完全自動測定

# きっかけ
測定器を制御して測定を自動化しようとしたのがきっかけです。
これを見ればどのようにPythonで測定を自動化できるか分かります。
もし再現したい場合はすべて読んでから行ってください。
# はじめに
[PyVISA](https://pyvisa.readthedocs.io/en/latest/)とはPythonで測定器を自動で制御できるようにするライブラリです。

どのように内部で制御されているかはNational Instruments社(NI)の[計測器制御に必要なソフトウェア(GPIB、Serial、VISA、USBなど)](https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019XKkSAM&l=ja-JP)を見るとわかりやすいです。
上記サイトの図に測定器制御ソフトウェア層が書かれています。
基本的に下位層から、ハードウェア層、ドライバ層、計測器ドライバ層、アプリケーション層に分かれています。

また図からわかりますが、今回、ハードウェアから通信を受けるプロトコルにはGPIBを用いるので、ドライバ層にはNI-488.2などが使われるのが一般的です。
GPIBプロトコルとはPCから受け取った情報を測定器に分かる通信に変えるようなものと思っておいたらいいです。
測定器にGPIBケーブルに加えてUSB、LANケーブルを指すところがありそちらを使うのであれば、NI-VISAのみインストールすればよいみたいですね(未検証)。
# 環境
Windows10
Python3.9.7
# 準備
Pythonのインストールは終えている状態から始めます。
### 大まかなハードウェアの構成

~~~
PC-USB/GPIB変換用アダプタ-GPIBケーブル-測定器(-GPIBケーブル-測定器-GPIBケーブル-測定器-...)
~~~

今回はGPIBプロトコルを用いるので変換アダプタを使用してPCと接続します。
GPIBケーブルには両端にGPIBコネクタが付いているのでそれをつなげることでいくつも測定器をつなげることが可能です。
変換アダプタにはKEYSIGHT TECHNOLOGIES社の[82357B USB/GPIB Interface High-Speed USB 2.0](https://www.keysight.com/jp/ja/product/82357B/usb-gpib-interface-high-speed-usb-2-0.html)を使用しています。

また先程、USB/GPIB変換用アダプタ用のドライバにはNI-VISA、NI-488.2が使われるのが一般的と言いました。
しかし今回、変換用アダプタにはNI社製ではなくKEYSIGHT TECHNOLOGIES社製のものを使用するので、[Keysight IO Libraries Suite](https://www.keysight.com/jp/ja/lib/software-detail/computer-software/io-libraries-suite-downloads-2175637.html)のみで十分です。
### インストールするもの
ここで一旦PCにインストールするものをまとめておきます。

**[Keysight IO Libraries Suite](https://www.keysight.com/jp/ja/lib/software-detail/computer-software/io-libraries-suite-downloads-2175637.html)**
上記リンクからダウンロード方法横の[Download IOLS 20**]ボタンをクリックしてインストールしてください。

**PyVISA**

~~~
$ pip install pyvisa
~~~~

左下の検索窓からPowerShellと調べ起動させましょう(もちろんコマンドプロンプトでも可能です)。
$以降の上記のコマンドを打ち込みましょう。
エラーが出なければインストールできました。

これで準備完了です。

# PyVISAで制御
ここからPythonファイルを書いて測定器を自動制御していきます。

### GPIBで測定器を確認
まずはGPIBで測定器が検出できているかを確認しましょう。
左下の検索窓からPowerShellと調べ起動させましょう。
PowerShellで以下のコマンドを打ち込んでください。

~~~
$ python
>>> import pyvisa
>>> rm = pyvisa.ResourceManager()
>>> rm.list_resources()
('ASRL1::INSTR', 'ASRL2::INSTR', 'GPIB0::12::INSTR')
>>> inst = rm.open_resource('GPIB0::12::INSTR')
>>> print(inst.query("*IDN?"))
(測定器の名前などが出力される)
>>> exit()
~~~
PyVISAのドキュメントに載っている通りに打ち込んだだけです。
順番に確認しましょう。

~~~
$ python
>>> import pyvisa
>>> rm = pyvisa.ResourceManager()
>>> rm.list_resources()
('ASRL1::INSTR', 'ASRL2::INSTR', 'GPIB0::12::INSTR')
~~~

まずPythonを起動させ、PyVISAライブラリをインポートしました。
その後、`rm`でインスタンスを作りました(よく分からなければおまじないだと思ってください)。
3行目ではPCに接続されているものが出てきます。
`'GPIB0::12::INSTR'`のようなものが出てくれば測定器を検出できています。
2つ以上の測定器をつなげていれば、12の部分がさまざまに変わっていくつか出力されます。

~~~
>>> inst = rm.open_resource('GPIB0::12::INSTR')
>>> print(inst.query("*IDN?"))
(測定器の名前などが出力される)
~~~

`inst`に測定器のアドレスを覚えさせます。
`inst.query("*IDN?")`は測定器の情報を聞き、答えが返り値で得られるものです。
それを`print`しているので測定器の名前などが出力されるのです。
2つ以上つなげている場合は、GPIBのアドレスと測定器の対応をメモしておきましょう。

### Pythonで自動測定
例えばここでは電源とスペクトラムアナライザの2つを繋いでいて、それぞれのGPIBのアドレスが`'GPIB0::0::INSTR'`、`'GPIB0::1::INSTR'`だったとします。

~~~auto_measure.py
import pyvisa

#設定
rm = pyvisa.ResourceManager()
power = rm.open_resource('GPIB0::0::INSTR') #電源
analyzer = rm.open_resource('GPIB0::1::INSTR') #スペクトラムアナライザ

# 電源の電圧を計測
max_volt = power.query('MEAS:VOLT?')
print(max_volt)

# スペクトラムアナライザのピーク周波数を計測
analyzer.write('CALC:MARK:MAX')
peak_freq = analyzer.query('CALC:MARK:X?')
print(peak_freq)
~~~

コードの説明をします。

~~~
import pyvisa

# 設定
rm = pyvisa.ResourceManager()
power = rm.open_resource('GPIB0::0::INSTR') #電源
analyzer = rm.open_resource('GPIB0::1::INSTR') #スペクトラムアナライザ
~~~

まずは`power`と`analyzer`に機器のアドレスを覚えさせます。

~~~
#電源の電圧を計測
max_volt = power.query('MEAS:VOLT?')

# queryを使わない方法
# power.write('MEAS:VOLT?')
# max_volt = power.read()

print(max_volt,'V')
~~~

`'MEAS:VOLT?'`を測定器に送り、返り値を`max_volt`に代入します。
ここで`query`は`write`、`read`をつかって同じことができます。
`write`で測定器に質問を送って、`read`で回答を得るイメージです。
`query`はこれを一気に行います。

~~~
#スペクトラムアナライザのピーク周波数を計測
analyzer.write('CALC:MARK:MAX')
peak_freq = analyzer.query('CALC:MARK:X?')
print(peak_freq,'Hz')
~~~
まずマーカーをピーク周波数にセットします。
`write`はこのように質問以外にも設定が送れます。
例えば電源の電圧値を設定したり、スペクトラムアナライザのフロントパネルの中心周波数を設定したりできます。
そのマーカーの値を読み出すことでピーク周波数を計測します。

この`auto_measure.py`をPowerShellで実行します。

~~~
$ python auto_measure.py
00.0000V
00.0000Hz
~~~
電圧とピーク周波数が出力されれば成功。

### SCPIコマンド
測定器に送るコマンドはSCPIコマンドと呼ばれ、階層構造になっています。
これは測定器の製造会社によって異なっていたり、測定器ごとに異なっていたりするので、測定器ごとに調べる必要があります。
[測定器の名称 クイックリファレンス]や[製造会社名 クイックリファレンス]で検索すると出てくるでしょう。

# まとめ
ハードウェアの構成とPCのインストールソフトウェア、GPIBプロトコルにおけるPyVISAの具体的な使い方を解説しました。
最近のものにはUSB、LANケーブルを指すところがあるのでGPIBを使わなくても良くなりました。
しかし昔からあるものを測定器の1つとして使う場合、GPIBで揃える方がなにかと良いかもしれません。
ぜひ参考になれば幸いです。

# コード
https://github.com/go-yu/GPIB_PyVISA

# 参考サイト
[計測器制御に必要なソフトウェア(GPIB、Serial、VISA、USBなど)](https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019XKkSAM&l=ja-JP)
[Keysight IOライブラリ・スイートのダウンロード・アーカイブ：すべてのダウンロード](https://www.keysight.com/jp/ja/lib/software-detail/computer-software/io-libraries-suite-downloads-2175637.html)
[PyVISA: Control your instruments with Python](https://pyvisa.readthedocs.io/en/latest/)
[Pythonを用いた計測器制御 [pyvisa]](https://qiita.com/Yuziii/items/8e0437b33555647b0fc4#ni-visa%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)