IoTで使うPython入門 Step5-Python3 VISA④DMM Keithley 2000 +電源E3631A 設置
実験用の電源を追加します。AgilentのE3631Aです。6V/5A、±25V/1Aの三つの出力が利用できる80Wの実験用電源です。デフォルトで、GPIBとRS-232インターフェースが用意されています。今回、GPIBを使います。
●GPIBアドレス
マニュアルによれば、デフォルトは5に設定されています。
パネルにあるI/O Configボタンを押します。HPIB / 488の表示が出ます。もう一度I/O Configボタンを押します。ADDR Xの表示が出るので、ダイヤルを回して、10にしました。I/O Configボタンを押すと、CHANGE SAVEDの表示が出た後、初期メッセージOUTPUT OFFが表示されます。
●接続
DMMのGPIBコネクタにGPIBケーブルで電源E3631Aを数珠つなぎしていけばよいのですが、ここでは、GPIB-USB変換ケーブル(Agilentの82357B)をもう1本使ってPCのUSBポートにつなぎました。
Keysight Connection Expert 2020を起動します。
GPIBのバス1のアドレス10に見つけてきました。DMMはGPIBバス0にいました。
このソフトの中にあるInteractive IOをボタンを押して起動します。デフォルトで機器名問い合わせの*IDN?がCommand欄に記述されているので、Send & Readボタンを押しました。
製品のパネルではAgilentですが、さらに古い会社名が出てきました。
●動作確認のプログラム
3台のGPIB機器に対して測定器のIDの問い合わせをします。
import visa Keithley2000_1_Addr = "GPIB0::6" Keithley2000_2_Addr = "GPIB0::18" AgilentE3631A_Addr = "GPIB1::10" r = visa.ResourceManager() keithley2000_1 = r.open_resource(Keithley2000_1_Addr) keithley2000_2 = r.open_resource(Keithley2000_2_Addr) agilentE3631A = r.open_resource(AgilentE3631A_Addr) keithley2000_1.write('*IDN?') keithley2000_2.write('*IDN?') agilentE3631A.write('*IDN?') print(keithley2000_1.read()) print(keithley2000_2.read()) print(agilentE3631A.read())
実行結果です。
>py keithley40.py
KEITHLEY INSTRUMENTS INC.,MODEL 2000,0801917,A13 /A02
KEITHLEY INSTRUMENTS INC.,MODEL 2000,0638990,A06 /A02
HEWLETT-PACKARD,E3631A,0,2.1-5.0-1.0
●電流を測る
DMMではデフォルトの電圧測定をしていました。GPIBアドレス6のDMMで電流を測ります。電源は手動で約10Vを出力します。負荷に2kΩの抵抗をつなぎ、電流を測定します。
import visa from time import sleep Keithley2000_1_Addr = "GPIB0::6" r = visa.ResourceManager() keithley2000_1 = r.open_resource(Keithley2000_1_Addr) keithley2000_1.write("*RST;*CLS") keithley2000_1.write("SENSe:FUNCtion 'CURRent'; DC:RANG AUTO") #keithley2000_1.write("CONF:CURR; DC:RANG AUTO") while 1: data = keithley2000_1.query(":READ?") sleep(1) print("I: ", float(data))
*RST;*CLSは初期化です。*RSTは測定器をリセットします。*CLSはステータス・レジスタをクリアします。Keithley 2000では、イベント・レジスタをクリアします。
keithley2000_1.write("SENSe:FUNCtion 'CURRent'; DC:RANG AUTO")
と、
keithley2000_1.write("CONF:CURR; DC:RANG AUTO")
は、同じ電流設定です。DCの前にスペースが必要です。113 Undefined header(コマンドの綴りが不正であるか、無効なコマンドが入力された)というエラーが出ますが、電流モードに変更されました。
●抵抗の両端に電圧をかけ、電圧と電流を測る
電源を約10Vに設定し、+25V端子に2kΩの抵抗をつなぎます。その両端の電圧を1台のDMMで、もう1台のDMMで電流を測ります。
import visa from time import sleep Keithley2000_6_Addr = "GPIB0::6" Keithley2000_18_Addr = "GPIB0::18" r = visa.ResourceManager() keithley2000_6 = r.open_resource(Keithley2000_6_Addr) keithley2000_18 = r.open_resource(Keithley2000_18_Addr) keithley2000_6.write("*RST;*CLS") keithley2000_18.write("*RST;*CLS") keithley2000_6.write("CONF:CURR; DC:RANG AUTO") keithley2000_18.write("CONF:VOLT:DC:RANG 10") while 1: dataI = keithley2000_6.query(":READ?") dataE = keithley2000_18.query(":READ?") sleep(1) print("I: ", float(dataI), "E: ", float(dataE))
実行結果です。
>py keithley43.py
I: 0.00498658355 E: 9.95433082
I: 0.00498560093 E: 9.95438632
I: 0.00498557851 E: 9.95436033
●電源の設定
+25Vの出力を制御します。最初に10.06Vの電圧を設定(中古品を入手したので少し電圧がずれているので補正)、すぐにトリガをかけ、出力をONする設定をし、INITで実行に移します。その後、電圧を1Vずつ上げます。
import visa from time import sleep AgilentE3631A_Addr = "GPIB1::10" r = visa.ResourceManager() agilentE3631A = r.open_resource(AgilentE3631A_Addr) agilentE3631A.write("*RST;*CLS") agilentE3631A.write("INST:SEL P25V") agilentE3631A.write("VOLT:TRIG 10.06") agilentE3631A.write("TRIG:SOUR IMM") agilentE3631A.write("OUTP ON") agilentE3631A.write("INIT") print('10V') sleep(5) agilentE3631A.write("VOLT:TRIG 11.06") agilentE3631A.write("INIT") print('11V') sleep(5) agilentE3631A.write("VOLT:TRIG 12.06") agilentE3631A.write("INIT") print('12V')
ループで電圧を、0から15Vに1Vステップで上げるように変更しました。
import visa from time import sleep AgilentE3631A_Addr = "GPIB1::10" r = visa.ResourceManager() agilentE3631A = r.open_resource(AgilentE3631A_Addr) agilentE3631A.write("*RST;*CLS") agilentE3631A.write("INST:SEL P25V") agilentE3631A.write("TRIG:SOUR IMM") agilentE3631A.write("OUTP ON") for outVolt in range(16): agilentE3631A.write("VOLT:TRIG " + str(outVolt+0.06)) agilentE3631A.write("INIT") print(outVolt) sleep(3)
●抵抗の両端に電圧をかけ、電圧と電流を測ってグラフにする
forループの中では、電圧を指定し、INITコマンドを発行し、100ms待つという動作を繰り返しています。この流れがよいかどうかは不明ですが、正しく動いているように見えます。電圧の設定は90ms以下の内部の時間が必要なので100msを待たしています。
出力される抵抗値は、いずれの値もほぼ2kΩなので、測定が正しいことがわかります。
import visa from time import sleep import matplotlib.pyplot as plt Keithley2000_6_Addr = "GPIB0::6" Keithley2000_18_Addr = "GPIB0::18" AgilentE3631A_Addr = "GPIB1::10" r = visa.ResourceManager() agilentE3631A = r.open_resource(AgilentE3631A_Addr) keithley2000_6 = r.open_resource(Keithley2000_6_Addr) keithley2000_18 = r.open_resource(Keithley2000_18_Addr) dataI = [] dataE = [] agilentE3631A.write("*RST;*CLS") agilentE3631A.write("INST:SEL P25V") agilentE3631A.write("TRIG:SOUR IMM") agilentE3631A.write("OUTP ON") keithley2000_6.write("*RST;*CLS") keithley2000_18.write("*RST;*CLS") keithley2000_6.write("CONF:CURR; DC:RANG AUTO") keithley2000_18.write("CONF:VOLT:DC:RANG 10") sleep(1) for outVolt in range(1,16): agilentE3631A.write("VOLT:TRIG " + str(outVolt+0.06)) agilentE3631A.write("INIT") print(outVolt) sleep(0.1) dI = keithley2000_6.query(":READ?") dataI.append(dI) dE = keithley2000_18.query(":READ?") dataE.append(dE) print(" E: ", float(dE), "I: ", float(dI) , "R=", float(dE)/float(dI)) dataCurrent = [float(f)*1000 for f in dataI] dataVoltage = [float(f) for f in dataE] print(dataCurrent, dataVoltage) plt.plot(dataVoltage, dataCurrent, label="R 2k") plt.xlabel("Volt [V]") plt.ylabel("Current [mA]") plt.show()
実行結果です。抵抗は線形素子なので、まっすぐなグラフが得られます。