I know this is written in an absolutely hideous programming style, but here is a program to calibrate a Keysight / Agilent K34461a with a Fluke 5700a. Hard to believe I'm a computer engineer and did my masters thesis project at Sun Microsystems in Silicon Valley in the IT boom of 2000. I then got seduced by the dark side and started to do management consulting and banking.... So that my explain a bit...
Use completely at own risk at lethal voltages will be in use!!
Its written to use VXI11 direct to the 34461a over ethernet and via an Agilent E5810 to the 5700a.
---------------------
import vxi11
import time
SettleTime = 10
CalCode = "AT3446XA"
# Instruments
k34461a = vxi11.Instrument("192.168.0.67")
F5700a = vxi11.Instrument("192.168.0.61", "gpib0,4")
ErrorDetected = 0
# -------------- Helper Functions ------------------
def sleep_with_message(seconds, message="Waiting for settling..."):
print(f"{message} ({seconds} seconds)")
time.sleep(seconds)
def ask_float(prompt, default):
try:
user_input = input(prompt)
return float(user_input) * 60 if user_input else default
except ValueError:
return default
def perform_calibration(value, command, range):
try:
k34461a.write(f"CONF:{command} {range}")
time.sleep(2)
k34461a.write(f"CAL:VAL {value}")
k34461a.timeout = 180
Status = int(k34461a.ask("CAL?"))
if Status == 0:
print (" -- Success")
else:
print(" -- FAIL!!!")
ErrorDetected = 1
k34461a.write("CAL:STOR")
finally:
k34461a.timeout = 60
def configure_and_operate(instr, output_cmds):
for cmd in output_cmds:
instr.write(cmd)
instr.write("OPER")
StartTime = time.time()
while True:
ISR= int(instr.ask("ISR?"))
Elapsed = time.time() - StartTime
if ISR & 0x1000 or Elapsed > 5:
break
time.sleep(0.5)
def output_voltage(val, freq=None):
cmds = [f"OUT {val} V"]
if freq is not None:
cmds.append(f"OUT {freq} Hz")
configure_and_operate(F5700a, cmds)
def output_current(val, freq=None):
cmds = [f"OUT {val} A"]
if freq is not None:
cmds.append(f"OUT {freq} Hz")
configure_and_operate(F5700a, cmds)
def CheckTerminal (TestTerm): # FRONT is should be front REAR if should be rear
Term = k34461a.ask ("ROUT:TERM?")
if Term == "FRON" and TestTerm =="REAR":
input("WRONG TERMINALS SELECTED! SWITH TO REAR. Then press enter.")
if Term == "REAR" and TestTerm =="FRONT":
input("WRONG TERMINALS SELECTED! SWITH TO FRONT. Then press enter.")
# -------------- Calibration Functions ------------------
def short_cal():
print("Insert 4-wire short in FRONT and REAR of K34461A")
print("Set K34461A switch to FRONT")
sleep_with_message(ask_float("Wait time for thermal settling in minutes (default 5 min): ", 300))
CheckTerminal("FRONT")
print("FRONT ADC calibration" , end="")
k34461a.timeout = 400
Status = int(k34461a.ask("CAL:ADC?"))
if Status == 0:
print (" -- Success")
else:
print(" -- FAIL!!!")
ErrorDetected = 1
k34461a.write("CAL:STOR")
print("FRONT Zero calibration" , end="")
perform_calibration(0.0,"VOLT:DC" , 0.1)
k34461a.write("CAL:STOR")
input("Set K34461A switch to REAR and press Enter...")
print("REAR ADC calibration" , end="")
CheckTerminal("REAR")
Status = int(k34461a.ask("CAL:ADC?"))
if Status == 0:
print (" -- Success")
else:
print(" -- FAIL!!!")
ErrorDetected = ErrorDetected + 1
k34461a.write("CAL:STOR")
print("REAR Zero calibration" , end="")
perform_calibration(0.0,"VOLT:DC",0.1)
k34461a.write("CAL:STOR")
def dcv_cal():
inputs = [10, -10, 0.1, -0.1, 1, 100, 500]
ranges = [10, 10, 0.1, 0.1, 1, 100, 1000]
for val, rng in zip(inputs, ranges):
print(f"Calibrating {val} V in range {rng}", end="")
output_voltage(val)
time.sleep(SettleTime)
perform_calibration(val, "VOLT:DC", rng)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
def res_cal():
print("Resistance Calibration")
F5700a.write("EXTSENSE ON")
values = [100, 1000, 10000, 100000, 1000000, 10000000]
for res in values:
F5700a.write(f"OUT {res} OHM")
actual = float(F5700a.ask("ADJOUT?").split(",")[0])
print(f"Calibrating {res:,} Ω (actual: {actual} 4 Wire " , end="")
configure_and_operate(F5700a, [f"OUT {res} OHM"])
time.sleep(SettleTime)
perform_calibration(actual, f"FRES" , res)
# 100 MΩ
F5700a.write("EXTSENSE OFF")
configure_and_operate(F5700a, "OUT 100000000 OHM")
print(f"Calibrating 100M Ω (actual: {actual} 2 Wire " , end="")
actual = float(F5700a.ask("ADJOUT?").split(",")[0])
time.sleep(SettleTime)
perform_calibration(actual, "RES" ,100000000)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
def dci_cal():
print("DC Current Calibration")
F5700a.write("EXTSENSE OFF")
F5700a.write("CUR_POST AUX")
k34461a.write("CONF:CURR:DC 1")
for val in [0.0001, 0.001, 0.01, 0.1, 1]:
print(f"Calibrating {val} A", end="")
output_current(val)
time.sleep(SettleTime)
perform_calibration(val, f"CURR:DC" , val)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
def acv_zero():
print("AC Voltage Zero Calibration", end="")
F5700a.write("OUT 0 OHM")
configure_and_operate(F5700a, [])
time.sleep(SettleTime)
perform_calibration(0.0, "VOLT:AC", 10)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
def acv_cal():
print("AC Voltage Low Frequency Gain and Flatness Calibration")
F5700a.write("EXTSENSE OFF")
k34461a.write("CURR:AC:BAND 3")
k34461a.write("VOLT:AC:BAND 3")
freqs = [10, 40]
for freq in freqs:
print(f"Calibrating 7V RMS at {freq} Hz ", end="")
output_voltage(7, freq)
time.sleep(SettleTime)
perform_calibration(7, "VOLT:AC", 10)
ACVolt = [0.1, 1, 10, 50]
ACRange = [0.1, 1, 10, 100]
ACFreq = [5000, 10000, 20000, 35000, 50000, 75000, 100000, 200000, 300000, 390000, 400000, 220, 1000]
for i, val in enumerate(ACVolt):
for freq in ACFreq:
print(f"Calibrating {val} V RMS at {freq} Hz " , end="")
output_voltage(val, freq)
time.sleep(SettleTime/2)
perform_calibration(val, "VOLT:AC", ACRange)
print(f"Calibrating 500 V RMS at 1000Hz" , end="")
output_voltage(500, 1000)
time.sleep (SettleTime/2)
perform_calibration(500, "VOLT:AC", 1000)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
def aci_cal():
print("AC Current Calibration")
F5700a.write("EXTSENSE OFF")
F5700a.write("CUR_POST AUX")
k34461a.write("CURR:AC:BAND 3")
ACCurrent = [1, 0.1, 0.01]
ACFreq = [5000, 7500, 9700, 10000, 220, 1000]
for i, val in enumerate(ACCurrent):
for freq in ACFreq:
k34461a.write("CONF:CURR:AC 0.1")
print(f"Calibrating {val} A RMS at {freq} Hz " , end="")
output_current(val, freq)
time.sleep(SettleTime/2)
perform_calibration(val, "CURR:AC", val)
for val in [0.001, 0.0001]:
print(f"Calibrating {val} A RMS at 1000 Hz " , end="")
output_current(val, 1000)
time.sleep(SettleTime/2)
perform_calibration(val, "CURR:AC" , val)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
def dc10a_cal():
print("DC 10A Calibration at 2A" ,end ="")
k34461a.write("CONF:CURR:DC 10")
output_current(2,0)
time.sleep(SettleTime/2)
perform_calibration(2, "CURR:DC", 10)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
def ac10a_cal():
k34461a.write("CONF:CURR:AC 10")
print("AC 10A Calibration at 2A 1000Hz", end = "")
output_current(2, 1000)
time.sleep(SettleTime/2)
perform_calibration(2, "CURR:AC", 10)
k34461a.write("CAL:STOR")
F5700a.write("STBY")
# -------------- Main Program ------------------
def main():
print("Starting Keysight 34661a Calibrator")
print(F5700a.ask("*IDN?"))
print(k34461a.ask("*IDN?"))
F5700a.write("*CLS")
F5700a.write("STBY")
F5700a.timeout = 30
k34461a.write("*RST")
k34461a.write(f"CAL:SEC:STAT OFF,{CalCode}")
short_cal()
input("Connect 5-wire cable between 5700A and K34461A, use 3 A connector for current, then press Enter...")
sleep_with_message(ask_float("Wait time for thermal settling in minutes (default 2 min): ", 120))
CheckTerminal("FRONT")
acv_cal()
aci_cal()
acv_zero()
dcv_cal()
res_cal()
dci_cal()
input("Swap current cable to 10A connector and press Enter...")
ac10a_cal()
dc10a_cal()
F5700a.write("STBY")
if ErrorDetected == 0:
print("All calibration steps sucessful!")
else:
print("ONE OR MORE CALIBRATION STEPS FAILED")
k34461a.write("")
k34461a.write("CAL:STOR")
k34461a.write("CAL:SEC:STAT OFF," + CalCode)
print("Cal data saved, K34661a cal locked, calibration complete")
if __name__ == "__main__":
main()