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()
重なって表示されると思ったのですが、ずれました。ヤフオクで購入した古い機材なので、少し確度が異なるようです。
