def start(deviceName): try: Ube_step = (Ube_max - Ube_min) / NUM_U_BE_STEPS scpi("*SAV 10") scpi("MEM:STAT:FREEze ON") scpi("INST:COUP:TRAC CGND") scpi("INST ch1") scpi("OUTP 0") scpi("CURR " + str(Ib)) scpi("VOLT 0") scpi("OUTP:DPR 1") scpi("SENS:CURR:RANG 50mA") scpi("INST ch2") scpi("OUTP 0") scpi("VOLT " + str(Uce)) scpi("CURR " + str(Ic_max)) scpi("SENS:CURR:RANG DEFault") scpi('SENS:DLOG:TRAC:COMMent "NPN Transfer curve for ' + deviceName + '"') scpi("SENS:DLOG:TRAC:X:UNIT VOLT") scpi("SENS:DLOG:TRAC:X:RANG:MIN " + str(Ube_min + Ube_step)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(Ube_max)) scpi("SENS:DLOG:TRAC:X:STEP " + str(Ube_step)) scpi("SENS:DLOG:TRAC:X:SCALE LIN") scpi('SENS:DLOG:TRAC:X:LABel "Ube"') scpi("SENS:DLOG:TRAC:Y1:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y1:RANG:MIN 0") scpi("SENS:DLOG:TRAC:Y1:RANG:MAX " + str(Ic_max * 1.1)) scpi('SENS:DLOG:TRAC:Y1:LABel "Ic"') scpi('INIT:DLOG:TRACE "/Recordings/' + deviceName + '-transfer.dlog"') scpi("INST ch1") scpi("OUTP 1") scpi("INST ch2") scpi("OUTP 1") scpi("DISP:WINDOW:DLOG") t = ticks_ms() for ube_step_counter in range(NUM_U_BE_STEPS): Ube = Ube_min + (ube_step_counter + 1) * Ube_step setU(1, Ube) t = ticks_add(t, TIME_STEP_MS) sleep_ms(ticks_diff(t, ticks_ms())) dlogTraceData(getI(2)) finally: scpi("ABOR:DLOG") scpi("*RCL 10") scpi("MEM:STAT:FREEze OFF")
def loop(self): time_step = 1 #seconds low_count = 0 self.display_charge_pane() self.startDatalogging() uMon = getU(channel) iMon = getI(channel) total_amp_seconds = 0 self.total_amp_hour = 0 self.total_seconds = 0 try: self.set_charge_param() action = '' while True: if action == 'stop': break elif action == 'view_datalog': scpi('DISP:WINDOW:DLOG') elif action == 'close' or action == 0: # TODO this won't actually exit... break; uMon = getU(channel) iMon = getI(channel) amp_seconds = iMon * time_step total_amp_seconds += amp_seconds self.total_amp_hour = total_amp_seconds/3600 dlogTraceData(uMon, iMon, self.total_amp_hour) scpi('DISP:DIAL:DATA "Vmeas", FLOAT, VOLT, ' + str(uMon)) scpi('DISP:DIAL:DATA "Imeas", FLOAT, AMPER, ' + str(iMon)) scpi('DISP:DIAL:DATA "elapsed_amp_hour", FLOAT, AMPER, ' + str(self.total_amp_hour)) scpi('DISP:DIAL:DATA "total_seconds", FLOAT, SECOnd, ' + str(self.total_seconds)) if iMon < termination_current: low_count += 1 if low_count >=3: break else: low_count = 0 action = scpi('DISP:DIALog:ACTIon? ' + str(time_step)) self.total_seconds += time_step finally: scpi('OUTP 0') scpi('ABOR:DLOG') self.done_loop()
def start_MOSFET(cgnd): global deviceName, Uds_max, Id_max TIME_ON_MS = 15 TIME_OFF_MS = 6 # Ch1 G-S Ugs = [3.5, 4, 4.5, 5, 5.5, 6] Ig = 5.0 # Ch2 D-S Uds_min = 0.1 NUM_U_DS_STEPS = 400 SIMULATOR = 0 if SIMULATOR: TIME_ON_MS = 10 TIME_OFF_MS = 0 Ugs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Ig = 5.0 #Uds_step = Uds_max / NUM_U_DS_STEPS Uds_logMin = math.log(Uds_min) / math.log(10) Uds_logMax = math.log(Uds_max) / math.log(10) Uds_step = (Uds_logMax - Uds_logMin) / (NUM_U_DS_STEPS - 1) if cgnd: scpi("INST:COUP:TRAC CGND") scpi("INST ch1") scpi("OUTP 0") scpi("VOLT 0") scpi("CURR " + str(Ig)) scpi("OUTP:DPR 1") scpi("INST ch2") scpi("OUTP 0") scpi("VOLT 0") scpi("CURR " + str(Id_max)) scpi('SENS:DLOG:TRAC:COMMent "Device name = ' + deviceName + '; Uds,max = ' + str(Uds_max) + '; Id,max = ' + str(Id_max) + '"') scpi("SENS:DLOG:TRAC:X:UNIT VOLT") scpi("SENS:DLOG:TRAC:X:RANG:MIN " + str(Uds_logMin)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(Uds_logMax)) scpi("SENS:DLOG:TRAC:X:STEP " + str(Uds_step)) scpi("SENS:DLOG:TRAC:X:SCALE LOG") scpi('SENS:DLOG:TRAC:X:LABel "Uds"') num_ugs_steps = len(Ugs) scpi("SENS:DLOG:TRAC:Y:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y:RANG:MIN 0") scpi("SENS:DLOG:TRAC:Y:RANG:MAX " + str(Id_max * 1.1)) scpi('SENS:DLOG:TRAC:Y:LABel "Id"') scpi('SENS:DLOG:TRAC:Y:SCALe LOG') for ugs_step_counter in range(num_ugs_steps): scpi('SENS:DLOG:TRAC:Y' + str(ugs_step_counter + 1) + ':LABel "Ugs=' + str(Ugs[ugs_step_counter]) + 'V"') scpi('INIT:DLOG:TRACE "/Recordings/' + deviceName + '.dlog"') scpi("INST ch1") scpi("OUTP 1") scpi("INST ch2") scpi("OUTP 1") if SIMULATOR: scpi("SIMU:LOAD:STATE ON,CH2") scpi("DISP:WINDOW:DLOG") iMonValues = [0.0] * num_ugs_steps t = ticks_ms() for uds_step_counter in range(NUM_U_DS_STEPS): Uds = math.pow(10, Uds_logMin + uds_step_counter * Uds_step) setU(2, Uds) for ugs_step_counter in range(num_ugs_steps): if SIMULATOR: if Uds < 10: scpi("SIMU:LOAD " + str(20 / Ugs[ugs_step_counter]) + ",CH2") else: scpi("SIMU:LOAD " + str((20 / 10) * Uds / Ugs[ugs_step_counter]) + ",CH2") setU(1, Ugs[ugs_step_counter]) t = ticks_add(t, TIME_ON_MS) sleep_ms(ticks_diff(t, ticks_ms())) iMonValues[ugs_step_counter] = getI(2) if TIME_OFF_MS > 0: setU(1, 0) t = ticks_add(t, TIME_OFF_MS) sleep_ms(ticks_diff(t, ticks_ms())) dlogTraceData(iMonValues)
def start_BJT(cgnd): global deviceName, Uce_max, Ic_max TIME_ON_MS = 30 TIME_OFF_MS = 0 # Ch1 B-E Ib = [50e-6, 100e-6, 150e-6, 200e-6, 250e-6, 300e-6, 350e-6, 400e-6] Ube = 10.0 # Ch2 C-E Uce_min = 0.1 NUM_U_DS_STEPS = 400 Uce_step = Uce_max / NUM_U_DS_STEPS if cgnd: scpi("INST:COUP:TRAC CGND") scpi("INST ch1") scpi("OUTP 0") scpi("VOLT " + str(Ube)) scpi("CURR 0") scpi("OUTP:DPR 1") scpi("SENS:CURR:RANG 50mA") scpi("INST ch2") scpi("OUTP 0") scpi("VOLT 0") scpi("CURR " + str(Ic_max)) scpi("SENS:CURR:RANG DEFault") scpi('SENS:DLOG:TRAC:COMMent "Device name = ' + deviceName + '; Uce,max = ' + str(Uce_max) + '; Ic,max = ' + str(Ic_max) + '"') scpi("SENS:DLOG:TRAC:X:UNIT VOLT") scpi("SENS:DLOG:TRAC:X:RANG:MIN " + str(Uce_min)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(Uce_max)) scpi("SENS:DLOG:TRAC:X:STEP " + str(Uce_step)) scpi("SENS:DLOG:TRAC:X:SCALE LIN") scpi('SENS:DLOG:TRAC:X:LABel "Uce"') num_ib_steps = len(Ib) scpi("SENS:DLOG:TRAC:Y:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y:RANG:MIN 0") scpi("SENS:DLOG:TRAC:Y:RANG:MAX " + str(Ic_max * 1.1)) scpi('SENS:DLOG:TRAC:Y:LABel "Ic"') for ib_step_counter in range(num_ib_steps): scpi('SENS:DLOG:TRAC:Y' + str(ib_step_counter + 1) + ':LABel "Ib=' + str(Ib[ib_step_counter] * 1E6) + 'uA"') scpi('INIT:DLOG:TRACE "/Recordings/' + deviceName + '.dlog"') scpi("INST ch1") scpi("OUTP 1") scpi("INST ch2") scpi("OUTP 1") scpi("DISP:WINDOW:DLOG") iMonValues = [0.0] * num_ib_steps t = ticks_ms() for uce_step_counter in range(NUM_U_DS_STEPS): Uce = Uce_min + uce_step_counter * Uce_step setU(2, Uce) for ib_step_counter in range(num_ib_steps): setI(1, Ib[ib_step_counter]) t = ticks_add(t, TIME_ON_MS) sleep_ms(ticks_diff(t, ticks_ms())) iMonValues[ib_step_counter] = getI(2) if TIME_OFF_MS > 0: setI(1, 0) t = ticks_add(t, TIME_OFF_MS) sleep_ms(ticks_diff(t, ticks_ms())) dlogTraceData(iMonValues)
def start(): if not can_start(): error("Enter diode name") return scpi("DISP:DIALog:CLOSe") uStep = U_step uBreakdown = None try: scpi("*SAV 10") scpi("MEM:STAT:FREEze ON") ch1Model = scpi("SYSTem:CHANnel:MODel? ch1") ch2Model = scpi("SYSTem:CHANnel:MODel? ch2") if ch1Model.startswith("DCP405") and ch2Model.startswith("DCP405"): scpi("INST:COUP:TRAC SER") else: scpi("INST:COUP:TRAC NONE") scpi("INST ch1") uMax = float(scpi("VOLT? MAX")) scpi("OUTP 0") scpi("SENS:CURR:RANG MIN") scpi("VOLT 0") scpi("CURR " + str(I_SET)) scpi('SENS:DLOG:TRAC:COMMent "Diode name = ' + diode_name + '; U step = ' + str(U_step) + '"') scpi("SENS:DLOG:TRAC:X:UNIT VOLT") scpi("SENS:DLOG:TRAC:X:STEP " + str(U_step)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(uMax)) scpi('SENS:DLOG:TRAC:X:LABel "Uset"') scpi("SENS:DLOG:TRAC:Y1:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y1:RANG:MAX " + str(I_SET)) scpi('SENS:DLOG:TRAC:Y1:LABel "Imon"') scpi('INIT:DLOG:TRACE "/Recordings/' + diode_name + '.dlog"') scpi("OUTP 1") scpi("DISP:WINDOW:DLOG") ch = 1 t = ticks_ms() i = 0 while True: uSet = i * U_step if uSet > uMax: break setU(ch, uSet) #scpi("VOLT " + str(uSet)) t = ticks_add(t, TIME_STEP_MS) sleep_ms(ticks_diff(t, ticks_ms())) iMon = getI(ch) #iMon = scpi("MEAS:CURR?") dlogTraceData(iMon) #scpi("DLOG:TRACE:DATA " + scpi("MEAS:CURR?")) mode = getOutputMode(ch) #mode = scpi("OUTP:MODE?") #print(uSet, iMon, mode) #if mode == "CC": # break if iMon >= I_SET: uBreakdown = uSet break i = i + 1 finally: scpi("ABOR:DLOG") scpi("*RCL 10") scpi("MEM:STAT:FREEze OFF") if uBreakdown != None: scpi('DISP:INPUT? "Breakdown voltage is ' + str(round(uBreakdown, 2)) + 'V", MENU, BUTTON, "Close"') else: scpi( 'DISP:INPUT? "Breakdown voltage not found", MENU, BUTTON, "Close"')
while True: uSet = i * uStep if uSet > uMax: break setU(ch, uSet) #scpi("VOLT " + str(uSet)) t = ticks_add(t, TIME_STEP_MS) sleep_ms(ticks_diff(t, ticks_ms())) iMon = getI(ch) #iMon = scpi("MEAS:CURR?") dlogTraceData(iMon) #scpi("DLOG:TRACE:DATA " + scpi("MEAS:CURR?")) mode = getOutputMode(ch) #mode = scpi("OUTP:MODE?") print(uSet, iMon, mode) #if mode == "CC": # break if iMon >= I_SET: uBreakdown = uSet break i = i + 1 finally:
def start_reform(): global max_cap_volt, charge_current, reform_time, have_data, channel try: scpi("SENS:CURR:RANG BEST") scpi("VOLT 0") scpi("CURR 0") scpi("CURR " + str(charge_current)) # Define datalogging scpi("SENS:DLOG:CLE") scpi('SENS:DLOG:TRAC:REM " Icharge = ' + str(charge_current) + '"') scpi("SENS:DLOG:TRAC:X:UNIT SECOND") scpi("SENS:DLOG:TRAC:X:STEP " + str(TIME_STEP)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(reform_time)) scpi('SENS:DLOG:TRAC:X:LABel "Time"') scpi("SENS:DLOG:TRAC:Y1:UNIT VOLT") scpi("SENS:DLOG:TRAC:Y1:RANG:MAX " + str(cap_max_volt * 1.1)) scpi("SENS:DLOG:TRAC:Y1:RANG:MIN 0") scpi('SENS:DLOG:TRAC:Y1:LABel "Vmon"') scpi("SENS:DLOG:TRAC:Y2:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y2:RANG:MAX " + str(charge_current * 2)) scpi("SENS:DLOG:TRAC:Y2:RANG:MIN 0") scpi('SENS:DLOG:TRAC:Y2:LABel "Imon"') scpi('INIT:DLOG:TRACE "/Recordings/ReformCap.dlog"') scpi("OUTP 1") have_data = True starttime = ticks_ms() t = starttime tdiff = 0.0 # Allocate outside loop for speed. action = "" # This is the measurement loop. ############################### while True: scpi('SYST:DIG:OUTP:DATA 4,1') # For timing analysis # Time critical stuff first ########################### # Measure as soon and fast as possible to hit it as close as possible to the set time (after delay) uMon = getU(channel) iMon = getI(channel) # Remember timestamp of the beginning of this iteration nowtime = ticks_ms() # Set (new) value uSet = STEP1 * cap_max_volt if nowtime > (starttime + 0.6666 * reform_time * 1000): uSet = STEP3 * cap_max_volt elif nowtime > (starttime + 0.3333 * reform_time * 1000): uSet = STEP2 * cap_max_volt setU(channel, uSet) # Not time critical ################### try: dlogTraceData(uMon, iMon) except: break # Done with loop? if nowtime > (starttime + reform_time * 1000): scpi('SYST:DIG:OUTP:DATA 4,0') break # Finally do the slow GUI stuff. ################################ # Process the action read during the delay if action == "view_dlog": scpi("DISP:WINDOW:DLOG") if action == "stop_reform": break # Update progress bar. scpi("DISP:DIAL:DATA \"reform_progress\", INT, " + str(int((nowtime - starttime) / (reform_time * 10)))) # Update V and I data scpi("DISP:DIAL:DATA \"Vmon\", FLOAT, VOLT, " + str(uMon)) scpi("DISP:DIAL:DATA \"Imon\", FLOAT, AMPER, " + str(iMon)) # Loop delay ############ # Set the next time we want the loop to execute t = ticks_add(t, int(TIME_STEP * 1000)) scpi('SYST:DIG:OUTP:DATA 4,0') # Everything after this line is time sensitive, it is nog compensated in the timing calculation # It will cause a drift in sampling time. # Calculate how long until next interval, wait for this time in dialog wait. #sleep_ms(ticks_diff(t,ticks_ms())) action = scpi("DISP:DIALOG:ACTION? " + str(max(1, ticks_diff(t, ticks_ms()))) + 'ms') # We don't process the action here but in the next iteration to keep timing # of measurements as jitter free as possible finally: scpi("OUTP 0") # Stop recording. scpi('ABOR:DLOG') discharge_cap()
def start(deviceName, Uce_max, Ic_max): try: Uce_step = Uce_max / NUM_U_DS_STEPS scpi("*SAV 10") scpi("MEM:STAT:FREEze ON") scpi("INST:COUP:TRAC CGND") scpi("INST ch1") scpi("OUTP 0") scpi("VOLT " + str(Ube)) scpi("CURR 0") scpi("OUTP:DPR 1") scpi("SENS:CURR:RANG 50mA") scpi("INST ch2") scpi("OUTP 0") scpi("VOLT 0") scpi("CURR " + str(Ic_max)) scpi("SENS:CURR:RANG DEFault") scpi('SENS:DLOG:TRAC:COMMent "Device name = ' + deviceName + '; Uce,max = ' + str(Uce_max) + '; Ic,max = ' + str(Ic_max) + '"') scpi("SENS:DLOG:TRAC:X:UNIT VOLT") scpi("SENS:DLOG:TRAC:X:RANG:MIN " + str(Uce_min)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(Uce_max)) scpi("SENS:DLOG:TRAC:X:STEP " + str(Uce_step)) scpi("SENS:DLOG:TRAC:X:SCALE LIN") scpi('SENS:DLOG:TRAC:X:LABel "Uce"') num_ib_steps = len(Ib) scpi("SENS:DLOG:TRAC:Y:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y:RANG:MIN 0") scpi("SENS:DLOG:TRAC:Y:RANG:MAX " + str(Ic_max * 1.1)) scpi('SENS:DLOG:TRAC:Y:LABel "Ic"') for ib_step_counter in range(num_ib_steps): scpi('SENS:DLOG:TRAC:Y' + str(ib_step_counter+1) + ':LABel "Ib=' + str(Ib[ib_step_counter] * 1E6) + 'uA"') scpi('INIT:DLOG:TRACE "/Recordings/' + deviceName + '.dlog"') scpi("INST ch1") scpi("OUTP 1") scpi("INST ch2") scpi("OUTP 1") scpi("DISP:WINDOW:DLOG") iMonValues = [0.0] * num_ib_steps t = ticks_ms() for uce_step_counter in range(NUM_U_DS_STEPS): Uce = Uce_min + uce_step_counter * Uce_step setU(2, Uce) for ib_step_counter in range(num_ib_steps): setI(1, Ib[ib_step_counter]) t = ticks_add(t, TIME_ON_MS) sleep_ms(ticks_diff(t, ticks_ms())) iMonValues[ib_step_counter] = getI(2) if TIME_OFF_MS > 0: setI(1, 0) t = ticks_add(t, TIME_OFF_MS) sleep_ms(ticks_diff(t, ticks_ms())) dlogTraceData(iMonValues) finally: scpi("ABOR:DLOG") scpi("*RCL 10") scpi("MEM:STAT:FREEze OFF")
def start(deviceName, Uds_max, Id_max): try: #Uds_step = Uds_max / NUM_U_DS_STEPS Uds_logMin = math.log(Uds_min) / math.log(10) Uds_logMax = math.log(Uds_max) / math.log(10) Uds_step = (Uds_logMax - Uds_logMin) / (NUM_U_DS_STEPS - 1) scpi("*SAV 10") scpi("MEM:STAT:FREEze ON") scpi("INST:COUP:TRAC CGND") scpi("INST ch1") scpi("OUTP 0") scpi("VOLT 0") scpi("CURR " + str(Ig)) scpi("OUTP:DPR 1") scpi("INST ch2") scpi("OUTP 0") scpi("VOLT 0") scpi("CURR " + str(Id_max)) scpi('SENS:DLOG:TRAC:COMMent "Device name = ' + deviceName + '; Uds,max = ' + str(Uds_max) + '; Id,max = ' + str(Id_max) + '"') scpi("SENS:DLOG:TRAC:X:UNIT VOLT") scpi("SENS:DLOG:TRAC:X:RANG:MIN " + str(Uds_logMin)) scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(Uds_logMax)) scpi("SENS:DLOG:TRAC:X:STEP " + str(Uds_step)) scpi("SENS:DLOG:TRAC:X:SCALE LOG") scpi('SENS:DLOG:TRAC:X:LABel "Uds"') num_ugs_steps = len(Ugs) scpi("SENS:DLOG:TRAC:Y:UNIT AMPER") scpi("SENS:DLOG:TRAC:Y:RANG:MIN 0") scpi("SENS:DLOG:TRAC:Y:RANG:MAX " + str(Id_max * 1.1)) scpi('SENS:DLOG:TRAC:Y:LABel "Id"') scpi('SENS:DLOG:TRAC:Y:SCALe LOG') for ugs_step_counter in range(num_ugs_steps): scpi('SENS:DLOG:TRAC:Y' + str(ugs_step_counter + 1) + ':LABel "Ugs=' + str(Ugs[ugs_step_counter]) + 'V"') scpi('INIT:DLOG:TRACE "/Recordings/' + deviceName + '.dlog"') scpi("INST ch1") scpi("OUTP 1") scpi("INST ch2") scpi("OUTP 1") if SIMULATOR: scpi("SIMU:LOAD:STATE ON,CH2") scpi("DISP:WINDOW:DLOG") iMonValues = [0.0] * num_ugs_steps t = ticks_ms() for uds_step_counter in range(NUM_U_DS_STEPS): Uds = math.pow(10, Uds_logMin + uds_step_counter * Uds_step) setU(2, Uds) for ugs_step_counter in range(num_ugs_steps): if SIMULATOR: if Uds < 10: scpi("SIMU:LOAD " + str(20 / Ugs[ugs_step_counter]) + ",CH2") else: scpi("SIMU:LOAD " + str((20 / 10) * Uds / Ugs[ugs_step_counter]) + ",CH2") setU(1, Ugs[ugs_step_counter]) t = ticks_add(t, TIME_ON_MS) sleep_ms(ticks_diff(t, ticks_ms())) iMonValues[ugs_step_counter] = getI(2) if TIME_OFF_MS > 0: setU(1, 0) t = ticks_add(t, TIME_OFF_MS) sleep_ms(ticks_diff(t, ticks_ms())) dlogTraceData(iMonValues) finally: scpi("ABOR:DLOG") scpi("*RCL 10") scpi("MEM:STAT:FREEze OFF")