"V1+": "A", "V1-": "E", "V2+": "C", "V2-": "G" } probe_current = 200e-6 time_values = np.array([]) Rxx = np.array([]) Rxy = np.array([]) tec_volts = np.array([]) error_sound = instruments.error_sound alert_sound = instruments.alert_sound sb = instruments.SwitchBox() dmm = instruments.K2000() pg = instruments.K2461() # tec = instruments.TEC1089SV() sb.connect(15) dmm.connect(16) pg.connect() # tec.connect(14) # tec.disable_control() # tec.set_target_temperature(0) # tec.enable_control() # while tec.get_temp_stability_state() is not "stable": # time.sleep(0.5) # print('Temp stable')
class DataCollector(QtCore.QObject): finished = QtCore.pyqtSignal() pos_data_ready = QtCore.pyqtSignal(np.ndarray, np.ndarray, np.ndarray) pos_scope_data_ready = QtCore.pyqtSignal(np.ndarray, np.ndarray) pos_tec_data_ready = QtCore.pyqtSignal(np.ndarray, np.ndarray) neg_data_ready = QtCore.pyqtSignal(np.ndarray, np.ndarray, np.ndarray) neg_scope_data_ready = QtCore.pyqtSignal(np.ndarray, np.ndarray) neg_tec_data_ready = QtCore.pyqtSignal(np.ndarray, np.ndarray) finished_res_measurement = QtCore.pyqtSignal(np.ndarray, np.ndarray) stable = QtCore.pyqtSignal() mutex = QtCore.QMutex() mutex.lock() is_stopped = False mutex.unlock() sb = instruments.SwitchBox() bb = instruments.BalanceBox() dmm = instruments.K2000() pg = instruments.K2461() scope = instruments.DS1104() tec = instruments.TEC1089SV() scope_enabled = False tec_enabled = False # default 8 arms # pulse1_assignments = {"I+": "B", "I-": "F"} # configuration for a pulse from B to F # pulse2_assignments = {"I+": "D", "I-": "H"} # configuration for a pulse from D to H # measure_assignments = {"I+": "A", "I-": "E", "V1+": "B", "V1-": "D", "V2+": "C", "V2-": "G"} # here V1 is Vxx # alt 1 8 arms # pulse1_assignments = {"I+": "A", "I-": "E"} # pulse2_assignments = {"I+": "C", "I-": "G"} # measure_assignments = {"I+": "H", "I-": "D", "V1+": "A", "V1-": "C", "V2+": "B", "V2-": "F"} # alt 2 8 arms # pulse1_assignments = {"I+": "D", "I-": "H"} # configuration for a pulse from B to F # pulse2_assignments = {"I+": "H", "I-": "D"} # configuration for a pulse from D to H # measure_assignments = {"I+": "A", "I-": "E", "V1+": "B", "V1-": "D", "V2+": "C", "V2-": "G"} # here V1 is Vxx # default 4 arms pulse1_assignments = { "I+": "AG", "I-": "CE" } # configuration for a pulse from B to F pulse2_assignments = { "I+": "AC", "I-": "GE" } # configuration for a pulse from D to H measure_assignments = { "I+": "A", "I-": "E", "V1+": "A", "V1-": "E", "V2+": "C", "V2-": "G" } # here V1 is Vxx resistance_assignments = { 'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 0, 'F': 0, 'G': 0, 'H': 0 } # 8 arm # two_wire_assignments = ({"I+": "A", "I-": "E"}, # {"I+": "B", "I-": "F"}, # {"I+": "C", "I-": "G"}, # {"I+": "D", "I-": "H"}, # ) # four_wire_assignments = ({"I+": "A", "I-": "E", "V1+": "B", "V1-": "D"}, # {"I+": "B", "I-": "F", "V1+": "C", "V1-": "E"}, # {"I+": "C", "I-": "G", "V1+": "D", "V1-": "F"}, # {"I+": "D", "I-": "H", "V1+": "E", "V1-": "G"}, # {"I+": "E", "I-": "A", "V1+": "F", "V1-": "H"}, # {"I+": "F", "I-": "B", "V1+": "G", "V1-": "A"}, # {"I+": "G", "I-": "C", "V1+": "H", "V1-": "B"}, # {"I+": "H", "I-": "D", "V1+": "A", "V1-": "C"}, # ) # 4 arm two_wire_assignments = ({"I+": "A", "I-": "E"}, {"I+": "C", "I-": "G"}) four_wire_assignments = ({ "I+": "A", "I-": "C", "V1+": "G", "V1-": "E" }, { "I+": "C", "I-": "E", "V1+": "A", "V1-": "G" }, { "I+": "E", "I-": "G", "V1+": "C", "V1-": "A" }, { "I+": "G", "I-": "A", "V1+": "E", "V1-": "C" }) # reference_resistance = 10.0154663186062 reference_resistance = 50.036 two_wire = 150 @QtCore.pyqtSlot(str, str, str, str, str, str, str, str, str, tuple) def start_measurement(self, mode, sb_port, bb_port, dmm_port, pulse_mag, pulse_width, meas_curr, meas_n, loop_n, checkboxes): bb_enabled, scope_enabled = checkboxes self.mutex.lock() self.is_stopped = False self.mutex.unlock() error_flag, pulse_volts, pulse_mag, pulse_width, meas_curr, meas_n, loop_n = self.handle_inputs( mode, sb_port, bb_port, dmm_port, pulse_mag, pulse_width, meas_curr, meas_n, loop_n, bb_enabled, scope_enabled) # If flag is true then something failed in parsing the inputs or connecting and the loop will not continue. if error_flag: return self.pulse_and_measure(pulse_volts, pulse_mag, pulse_width, meas_curr, meas_n, loop_n) self.sb.close() if bb_enabled: self.bb.close() if scope_enabled: self.scope.close() self.dmm.close() self.pg.close() # plt.pause()(1) self.finished.emit() @QtCore.pyqtSlot(str, str, str, str, str, str, str, str, str, bool) def resistance_measurement(self, mode, sb_port, bb_port, dmm_port, pulse_mag, pulse_width, meas_curr, meas_n, loop_n, bb_enabled): self.mutex.lock() self.is_stopped = False self.mutex.unlock() # Converts the strings in the gui boxes into appropriate types and then connects and sets up instruments. error_flag, pulse_volts, pulse_mag, pulse_width, meas_curr, meas_n, loop_n = self.handle_inputs( mode, sb_port, bb_port, dmm_port, pulse_mag, pulse_width, meas_curr, meas_n, loop_n, bb_enabled, False) # If something fails to connect, the UI doesn't continue if error_flag: return # reset the resistances to measure two wires properly if bb_enabled: self.bb.reset_resistances() two_wires = np.zeros(len(self.two_wire_assignments)) four_wires = np.zeros(len(self.four_wire_assignments)) for i in range(len(self.two_wire_assignments)): self.sb.switch(self.two_wire_assignments[i]) time.sleep(0.3) self.pg.enable_2_wire_probe(meas_curr) time.sleep(0.2) c, v = self.pg.read_one() two_wires[i] = v / c self.pg.disable_probe_current() print('Two Wires: ', two_wires) for i in range(len(self.four_wire_assignments)): self.sb.switch(self.four_wire_assignments[i]) time.sleep(0.3) self.pg.enable_4_wire_probe(meas_curr) time.sleep(0.2) c, v = self.pg.read_one() four_wires[i] = v / c self.pg.disable_probe_current() print('Four Wires: ', four_wires) if bb_enabled: self.bb.close() self.dmm.close() self.pg.close() self.sb.close() self.finished_res_measurement.emit(two_wires, four_wires) @QtCore.pyqtSlot(int, str, str) def start_TEC_temperature_control(self, system, port, target): # System: 0 -> none, 1-> TEC 2-> anything else, for future (HTS?) self.tec_enabled = True if system == 0: return try: port = int(port) target = float(target) except ValueError: print( 'Failed to convert strings to numbers. Check port and target temp boxes' ) return if system == 1: try: self.tec.connect(port) self.tec.set_target_temperature(target) self.tec.enable_control() except visa.VisaIOError: print( f'Could not connect to TEC on port {port} or could not set temperature to {target}' ) self.stable.emit() return a = self.tec.get_temp_stability_state() while a is not "stable": time.sleep(1) a = self.tec.get_temp_stability_state() self.stable.emit() # if system == 2: # try: # self.hts.connect(port) # self.hts.set_target_temperature(target) # self.hts.enable_control() # except visa.VisaIOError: # print('Could not connect to HTS on port ' + port + ' or could not set temperature to ' + target) # return @QtCore.pyqtSlot() def stop_TEC_temperature_control(self): self.tec_enabled = False try: self.tec.disable_control() except visa.VisaIOError: print('Could not send disable output command to TEC') self.tec.close() def pulse_and_measure(self, volts, pulse_mag, pulse_width, meas_curr, meas_n, loop_n): # see footnote on 6-110 in k2461 manual self.dmm.prepare_measure_one() start_time = time.time() for loop_count in range(loop_n): self.mutex.lock() if self.is_stopped: return self.mutex.unlock() print('Loop count:', loop_count + 1, 'Pulse: 1') self.sb.switch(self.pulse1_assignments) if self.scope_enabled: self.scope.single_trig() if volts: self.pg.prepare_pulsing_voltage(pulse_mag, pulse_width) else: self.pg.prepare_pulsing_current(pulse_mag, pulse_width) self.pg.set_ext_trig() time.sleep(200e-3) pulse_t = time.time() self.pg.send_pulse() time.sleep(200e-3) self.sb.switch(self.measure_assignments) self.pg.enable_4_wire_probe(meas_curr) time.sleep(500e-3) t = np.zeros(meas_n) vxx = np.zeros(meas_n) vxy = np.zeros(meas_n) curr = np.zeros(meas_n) if self.tec_enabled: tec_data = np.zeros(meas_n) for meas_count in range(meas_n): t[meas_count] = time.time() self.pg.trigger_fetch() self.dmm.trigger() vxx[meas_count], curr[meas_count] = self.pg.fetch_one() vxy[meas_count] = self.dmm.fetch_one() if self.tec_enabled: tec_data[meas_count] = self.tec.get_object_temperature() self.pg.disable_probe_current() self.pos_data_ready.emit(t - start_time, vxx / curr, vxy / curr) if self.scope_enabled: scope_data = self.scope.get_data(30001, 60000) time_step = float(self.scope.get_time_inc()) scope_time = np.array(range( 0, len(scope_data))) * time_step + pulse_t - start_time self.pos_scope_data_ready.emit( scope_time, scope_data / self.reference_resistance) if self.tec_enabled: self.pos_tec_data_ready.emit(t - start_time, tec_data) self.mutex.lock() if self.is_stopped: return self.mutex.unlock() print('Loop count:', loop_count + 1, 'Pulse: 2') self.sb.switch(self.pulse2_assignments) if self.scope_enabled: self.scope.single_trig() if volts: self.pg.prepare_pulsing_voltage(pulse_mag, pulse_width) else: self.pg.prepare_pulsing_current(pulse_mag, pulse_width) self.pg.set_ext_trig() time.sleep(200e-3) pulse_t = time.time() self.pg.send_pulse() time.sleep(200e-3) self.sb.switch(self.measure_assignments) self.pg.enable_4_wire_probe(meas_curr) time.sleep(500e-3) t = np.zeros(meas_n) vxx = np.zeros(meas_n) vxy = np.zeros(meas_n) curr = np.zeros(meas_n) if self.tec_enabled: tec_data = np.zeros(meas_n) for meas_count in range(meas_n): t[meas_count] = time.time() self.pg.trigger_fetch() self.dmm.trigger() vxx[meas_count], curr[meas_count] = self.pg.fetch_one() vxy[meas_count] = self.dmm.fetch_one() if self.tec_enabled: tec_data[meas_count] = self.tec.get_object_temperature() self.pg.disable_probe_current() self.neg_data_ready.emit(t - start_time, vxx / curr, vxy / curr) if self.scope_enabled: scope_data = self.scope.get_data(30001, 60000) time_step = float(self.scope.get_time_inc()) scope_time = np.array(range( 0, len(scope_data))) * time_step + pulse_t - start_time self.neg_scope_data_ready.emit( scope_time, scope_data / self.reference_resistance) if self.tec_enabled: self.neg_tec_data_ready.emit(t - start_time, tec_data) def handle_inputs(self, mode, sb_port, bb_port, dmm_port, pulse_mag, pulse_width, meas_curr, meas_n, loop_n, bb_enabled, scope_enabled): connection_flag = False conversion_flag = False if mode == 'Pulse Current': pulse_volts = False elif mode == 'Pulse Voltage': pulse_volts = True else: print('Pulse mode selection error?') pulse_volts = False conversion_flag = True try: sb_port = int(sb_port) except ValueError: error_sound() print('Invalid switchbox port please enter integer value.') conversion_flag = True if bb_enabled: try: bb_port = int(bb_port) except ValueError: error_sound() print('Invalid balance box port please enter integer value.') conversion_flag = True self.bb.enable_all() self.bb.set_resistances(self.resistance_assignments) try: dmm_port = int(dmm_port) except ValueError: error_sound() print('Invalid keithley port please enter integer value.') conversion_flag = True try: if pulse_volts: pulse_mag = float(pulse_mag) else: pulse_mag = float(pulse_mag) * 1e-3 except ValueError: error_sound() print('Invalid pulse magnitude. Please enter a valid float') conversion_flag = True try: pulse_width = float(pulse_width) * 1e-3 except ValueError: error_sound() print('Invalid pulse width. Please enter a valid float') conversion_flag = True try: meas_curr = float(meas_curr) * 1e-6 except ValueError: error_sound() print('Invalid probe current. Please enter a valid float') conversion_flag = True try: meas_n = int(meas_n) except ValueError: error_sound() print( 'Invalid measurement count per loop. Please enter an integer value' ) conversion_flag = True try: loop_n = int(loop_n) except ValueError: error_sound() print('Invalid number of loops. Please enter an integer value') conversion_flag = True try: self.sb.connect(sb_port) except serial.SerialException: error_sound() print(f"Could not connect to switch box on port COM{sb_port}.") connection_flag = True if bb_enabled: try: self.bb.connect(bb_port) except serial.SerialException: error_sound() print( f"Could not connect to balance box on port COM{bb_port}.") connection_flag = True if scope_enabled & pulse_volts: try: self.scope.connect() self.scope.prepare_for_pulse(pulse_mag, self.reference_resistance, self.two_wire, pulse_width) self.scope.set_trig_chan() # self.scope.single_trig() self.scope_enabled = True time.sleep(12) except visa.VisaIOError: error_sound() print("Could not connect to RIGOL DS1104Z.") connection_flag = True else: self.scope_enabled = False try: self.dmm.connect(dmm_port) except visa.VisaIOError: error_sound() print(f"Could not connect to Keithley2000 on port COM{dmm_port}.") connection_flag = True try: self.pg.connect() except visa.VisaIOError: error_sound() print("Could not connect to keithley 2461.") connection_flag = True return connection_flag or conversion_flag, pulse_volts, pulse_mag, pulse_width, meas_curr, meas_n, loop_n
import numpy as np import time # import tkinter as tk # import tkinter.messagebox as mb # from tkinter import filedialog as dialog import matplotlib import instruments switchbox = instruments.SwitchBox() #dual arm pulsing pulse1_assignments = {"I+": "BD", "I-": "FH"} # single arm pulsing pulse2_assignments = {"I+": "D", "I-": "H"} # measuring with two different kiethley connectors to one pin measure_assignments = { "I+": "A", "I-": "E", "V1+": "A", "V1-": "E", "V2+": "C", "V2-": "G" } switchbox.connect(4) # switch between example configs every second. Listen for clicking. switchbox.switch(pulse1_assignments) time.sleep(1) switchbox.switch(measure_assignments) time.sleep(1) switchbox.switch(pulse2_assignments)
# pulse_current = 10e-3 # set current pulse_voltage = 30 # set voltage pulse_width = 1e-3 # set pulse duration measure_current = 5e-4 # measurement current measure_number = 200 # number of measurements to store in buffer when calling measure_n and read_buffer. 375 is ~1min num_loops = 2 measure_delay = measure_number * 0.15 # Not strictly necessary. pos_time = np.array([]) neg_time = np.array([]) pos_rxx = np.array([]) neg_rxx = np.array([]) pos_rxy = np.array([]) neg_rxy = np.array([]) switch_box = instruments.SwitchBox() # make a sb object pulse_generator = instruments.K2461() # make a k2461 object keithley = instruments.K2000() # make a k2000 object balance_box = instruments.BalanceBox() start_time = time.time() # use this for the graphing only # actually connect to the instruments pulse_generator.connect() switch_box.connect(4) keithley.connect(3) balance_box.connect(5) balance_box.enable_all() balance_box.set_resistances(resistance_assignments) plt.figure(1) plt.xlabel('Time (s)')