IoTで使うPython入門 Step5-Python3 VISA②DMM Keithley 2000 電圧測定(その1)
VISAという規約を使って計測器と通信をします。前回、GPIB-USB変換器を利用してPCとつなぎました。ここでは、具体的に接続したDMMを使って電圧を測定します。
●電圧の測定
2台のDMMで同じ電圧源を測定します。電圧源はTL431を使った2.5V出力です。
import visa from time import sleep Keithley2000_1_Addr = "GPIB0::6" Keithley2000_2_Addr = "GPIB0::18" r = visa.ResourceManager() keithley2000_1 = r.open_resource(Keithley2000_1_Addr) keithley2000_2 = r.open_resource(Keithley2000_2_Addr) keithley2000_1.write(":conf:VOLT:DC:range 10") keithley2000_2.write(":conf:VOLT:DC:range 10") while 1: data6 = keithley2000_1.query(":read?") data18 = keithley2000_2.query(":read?") sleep(1) print("6DC: ", float(data6)) print("18DC: ", float(data18))
実行している様子です。
6DC: 2.49226917 18DC: 2.4924012 6DC: 2.49227095 18DC: 2.49240339 6DC: 2.49227077 18DC: 2.49240394 6DC: 2.49226933 18DC: 2.49240256 6DC: 2.4922712 18DC: 2.49240278 6DC: 2.49227047 18DC: 2.49240329 6DC: 2.49226995 18DC: 2.49240302 6DC: 2.49226884 18DC: 2.49240154 |
●まとめて計測
100個のデータをロギングしてPCに読み込みます。動作しているDMMは1台だけです。このプログラムは、検索するといろいろなところで見かけます。
10行;*rstはリセット・コマンド、*clsはステータス・レジスタの消去
14行;インターバル時間を1msに設定。サンプルでは500msでした。
15行;測定データの読み取る数を100個に設定。サンプルでは10個でした。
16行;*sre 1はService request enableコマンドを1に設定。レジスタは1バイトで、ビットごとに定義され、6個あり、最上位ビットから、OSB = Operation Summary Bit、0、ESB = Event Summary Bit、MAV = Message Available、QSB = Questionable Summary Bit、EAV = Error Available、0、MSB = Measurement Summary Bitが定義されている。指定するときは、おもみ付けの数値を加算した合計を書く。全部のビットが'1'ならば512になる。
17行;トリガを10回
18行;「トリガ待ち」状態になると、リモート・インタフェース経由で*TRGにより測定器のトリガが実行される
19行;トリガ遅延時間
20行;合計10の読み取りをキャプチャするようにバッファのサイズを設定
21行;バッファがいっぱいになったときに充填を停止する。ここまでが設定の記述。
22行;設定内容に従って測定開始
23行;ソフトウェア・トリガをデバイスに送信
24行;待ち状態のサービス・リクエスト(SRQ)イベントが完了するのを待つ
import visa Keithley2000_1_Addr = "GPIB0::6" Keithley2000_2_Addr = "GPIB0::18" r = visa.ResourceManager() keithley2000_1 = r.open_resource(Keithley2000_1_Addr, timeout = 20) # , values_format = single) keithley2000_2 = r.open_resource(Keithley2000_2_Addr) keithley2000_1.write("*rst; status:preset; *cls") data6 = [] print('\n---start ---') try: interval_in_ms = 1 number_of_readings = 100 keithley2000_1.write("status:measurement:enable 512; *sre 1") keithley2000_1.write("sample:count %d" % number_of_readings) keithley2000_1.write("trigger:source bus") keithley2000_1.write("trigger:delay %f" % (interval_in_ms / 1000.0)) keithley2000_1.write("trace:points %d" % number_of_readings) keithley2000_1.write("trace:feed sense1; feed:control next") keithley2000_1.write("initiate") keithley2000_1.assert_trigger() keithley2000_1.wait_for_srq(timeout=None) data6 = keithley2000_1.query_ascii_values("trace:data?") print("6DC : ", len(data6), data6) except KeyboardInterrupt: print('CTRL-C') print('\n -- end --')
write、assert_trigger、query_ascii_valuesなどは、/pyvisa/resources/messagebased.pyに定義されています。しかし、writeで書かれている16行から22行の内容を解説した文書が見つかりません。したがって、SCPIコマンドの何が発行されているかが不明です。
wait_for_srqは、/pyvisa/resources/gpib.py に定義されています。
●得られたデータでグラフを描画
得られた測定データを使って、最頻度グラフを描きます。上記のプログラムの先頭に、
import matplotlib.pyplot as plt
を記述し、次の2行を最後に追加しています。
plt.hist(data6, rwidth=0.8) plt.show()
実行結果です。
●SCPIコマンドで書き直す
「Model 2000 Multimeter User’s Manual2000-900-01 Rev. J / August 2010」 C Example Programsの事例 「DMM6500 in a Model 2000 Application Emulation and Migration Guide」 「Model DAQ6510 Data Acquisition nad Multimeter System User's Manual」 |
などを参考にして、まったく同じではないですが、SCPIコマンドを使うように書き直しました。データの取得は40までならエラーなく動きます。100個を取得するとき、sleep(5)を入れて待ちます。INITを送った後に、データが用意できたかを確認するプログラムを入れるのが確実です(次回予定)。
import visa from time import sleep Keithley2000_1_Addr = "GPIB0::6" Keithley2000_2_Addr = "GPIB0::18" r = visa.ResourceManager() keithley2000_1 = r.open_resource(Keithley2000_1_Addr) keithley2000_2 = r.open_resource(Keithley2000_2_Addr) keithley2000_1.write("*rst;*cls") data6 = [] print('\n---start ---') try: interval_in_ms = 1 number_of_readings = 40 keithley2000_1.write("STAT:MEAS:ENAB 512:*SRE 1") keithley2000_1.write(":CONF:VOLT:DC:range 10") keithley2000_1.write(":TRIG:COUN %d" % number_of_readings) keithley2000_1.write(":TRIGer:DELay %f" % (interval_in_ms / 1000.0)) keithley2000_1.write(":TRAC:POIN %d" % number_of_readings) keithley2000_1.write(":TRAC:FEED SENS1;FEED:CONT NEXT") keithley2000_1.write(":INIT") data6 = keithley2000_1.query_ascii_values(":TRACE:DATA?") print("6DC : ", len(data6), data6) except KeyboardInterrupt: print('CTRL-C') print('\n -- end --')
●二つの計測を表示
エラーが取り切れていませんが、測定部分を関数にしました。plt.hist(data1, rwidth=0.8) とplt.hist(data2, rwidth=0.8)のように同じ描画コマンドを実行すると、同じグラフ枠の上に、色を変えて表示します。
import visa from time import sleep import matplotlib.pyplot as plt Keithley2000_1_Addr = "GPIB0::6" Keithley2000_2_Addr = "GPIB0::18" r = visa.ResourceManager() keithley2000_1 = r.open_resource(Keithley2000_1_Addr) keithley2000_2 = r.open_resource(Keithley2000_2_Addr) #print('\n---start ---') def read_Keithley2000(GPIB, number): GPIB.write("*rst;*cls") interval_in_ms = 1 number_of_readings = number GPIB.write("STAT:MEAS:ENAB 512:*SRE 1") GPIB.write(":CONF:VOLT:DC:range 10") GPIB.write(":SENS:RES:NPLC 1") GPIB.write(":TRIG:COUN %d" % number_of_readings) GPIB.write(":TRIG:DEL %f" % (interval_in_ms / 1000.0)) GPIB.write(":TRAC:POIN %d" % number_of_readings) GPIB.write(":TRAC:FEED SENS1;FEED:CONT NEXT") GPIB.write(":INIT") sleep(10) data = GPIB.query_ascii_values(":TRACE:DATA?") return data #print('\n -- end --') data1 = read_Keithley2000(keithley2000_1,100) data2 = read_Keithley2000(keithley2000_2,100) print(data1) print(data2) plt.hist(data1, rwidth=0.8) plt.hist(data2, rwidth=0.8) plt.show()
重なって表示されると思ったのですが、ずれました。ヤフオクで購入した古い機材なので、少し確度が異なるようです。