2019年1月24日木曜日

PyVISAは無敵かも

春休みに磁気抵抗を測定しようと思い,マグネット電源とシリアル通信しないといけないなぁ,となんとなく気が重くなっていたのですが,すばらしい解決方法を見つけてしまいました。

環境としては,
macOS HighSierra
Python 3.6.3 (finkでインストール)
NI VISA 18.0.0

pip3でpyserialをインストールし,ためしに通信してみました。





こんな感じで,無事に通信できました。
実はここに至るまで紆余曲折あり,一筋縄ではいきませんでした。

ポイントは,コマンドの文字列を送るところです。
最初,ネットの記事を参考に,

>>>ser.write("get o¥n")

のようにしてみたのですが,うまくいかず,基本にもどって,公式ドキュメントを参考にしてみたところ,

>>>ser.write(b'get o¥n')

と書くのが正しいようだったので,そうしてみました。
(いつも学生に,『安易なネット検索はいかん』と言っていたのに,自分でハマってしまった。。。)

帰ってきた文字列を見てみると,CRとかLFが入っているし,『b' '』で囲まれてしまっているので,ちょっと厄介だなぁ,と思っていました。

つづいて,PyVISAをインストール。
うっかり最初,easy_install pyvisaとやってしまったところ,python2.7用のVISAがインストールされてしまいました。
これはいかんと,pip3でインストールしたところ,無事python3用のpyvisaがインストールされました。

PyVISAも,ネット上にはいろいろな情報があふれているのでw,基本にかえりながら,



ここで,重大なことに気づきました!!!
今,macにはusbで(と言ってもUSB-Serial変換アダプタ経由で)マグネット電源が,NIのGPIB-USBアダプタ(アドレスは3)で温度コントローラが繋がっています。

>>> rm = visa.ResourceManager()
>>> print(rm.list_resources())

とやってリストをみると,GPIB機器(GPIB0::3::INSTR)のほかに,ASRL1::INSTRという装置が見えます。

そうでした,そこがVISAのすばらしいところでした。
つまり,pyserialは必要なかったのです。。。

>>> instr1 = rm.open_resource('ASRL1::INSTR')
>>> instr2 = rm.open_resource('GPIB0::3::INSTR')


のように,二つの機器にそれぞれinstr1とinstr2という名前をつけて,通信してみたところ,

>>> instr1.write('get o\n')
(8, <StatusCode.success: 0>)
>>> print(instr1.read())
OUTPUT: 0.0000 TESLA AT 0.0 VOLTS 

>>> instr2.write('*idn?')
(7, <StatusCode.success: 0>)
>>> print(instr2.read())
LSCI,MODEL350,LSA14J9/#######,1.4

>>> 


と,無事にシリアルかGPIBかの区別を全く感じずに通信することができました。

ただ,このままexit()すると

>>> exit()
Exception ignored in: <object repr() failed>
Traceback (most recent call last):
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 108, in __del__
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 243, in close
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 235, in before_close
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 252, in __switch_events_off
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 309, in disable_event
  File "/sw/lib/python3.6/site-packages/pyvisa/ctwrapper/functions.py", line 410, in disable_event
  File "/sw/lib/python3.6/site-packages/pyvisa/ctwrapper/highlevel.py", line 188, in _return_handler
pyvisa.errors.VisaIOError: VI_ERROR_INV_OBJECT (-1073807346): The given session or object reference is invalid.
Exception ignored in: <object repr() failed>
Traceback (most recent call last):
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 108, in __del__
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 243, in close
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 235, in before_close
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 252, in __switch_events_off
  File "/sw/lib/python3.6/site-packages/pyvisa/resources/resource.py", line 309, in disable_event
  File "/sw/lib/python3.6/site-packages/pyvisa/ctwrapper/functions.py", line 410, in disable_event
  File "/sw/lib/python3.6/site-packages/pyvisa/ctwrapper/highlevel.py", line 188, in _return_handler
pyvisa.errors.VisaIOError: VI_ERROR_INV_OBJECT (-1073807346): The given session or object reference is invalid.

のようにちょっと嫌なメッセージが出ます。
おそらくcloseしていないからでしょうが,今日はここまでにします。
うまくいけば,PyQtとか使ってらくちんに測定できるかもしれません。