class Boonton7200(HasTraits): name = Unicode("Boonton7200") measurement_info = Dict() x_units = Dict({0: "SampleNumber", 1: "Time"}) y_units = Dict({0: "Capacitance"}) acquired_data = List(Dict) start_stop = Event running = Bool output_channels = Dict({0: "cap", 1: "bias"}) enabled_channels = List(Bool) timer = Instance(Timer) timer_dormant = Bool(False) update_interval = Float(0.5) start_time = Float # bias = Range(-10.0, 10.0, 0.0) bias = Float(0.0) current_capacitance = Float current_bias = Float sample_nr = Int(0) start_stop = Event button_label = Str("Start") bias_low_limit = Float(-10.0) # Instrument supports -100V to +100V bias_high_limit = Float(10.0) bias_table = List(TableEntry) bias_table_current_row = Int(0) bias_table_enable = Bool(False) stop_meas_after_last_row = Bool(False) _available_devices_map = Dict(Unicode, Unicode) selected_device = Str visa_resource = Instance(visa.ResourceManager, ()) instrument = Instance(visa.Resource) traits_view = View( Item( "selected_device", label="Device", editor=EnumEditor(name="_available_devices_map"), enabled_when="not running", ), Item("update_interval", enabled_when="not running"), Item("bias", editor=RangeEditor(is_float=True, low_name="bias_low_limit", high_name="bias_high_limit")), Group( Item("current_capacitance", enabled_when="False"), Item("current_bias", enabled_when="False"), Item("sample_nr", enabled_when="False"), label="Measurement", show_border=True, ), Group( Item("bias_table_enable"), Item("stop_meas_after_last_row"), Item( "bias_table", show_label=False, # label = 'right-click to edit', editor=table_editor, enabled_when="not running and bias_table_enable", ), show_border=True, ), Item("start_stop", label="Start/Stop Acqusistion", editor=ButtonEditor(label_value="button_label")), handler=ViewHandler, ) def instrument_init(self): if self.instrument is not None: self.instrument.write("BI" + str(self.bias)) def instrument_stop(self): if self.instrument is not None: pass def start(self): self.button_label = "Stop" self.sample_nr = 0 self.running = True self.instrument_init() self.start_time = time() self.bias_table_current_row = 0 self._row_changed(0) if self.timer is None: self.timer = Timer(self.update_interval * 1000, self._onTimer) else: self.timer.Start(self.update_interval * 1000) def stop(self): if self.timer is not None: self.timer.Stop() self.button_label = "Start" self.running = False self.timer_dormant = False self.instrument_stop() def _onTimer(self): # self.timer.Stop() self.timer_dormant = True d = dict() values = self.instrument.query_ascii_values("TM") self.current_capacitance = values[0] * 1e-12 self.current_bias = values[2] d[self.output_channels[0]] = ( dict({self.x_units[0]: self.sample_nr, self.x_units[1]: time() - self.start_time}), dict({self.y_units[0]: self.current_capacitance}), ) d[self.output_channels[1]] = ( dict({self.x_units[0]: self.sample_nr, self.x_units[1]: time() - self.start_time}), dict({self.y_units[0]: self.bias}), ) self.sample_nr += 1 # self.timer.Start(self.update_interval * 1000) self.timer_dormant = False self.acquired_data.append(d) if self.bias_table_enable: if self.bias_table_current_row < len(self.bias_table): row_time = time() - self.row_start_time self.bias_table[self.bias_table_current_row].remaining = int( self.bias_table[self.bias_table_current_row].time - row_time ) if self.bias_table[self.bias_table_current_row].remaining < 1: self.bias_table_current_row += 1 self._row_changed(self.bias_table[self.bias_table_current_row - 1].time - row_time) def _row_changed(self, remainder): self.row_start_time = time() + remainder # logging.getLogger(__name__).info('self.row_start_time: %f', self.row_start_time) if self.bias_table_current_row >= len(self.bias_table): if self.stop_meas_after_last_row: self.start_stop = True return self.bias = self.bias_table[self.bias_table_current_row].bias def _start_stop_fired(self): if self.instrument is None: return if self.timer is None: self.start() return if self.timer.isActive() or self.timer_dormant: self.stop() else: self.start() def _selected_device_changed(self, new): logger.info("New instrument %s", new) if self.instrument is not None: self.instrument.close() if new is not "": self.instrument = SerialUtil.open(new, self.visa_resource, command="ID") if self.instrument is None: GenericPopupMessage(message="Error opening " + new).edit_traits() self.instrument = None self.selected_device = "" def _selected_device_default(self): try: device = self._available_devices_map.items()[0][0] except IndexError: return "" self._selected_device_changed(device) return device def _enabled_channels_default(self): return [True, False] def _bias_table_default(self): return [TableEntry(time=10, bias=0.0, remaining=0), TableEntry(time=10, bias=0.5, remaining=0)] def __available_devices_map_default(self): try: instruments_info = self.visa_resource.list_resources_info() except visa.VisaIOError: return {} d = {} candidates = [n for n in instruments_info.values() if n.resource_name.upper().startswith("GPIB")] d.update(SerialUtil.probe(candidates, self.visa_resource, INSTRUMENT_IDENTIFIER, command="ID")) return d def _bias_changed(self, new): if self.instrument is not None: self.instrument.write("BI" + str(new))
class DummyIntervalInstrument(HasTraits): # implements(IInstrument) name = Unicode("DummyIntervalInstrument") model = Unicode("DummyInterval") # x_units = Dict # y_units = Dict x_units = Dict({0: "Voltage"}) y_units = Dict({0: "Current", 1: "Resistance"}) acquired_data = List(Dict) start_stop = Event running = Bool output_channels = Dict({0: "IV", 1: "CF"}) measurement_info = Dict() enabled_channels = List(Bool) timer = Instance(Timer) update_interval = Float(0.03) start_voltage = Float(0) stop_voltage = Float(5) step_voltage = Float(0.05) current_voltage = Float current_current = Float start_frequency = Float(20) stop_frequency = Float(1e6) step_frequency = Float(10000) current_frequency = Float current_capacitance = Float use_log_steps = Bool(True) iteration = Int(0) start_stop = Event button_label = Str("Start") sweep_name = Str bias = Float measurement_mode = Int traits_view = View( Item("measurement_mode", editor=EnumEditor(name="output_channels"), enabled_when="not running"), Group( Item("start_voltage"), Item("stop_voltage"), Item("step_voltage"), Item("current_voltage", enabled_when="False"), Item("current_current", enabled_when="False"), label="I/V", show_border=True, ), Group( Item("start_frequency"), Item("stop_frequency"), Item("step_frequency"), Item("use_log_steps"), Item("current_frequency", enabled_when="False"), Item("current_capacitance", enabled_when="False"), label="C/F", show_border=True, ), Item("update_interval"), Item("sweep_name"), Item("start_stop", label="Start/Stop Acqusistion", editor=ButtonEditor(label_value="button_label")), handler=DummyIntervalInstrumentHandler, ) def start(self): if self.timer is None: self.timer = Timer(self.update_interval * 1000, self._onTimer) else: self.timer.Start(self.update_interval * 1000) self.button_label = "Stop" self.current_voltage = self.start_voltage self.current_frequency = self.start_frequency self.iteration = 0 self.running = True self.bias = random.random_sample() - 0.5 self.measurement_info = { "name": self.sweep_name, "start_voltage": self.start_voltage, "start_frequency": self.start_frequency, "start_bias": self.bias, } if len(self.measurement_info["name"]) is 0: self.measurement_info.pop("name") def stop(self): if self.timer is not None: self.timer.Stop() self.button_label = "Start" self.running = False def _onTimer(self): d = dict() self.current_current = self.current_voltage ** 1.3 + self.bias self.current_capacitance = (self.current_frequency * (self.stop_frequency - self.current_frequency)) / 1e9 if self.measurement_mode is 0: d[self.output_channels[self.measurement_mode]] = ( dict({self.x_units[0]: self.current_voltage}), dict( { self.y_units[0]: self.current_current, self.y_units[1]: self.current_voltage / self.current_current, } ), ) elif self.measurement_mode is 1: d[self.output_channels[self.measurement_mode]] = ( dict({self.x_units[0]: self.current_frequency}), dict({self.y_units[0]: self.current_capacitance}), ) self.iteration += 1 self.current_voltage += self.step_voltage # if self.use_log_steps: self.current_frequency += self.step_frequency self.acquired_data.append(d) if self.current_voltage > self.stop_voltage: self.start_stop = True def _start_stop_fired(self): if self.timer is None: self.start() return if self.timer.isActive(): self.stop() else: self.start() def _enabled_channels_default(self): return [True, False] def _measurement_mode_changed(self, new): if new is 0: self.x_units = {0: "Voltage"} self.y_units = {0: "Current", 1: "Resistance"} self.enabled_channels = [True, False] elif new is 1: self.x_units = {0: "Frequency"} self.y_units = {0: "Capacitance"} self.enabled_channels = [False, True] def _measurement_mode_default(self): return 0 def get_nr_of_samples(self): if self.measurement_mode == 0: return (self.stop_frequency - self.start_frequency) / self.step_frequency elif self.measurement_mode == 1: return (self.stop_voltage - self.start_voltage) / self.step_voltage else: return 1