Linux(macでも同様)からUSBのシリアル通信でコントロールしようとした時にはまったところをメモ。
コントロールは“Standard Commands for Programmable Instruments(SCPI)“という言語?を用いて行う。 自動ステージなんかもSCPIを用いてコントロールできるらしい。 コマンドを送って設定を与えたり、クエリを送って返答を読み出すことで設定、値を読み出すことができる(説明書を参照)。
pythonのmoduleである”pyserial”を用いて通信を行った。
pythonを用いてシリアル通信を行うためのpython module。
pyserialのインストールはここからsourceをダウンロードして解凍、ディレクトリに入った後、
python setup.py install
で完了。
簡単な以下のようなコードHVtest.pyを
#coding utf-8 import serial import time from time import localtime ser = serial.Serial("/dev/ttyUSB0",9600,timeout=1)## macでやろうとした時は/dev/ttyUSB0->/dev/tty.usbserial-A1030KW5 print "device open status : " + str(ser.isOpen()) ser.write("*IDN?") ser.readline()
python HVtest.py
で実行。
結果は、ser.isOpen()はTrueを返しており、通信自体は確立している様子。 しかし、“*IDN?”の返答が返ってこない。
結局、鍵は”改行コード”。 module側がWindows型の改行コードであるCR+LF型であるため、それに合わせるようにコマンドを送る際には
ser.write("*IDN?\r\n")
のようにしなくてはならなかった。 さらに、読み出しも1行目には空行が入るため、readline()を二度行う必要がある。
以上を踏まえて、3 channel のHV,Currentを読み出し、日付ごとにファイルを分けて書き出すモニタリングプログラムを下に示す。
#coding utf-8 import serial import time from time import localtime ser = serial.Serial("/dev/ttyUSB0",9600,timeout=1) print "device open status : " + str(ser.isOpen()) print "serial name : " + str(ser.name) ser.write("*IDN?\r\n") ser.readline() print ser.readline().replace("\r\n","\n") timestamp = time.strftime("%Y%m%d",localtime()) print " now data taking... " f = open("data{0}.dat".format(timestamp),"w") while True: mtime = time.time() if timestamp != time.strftime("%Y%m%d",localtime(mtime)): f.close timestamp = time.strftime("%Y%m%d",localtime(mtime)) f = open("data{0}.dat".format(timestamp),"w") ser.write(":MEAS:VOLT? (@0-2); CURR? (@0-2)\r\n") ser.readline() dataBuf = ser.readline().replace("\r\n","\n").replace(","," ").replace("V","").replace("A","") f.write(str(mtime)+" "+dataBuf.replace(";"," ")) f.flush() f.close ser.close
出力ファイルには各行にUNIX Time, 3ch のHV, 3ch のCurrentがスペースで区切られて出力される。
:READ で読み出せる項目には、無印, NOMinal, LIMit, BOUnd がある。 (:READ:VOLT? , :READ:VOLT:NOM? , :READ:VOLT:LIN? , :READ:VOLT:BOU?)
それぞれの意味は、