def __init__(self, parent, name, slot, default_switch_pos=DacBase._DEFAULT_SWITCH_POS): """ Initialize the slot Arguments: parent (Decadac): Decadac object this slot belongs to name (str): name of the slot slot (int): number of the slot switch (int): switch position of all channels of this slot mode (int): slot mode (MODE_OFF, MODE_FINE, MODE_COARSE) Attributes: name (str): name of the slot channels (ChannelList): list of channels in this slot mode (int): slot mode (MODE_OFF, MODE_FINE, MODE_COARSE) """ InstrumentChannel.__init__(self, parent, name) DacSlot._SLOT_VAL.validate(slot) self.number = slot channels = ChannelList(self, "Slot_Chans", DacChannel) for channel in range(4): channels.append(DacChannel(self, "Chan{}".format(channel), channel, default_switch_pos=default_switch_pos)) self.add_submodule("channels", channels) self.add_parameter("mode", get_cmd=self._get_mode, set_cmd=self._set_mode, vals=self._MODE_VAL, label="Slot Mode")
def __init__(self, name, address, model_no, **kwargs): super().__init__(name, address, terminator="\n", **kwargs) self.model_no = model_no self.add_parameter('state', label='Output enabled', set_cmd='OUTPut:GENeral {}', get_cmd='OUTPut:GENeral?', val_mapping={ 'ON': 1, 'OFF': 0 }, vals=vals.Enum('ON', 'OFF')) # number of channels can be calculated from model number num_channels = (self.model_no % 100) // 10 # channel-specific parameters channels = ChannelList(self, "SupplyChannel", RohdeSchwarzHMPChannel, snapshotable=False) for ch_num in range(1, num_channels + 1): ch_name = "ch{}".format(ch_num) channel = RohdeSchwarzHMPChannel(self, ch_name, ch_num) channels.append(channel) self.add_submodule(ch_name, channel) channels.lock() self.add_submodule("channels", channels) self.connect_message()
def __init__(self, name: str, resource: str, name_mapping: Optional[Dict[str, str]] = None, reset_device: bool = False, niswitch_kw: Optional[Dict] = None, **kwargs): super().__init__(name=name, **kwargs) if name_mapping is None: name_mapping = {} if niswitch_kw is None: niswitch_kw = {} self.session = Session(resource, reset_device=reset_device, **niswitch_kw) new_channels = ChannelList(self, "all_channels", SwitchChannel) for i in range(self.session.channel_count): raw_name = self.session.get_channel_name(i + 1) alias = name_mapping.get(raw_name, raw_name) ch = SwitchChannel(self, alias, raw_name) new_channels.append(ch) new_channels.lock() self.add_submodule("channels", new_channels) self.snapshot(update=True) # make all channels read their conenctions self.connect_message()
def __init__(self, parent, name, slot, min_val=-5, max_val=5): super().__init__(parent, name) # Validate slot and channel values self._SLOT_VAL.validate(slot) self._slot = slot # Store whether we have access to the VERSADAC EEPROM self._VERSA_EEPROM_available = self._parent._VERSA_EEPROM_available # Create a list of channels in the slot channels = ChannelList(self, "Slot_Channels", parent.DAC_CHANNEL_CLASS) for i in range(4): channels.append(parent.DAC_CHANNEL_CLASS(self, "Chan{}".format(i), i, min_val=min_val, max_val=max_val)) self.add_submodule("channels", channels) # Set the slot mode. Valid modes are: # Off: Channel outputs are disconnected from the input, grounded with 10MOhm. # Fine: 2-channel mode. Channels 0 and 1 are output, use 2 and 3 for fine # adjustment of Channels 0 and 1 respectively # Coarse: All 4 channels are used as output # FineCald: Calibrated 2-channel mode, with 0 and 1 output, 2 and 3 used # automatically for fine adjustment. This mode only works for calibrated # DecaDAC's # Unfortunately there is no known way of reading the slot mode hence this will be # set in initialization if self._parent._cal_supported: slot_modes = {"Off": 0, "Fine": 1, "Coarse": 2, "FineCald": 3} else: slot_modes = {"Off": 0, "Fine": 1, "Coarse": 2} self.add_parameter('slot_mode', get_cmd="m;", get_parser=self._dac_parse, set_cmd="M{};", val_mapping=slot_modes) # Enable all slots in coarse mode. self.slot_mode.set(self.SLOT_MODE_DEFAULT)
def __init__(self, name, address, num_channels, **kwargs): super().__init__(name, address, **kwargs) self.max_current = _RohdeSchwarzHMC804x._max_currents[num_channels] self.add_parameter('state', label='Output enabled', set_cmd='OUTPut:MASTer:STATe {}', get_cmd='OUTPut:MASTer:STATe?', val_mapping={ 'ON': 1, 'OFF': 0 }, vals=vals.Enum('ON', 'OFF')) # channel-specific parameters channels = ChannelList(self, "SupplyChannel", RohdeSchwarzHMC804xChannel, snapshotable=False) for ch_num in range(1, num_channels + 1): ch_name = "ch{}".format(ch_num) channel = RohdeSchwarzHMC804xChannel(self, ch_name, ch_num) channels.append(channel) self.add_submodule(ch_name, channel) channels.lock() self.add_submodule("channels", channels) # add bipolar virtual channel 1/2 bip = RohdeSchwarzHMC804xBIP(self, 'bip', self.ch1, self.ch2) self.add_submodule("bip", bip) self.connect_message()
def __init__(self, name: str, address: str, num_channels: int, **kwargs: Any) -> None: super().__init__(name, address, **kwargs) self.max_current = _RohdeSchwarzHMC804x._max_currents[num_channels] self.add_parameter('state', label='Output enabled', set_cmd='OUTPut:MASTer:STATe {}', get_cmd='OUTPut:MASTer:STATe?', val_mapping={ 'ON': 1, 'OFF': 0 }, vals=vals.Enum('ON', 'OFF')) # channel-specific parameters channels = ChannelList(self, "SupplyChannel", RohdeSchwarzHMC804xChannel, snapshotable=False) for ch_num in range(1, num_channels + 1): ch_name = f"ch{ch_num}" channel = RohdeSchwarzHMC804xChannel(self, ch_name, ch_num) channels.append(channel) self.add_submodule(ch_name, channel) self.add_submodule("channels", channels.to_channel_tuple()) self.connect_message()
def __init__(self, name: str, address: str, terminator: str = '\r\n', **kwargs: Any) -> None: super().__init__(name, address, terminator=terminator, **kwargs) # Allow access to channels either by referring to the channel name # or through a channel list, i.e. instr.A.temperature() and # instr.channels[0].temperature() refer to the same parameter. # Note that `snapshotable` is set to false in order to avoid duplicate # snapshotting which otherwise will happen because each channel is also # added as a submodule to the instrument. channels = ChannelList(self, "TempSensors", self.CHANNEL_CLASS, snapshotable=False) for name, command in self.channel_name_command.items(): channel = self.CHANNEL_CLASS(self, name, command) channels.append(channel) self.add_submodule(name, channel) channels.lock() self.add_submodule("channels", channels) self.connect_message()
def __init__(self, name: str, address: str, **kwargs) -> None: """ Args: name: Name to use internally in QCoDeS. address: VISA resource address """ super().__init__(name, address, terminator='\n', **kwargs) channels = ChannelList(self, "Channels", AimTTiChannel, snapshotable=False) _model = self.get_idn()['model'] _numOutputChannels = {'PL068-P': 1, 'PL155-P': 1, 'PL303-P': 1, 'PL601-P': 1, 'PL303QMD-P': 2, 'PL303QMT': 3} if (not _model in _numOutputChannels.keys()) or (_model is None): raise NotKnownModel("Unknown model, connection cannot be " "established.") self.numOfChannels = _numOutputChannels[_model] for i in range(1, self.numOfChannels+1): channel = AimTTiChannel(self, f'ch{i}', i) channels.append(channel) self.add_submodule(f'ch{i}', channel) channels.lock() self.add_submodule('channels', channels) self.connect_message()
def __init__(self, name: str, address: str, channels_ranges: Sequence[Tuple[float, float]], ovp_ranges: Tuple[Sequence[Tuple[float, float]], Sequence[Tuple[float, float]]], ocp_ranges: Tuple[Sequence[Tuple[float, float]], Sequence[Tuple[float, float]]], **kwargs: Any): super().__init__(name, address, **kwargs) # Check if precision extension has been installed opt = self.installed_options() if 'DP8-ACCURACY' in opt: ovp_ranges_selected = ovp_ranges[1] ocp_ranges_selected = ocp_ranges[1] else: ovp_ranges_selected = ovp_ranges[0] ocp_ranges_selected = ocp_ranges[0] # channel-specific parameters channels = ChannelList(self, "SupplyChannel", RigolDP8xxChannel, snapshotable=False) for ch_num, channel_range in enumerate(channels_ranges): ch_name = "ch{}".format(ch_num + 1) channel = RigolDP8xxChannel(self, ch_name, ch_num + 1, channel_range, ovp_ranges_selected[ch_num], ocp_ranges_selected[ch_num]) channels.append(channel) self.add_submodule(ch_name, channel) channels.lock() self.add_submodule("channels", channels) self.connect_message()
def __init__(self, name: str, address: str, **kwargs): super().__init__(name, address, terminator="\r", **kwargs) self.visa_handle.baud_rate = 115200 instrument_info = self.parse_idn_string(self.ask("IDN")) for key, value in instrument_info.items(): setattr(self, key, value) channels = ChannelList(self, "channel", StahlChannel, snapshotable=False) for channel_number in range(1, self.n_channels + 1): name = f"channel{channel_number}" channel = StahlChannel(self, name, channel_number) self.add_submodule(name, channel) channels.append(channel) self.add_submodule("channel", channels) self.add_parameter("temperature", get_cmd=f"{self.identifier} TEMP", get_parser=chain( re.compile("^TEMP (.*)°C$").findall, float), unit="C") self.connect_message()
def __init__(self, name: str, address: str, login_name: str, login_password: str, **kwargs): super().__init__(name, **kwargs) # save access settings self.address = address # set up http connection password_manager = urllib.request.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, self.address, login_name, login_password) handler = urllib.request.HTTPBasicAuthHandler(password_manager) opener = urllib.request.build_opener(handler) urllib.request.install_opener(opener) # add channels channels = ChannelList(self, "PowerChannels", PowerChannel, snapshotable=False) for id_name in PowerChannel.CHANNEL_IDS.keys(): channel = PowerChannel(self, 'Chan{}'.format(id_name), id_name) channels.append(channel) self.add_submodule(id_name, channel) channels.lock() self.add_submodule("channels", channels) # print connect message self.connect_message()
class DacSlot(InstrumentChannel, DacReader): """ A single DAC Slot of the DECADAC """ _SLOT_VAL = vals.Ints(0, 5) def __init__(self, parent, name, slot, min_val=-5, max_val=5): super().__init__(parent, name) # Validate slot and channel values self._SLOT_VAL.validate(slot) self._slot = slot # Store whether we have access to the VERSADAC EEPROM self._VERSA_EEPROM_available = self._parent._VERSA_EEPROM_available # Create a list of channels in the slot self.channels = ChannelList(self, "Slot_Channels", DacChannel) for i in range(4): self.channels.append(DacChannel(self, "Chan{}".format(i), i)) # Set the slot mode. Valid modes are: # Off: Channel outputs are disconnected from the input, grounded with 10MOhm. # Fine: 2-channel mode. Channels 0 and 1 are output, use 2 and 3 for fine # adjustment of Channels 0 and 1 respectively # Coarse: All 4 channels are used as output # FineCald: Calibrated 2-channel mode, with 0 and 1 output, 2 and 3 used # automatically for fine adjustment. This mode only works for calibrated # DecaDAC's # Unfortunately there is no known way of reading the slot mode hence this will be # set in initialization if self._parent._cal_supported: slot_modes = {"Off": 0, "Fine": 1, "Coarse": 2, "FineCald": 3} else: slot_modes = {"Off": 0, "Fine": 1, "Coarse": 2} self.add_parameter('slot_mode', get_cmd="m;", get_parser=self._dac_parse, set_cmd="M{};", val_mapping=slot_modes) # Enable all slots in coarse mode. self.slot_mode.set("Coarse") def write(self, cmd): """ Overload write to set channel prior to any channel operations. Since all commands are echoed back, we must keep track of responses as well, otherwise commands receive the wrong response. """ self._set_slot() return self.ask_raw(cmd) def ask(self, cmd): """ Overload ask to set channel prior to operations """ self._set_slot() return self.ask_raw(cmd)
def __init__(self, name, address, active_channels={ 'A': 'cernox', 'B': 'diode' }, **kwargs): super().__init__(name, address, terminator="\r\n", **kwargs) # Allow access to channels either by referring to the channel name # or through a channel list. # i.e. Model_340.A.temperature() and Model_340.channels[0].temperature() # refer to the same parameter. # Serial parameters if instrument is connected via RS-232: # self.visa_handle.baud_rate = 57600 # self.visa_handle.stop_bits = visa.constants.StopBits.one # self.visa_handle.parity = visa.constants.Parity.odd # self.visa_handle.data_bits = 7 channels = ChannelList(self, "TempSensors", SensorChannel34x, snapshotable=False) for chan_name, sensor_name in active_channels.items(): channel = SensorChannel34x(self, chan_name, chan_name, sensor_name) channels.append(channel) self.add_submodule(chan_name, channel) channels.lock() self.add_submodule("channels", channels) ############### self.add_parameter(name='set_temperature', get_cmd='SETP?', get_parser=float, set_cmd='SETP 1,{}', label='Set Temperature', vals=Numbers(0.3, 300), unit='K') self.add_parameter(name='heater_range', get_cmd='RANGE?', get_parser=int, set_cmd='RANGE {}', label='Heater range', vals=Enum(0, 1, 2, 3, 4, 5), unit='') self.add_parameter(name='ramp_rate', get_cmd='RAMP? 1', get_parser=str, set_cmd='RAMP 1,1,{}', label='Heater range', vals=Numbers(min_value=0), unit='K/min') self.add_parameter(name='analog_out_config', get_cmd='ANALOG? 1', get_parser=str, label='Analog output configuration.', unit='') ############# self.connect_message()
def __init__(self, name, address, active_channels={ 'ch1': '50K Plate', 'ch2': '3K Plate' }, **kwargs): super().__init__(name, address, terminator="\r\n", **kwargs) # Allow access to channels either by referring to the channel name # or through a channel list. # i.e. Model_335.A.temperature() and Model_335.channels[0].temperature() # refer to the same parameter. # Serial parameters if instrument is connected via RS-232: # self.visa_handle.baud_rate = 57600 # self.visa_handle.stop_bits = visa.constants.StopBits.one # self.visa_handle.parity = visa.constants.Parity.odd # self.visa_handle.data_bits = 7 channels = ChannelList(self, "TempSensors", SensorChannel372, snapshotable=False) for chan_name, sensor_name in active_channels.items(): channel = SensorChannel372(self, 'Chan{}'.format(chan_name), chan_name, sensor_name) channels.append(channel) self.add_submodule(chan_name, channel) channels.lock() self.add_submodule("channels", channels) ############### # self.add_parameter(name='set_temperature', # get_cmd='SETP?', # get_parser=float, # set_cmd='SETP 1,{}', # label='Set Temerature', # vals=Numbers(4, 300), # unit='K') # self.add_parameter(name='heater_range', # get_cmd='RANGE?', # get_parser=int, # set_cmd='RANGE 1,{}', # label='Heater range', # vals=Enum(0, 1, 2, 3), # unit='') # self.add_parameter(name='ramp_rate', # get_cmd='RAMP? 1', # get_parser=str, # set_cmd='RAMP 1,1,{}', # label='Heater range', # vals=Numbers(min_value=0), # unit='K/min') ############## self.connect_message()
def __init__(self, name, chan_count=25): super().__init__(name) self.chan_count = chan_count channels = ChannelList(self, "channels", BBChan) for i in range(chan_count): channel = BBChan(self, f"ch{i+1:02}") channels.append(channel) self.add_submodule(f"ch{i+1:02}", channel) channels.lock() self.add_submodule("channels", channels)
def __init__(self, name: str, address: str, min_val: number = -5, max_val: number = 5, **kwargs) -> None: """ Creates an instance of the Decadac instruments Args: name: What this instrument is called locally. address: The address of the DAC. For a serial port this is ASRLn::INSTR where n is replaced with the address set in the VISA control panel. Baud rate and other serial parameters must also be set in the VISA control panel. min_val: The minimum value in volts that can be output by the DAC. This value should correspond to the DAC code 0. max_val: The maximum value in volts that can be output by the DAC. This value should correspond to the DAC code 65536. """ super().__init__(name, address, **kwargs) # Do feature detection self._feature_detect() # Create channels channels = ChannelList(self, "Channels", self.DAC_CHANNEL_CLASS, snapshotable=False) slots = ChannelList(self, "Slots", self.DAC_SLOT_CLASS) for i in range(5): # Create the 6 DAC slots slots.append( self.DAC_SLOT_CLASS(self, "Slot{}".format(i), i, min_val, max_val)) slot_channels = slots[i].channels slot_channels = cast(ChannelList, slot_channels) channels.extend(slot_channels) slots.lock() channels.lock() self.add_submodule("slots", slots) self.add_submodule("channels", channels) self.connect_message()
def __init__(self, name: str, address: str, **kwargs: Any) -> None: super().__init__(name, address, terminator="\n", **kwargs) self.add_submodule("horizontal", TektronixDPOHorizontal(self, "horizontal")) self.add_submodule("data", TektronixDPOData(self, "data")) self.add_submodule("waveform", TektronixDPOWaveformFormat(self, "waveform")) measurement_list = ChannelList(self, "measurement", TektronixDPOMeasurement) for measurement_number in range(1, self.number_of_measurements): measurement_name = f"measurement{measurement_number}" measurement_module = TektronixDPOMeasurement( self, measurement_name, measurement_number) self.add_submodule(measurement_name, measurement_module) measurement_list.append(measurement_module) self.add_submodule("measurement", measurement_list) self.add_submodule( "statistics", TektronixDPOMeasurementStatistics(self, "statistics")) channel_list = ChannelList(self, "channel", TektronixDPOChannel) for channel_number in range(1, self.number_of_channels + 1): channel_name = f"channel{channel_number}" channel_module = TektronixDPOChannel( self, channel_name, channel_number, ) self.add_submodule(channel_name, channel_module) channel_list.append(channel_module) self.add_submodule("channel", channel_list) self.add_submodule("trigger", TekronixDPOTrigger(self, "trigger")) self.add_submodule( "delayed_trigger", TekronixDPOTrigger(self, "delayed_trigger", delayed_trigger=True)) self.connect_message()
def __init__(self, name: str, address: str, **kwargs): super().__init__(name, address, terminator="\r\n", **kwargs) # add channels channels = ChannelList(self, "TempSensors", SensorChannel, snapshotable=False) for channel_id in ('A', 'B'): channel = SensorChannel(self, 'Chan{}'.format(channel_id), channel_id) channels.append(channel) self.add_submodule(channel_id, channel) channels.lock() self.add_submodule("channels", channels) # add parameters self.add_parameter('heater_output', get_cmd='HTR?', get_parser=float, label='heater output', unit='%') self.add_parameter('heater_range', get_cmd='RANGE?', get_parser=int, set_cmd='RANGE {}', val_mapping={ 'off': 0, '0.5W': 1, '5W': 2, '50W': 3 }, label='heater range') self.add_parameter('input', get_cmd='CSET? %i' % self._loop, set_cmd='CSET ' + str(self._loop) + ',{},1,1,1', get_parser=lambda ans: ans[0], label='input') self.add_parameter('setpoint', get_cmd='SETP? ' + str(self._loop), set_cmd='SETP ' + str(self._loop) + ', {}', get_parser=float, label='setpoint', unit='K') # print connect message self.connect_message()
def __init__(self, name, address, reset=_DEFAULT_RESET, baudrate=_DEFAULT_BAUDRATE, timeout=_DEFAULT_TIMEOUT, default_switch_pos=DacBase._DEFAULT_SWITCH_POS, terminator='\n', run_buffered_cmd=None, **kwargs): """ Initialize the device Args: name (str): name of the device address (str): address of the device (e.g. /dev/ttyUSB0) reset (bool): if "True", set all voltages to zero, set trigger mode to "always update" and stop ramps. If "False" only the upper and lower limit is reset. baudrate (int): baud rate of ASCII protocol timeout (int): seconds to allow for responses. Default 5 default_switch_pos (int): default switch position (-1, 0 or 1) that is set when reset is called (default: 0) Attributes: name (str): name slots (ChannelList): list of all slots channels (ChannelList): list of all channels """ super().__init__(name, address, timeout=timeout, terminator=terminator, **kwargs) self.current_slot = None self.current_channel = None channels = ChannelList(self, "Channels", DacChannel) slots = ChannelList(self, "Slots", DacSlot) for slot in range(5): slots.append(DacSlot(self, "Slot{}".format(slot), slot, default_switch_pos=default_switch_pos)) channels.extend(slots[slot].channels) slots.lock() channels.lock() self.add_submodule("slots", slots) self.add_submodule("channels", channels) self.run_buffered_cmd = run_buffered_cmd self._buffered_loop = None if reset: self.reset()
def __init__(self, name, address, **kwargs): super().__init__(name, address, **kwargs) channels = ChannelList(self, "TempSensors", SensorChannel, snapshotable=False) for chan_name in ('A', 'B'): channel = SensorChannel(self, chan_name, chan_name) channels.append(channel) self.add_submodule(chan_name, channel) channels.lock() self.add_submodule("channels", channels) self.connect_message() # Enable overtemp protection. self.write('OVER:SOUR A') self.write('OVER:TEMP 310') self.write('OVER:ENAB ON')
def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator="\r\n", **kwargs) channels = ChannelList(self, "TempSensors", SensorChannel, snapshotable=False) for chan_name in ('A', 'B'): channel = SensorChannel(self, 'Chan{}'.format(chan_name), chan_name) channels.append(channel) self.add_submodule(chan_name, channel) channels.lock() self.add_submodule("channels", channels) self.connect_message()
class LakeshoreBase(VisaInstrument): """ This base class has been written to be that base for the Lakeshore 336 and 372. There are probably other lakeshore modes that can use the functionality provided here. If you add another lakeshore driver please make sure to extend this class accordingly, or create a new one. In order to use a variation of the `BaseSensorChannel` class for sensor channels, just set `CHANNEL_CLASS` to that variation of the class inside your `LakeshoreBase`'s subclass. In order to add heaters (output channels) to the driver, add `BaseOutput` instances (subclasses of those) in your `LakeshoreBase`'s subclass constructor via `add_submodule` method. """ # Redefine this in the model-specific class in case you want to use a # different class for sensor channels CHANNEL_CLASS = BaseSensorChannel # This dict has channel name in the driver as keys, and channel "name" that # is used in instrument commands as values. For example, if channel called # "B" is referred to in instrument commands as '2', then this dictionary # will contain {'B': '2'} entry. channel_name_command: Dict[str, str] = {} input_channel_parameter_values_to_channel_name_on_instrument: Dict[Any, str] def __init__(self, name: str, address: str, terminator: str ='\r\n', **kwargs ) -> None: super().__init__(name, address, terminator=terminator, **kwargs) # Allow access to channels either by referring to the channel name # or through a channel list, i.e. instr.A.temperature() and # instr.channels[0].temperature() refer to the same parameter. self.channels = ChannelList(self, "TempSensors", self.CHANNEL_CLASS, snapshotable=False) for name, command in self.channel_name_command.items(): channel = self.CHANNEL_CLASS(self, name, command) self.channels.append(channel) self.add_submodule(name, channel) self.channels.lock() self.add_submodule("channels", self.channels) self.connect_message()
def __init__(self, name, address, **kwargs): super().__init__(name, address, terminator="\r\n", **kwargs) # Allow access to channels either by referring to the channel name # or through a channel list. # i.e. Model_336.A.temperature() and Model_336.channels[0].temperature() # refer to the same parameter. channels = ChannelList(self, "TempSensors", SensorChannel, snapshotable=False) for chan_name in ('A', 'B', 'C', 'D'): channel = SensorChannel(self, 'Chan{}'.format(chan_name), chan_name) channels.append(channel) self.add_submodule(chan_name, channel) channels.lock() self.add_submodule("channels", channels) self.connect_message()
def __init__(self, name: str, address: str, **kwargs: Any): super().__init__(name, address, terminator="\n", **kwargs) channels = ChannelList(self, "channel", DG1062Channel, snapshotable=False) for ch_num in [1, 2]: ch_name = f"ch{ch_num}" channel = DG1062Channel(self, ch_name, ch_num) channels.append(channel) self.add_submodule(ch_name, channel) channels.lock() self.add_submodule("channels", channels) self.connect_message()
def __init__(self, name, address, min_val=-5, max_val=5, **kwargs): """ Creates an instance of the Decadac instrument corresponding to one slot on the physical instrument. Args: name (str): What this instrument is called locally. port (str): The address of the DAC. For a serial port this is ASRLn::INSTR where n is replaced with the address set in the VISA control panel. Baud rate and other serial parameters must also be set in the VISA control panel. min_val (number): The minimum value in volts that can be output by the DAC. This value should correspond to the DAC code 0. max_val (number): The maximum value in volts that can be output by the DAC. This value should correspond to the DAC code 65536. """ super().__init__(name, address, **kwargs) # Do feature detection self._feature_detect() # Create channels channels = ChannelList(self, "Channels", DacChannel, snapshotable=False) slots = ChannelList(self, "Slots", DacSlot) for i in range(6): # Create the 6 DAC slots slots.append(DacSlot(self, "Slot{}".format(i), i, min_val, max_val)) channels.extend(self.slots[i].channels) slots.lock() channels.lock() self.add_submodule("slots", slots) self.add_submodule("channels", channels) self.connect_message()
def __init__(self, name: str, address: str, **kwargs) -> None: super().__init__(name, address, terminator="\r\n", **kwargs) sensors = ChannelList(self, "sensor", Model_325_Sensor, snapshotable=False) for inp in ['A', 'B']: sensor = Model_325_Sensor(self, 'sensor_{}'.format(inp), inp) sensors.append(sensor) self.add_submodule('sensor_{}'.format(inp), sensor) sensors.lock() self.add_submodule("sensor", sensors) heaters = ChannelList(self, "heater", Model_325_Heater, snapshotable=False) for loop in [1, 2]: heater = Model_325_Heater(self, 'heater_{}'.format(loop), loop) heaters.append(heater) self.add_submodule('heater_{}'.format(loop), heater) heaters.lock() self.add_submodule("heater", heaters) curves = ChannelList(self, "curve", Model_325_Curve, snapshotable=False) for curve_index in range(1, 35): curve = Model_325_Curve(self, curve_index) curves.append(curve) self.add_submodule("curve", curves) self.connect_message()
def __init__(self, name, address, terminator='\n', timeout=5, **kwargs): super().__init__(name, address, terminator=terminator, timeout=timeout, **kwargs) self.add_parameter('waveform_xorigin', get_cmd='WAVeform:XORigin?', unit='s', get_parser=float) self.add_parameter('waveform_xincrem', get_cmd=':WAVeform:XINCrement?', unit='s', get_parser=float) self.add_parameter('waveform_npoints', get_cmd='WAV:POIN?', set_cmd='WAV:POIN {}', unit='s', get_parser=int) self.add_parameter('waveform_yorigin', get_cmd='WAVeform:YORigin?', unit='V', get_parser=float) self.add_parameter('waveform_yincrem', get_cmd=':WAVeform:YINCrement?', unit='V', get_parser=float) self.add_parameter('waveform_yref', get_cmd=':WAVeform:YREFerence?', unit='V', get_parser=float) self.add_parameter('trigger_mode', get_cmd=':TRIGger:MODE?', set_cmd=':TRIGger:MODE {}', unit='V', vals=Enum('edge', 'pulse', 'video', 'pattern'), get_parser=str) # trigger source self.add_parameter('trigger_level', unit='V', get_cmd=self._get_trigger_level, set_cmd=self._set_trigger_level, vals=Numbers()) self.add_parameter('trigger_edge_source', label='Source channel for the edge trigger', get_cmd=':TRIGger:EDGE:SOURce?', set_cmd=':TRIGger:EDGE:SOURce {}', val_mapping={ 'ch1': 'CHAN1', 'ch2': 'CHAN2', 'ch3': 'CHAN3', 'ch4': 'CHAN4' }) self.add_parameter('trigger_edge_slope', label='Slope of the edge trigger', get_cmd=':TRIGger:EDGE:SLOPe?', set_cmd=':TRIGger:EDGE:SLOPe {}', vals=Enum('positive', 'negative', 'neither')) self.add_parameter('data_source', label='Waveform Data source', get_cmd=':WAVeform:SOURce?', set_cmd=':WAVeform:SOURce {}', val_mapping={ 'ch1': 'CHAN1', 'ch2': 'CHAN2', 'ch3': 'CHAN3', 'ch4': 'CHAN4' }) self.add_parameter('time_axis', unit='s', label='Time', set_cmd=False, get_cmd=self._get_time_axis, vals=Arrays(shape=(self.waveform_npoints, )), snapshot_value=False) channels = ChannelList(self, "channels", RigolDS1074ZChannel, snapshotable=False) for channel_number in range(1, 5): channel = RigolDS1074ZChannel(self, "ch{}".format(channel_number), channel_number) channels.append(channel) channels.lock() self.add_submodule('channels', channels) self.connect_message()
def __init__( self, name: str, address: str, # Set frequency ranges min_freq: Union[int, float], max_freq: Union[int, float], # Set power ranges min_power: Union[int, float], max_power: Union[int, float], nports: int, # Number of ports on the PNA **kwargs: Any) -> None: super().__init__(name, address, terminator='\n', **kwargs) self.min_freq = min_freq self.max_freq = max_freq #Ports ports = ChannelList(self, "PNAPorts", PNAPort) for port_num in range(1, nports + 1): port = PNAPort(self, f"port{port_num}", port_num, min_power, max_power) ports.append(port) self.add_submodule(f"port{port_num}", port) ports.lock() self.add_submodule("ports", ports) # Drive power self.add_parameter('power', label='Power', get_cmd='SOUR:POW?', get_parser=float, set_cmd='SOUR:POW {:.2f}', unit='dBm', vals=Numbers(min_value=min_power, max_value=max_power)) # IF bandwidth self.add_parameter('if_bandwidth', label='IF Bandwidth', get_cmd='SENS:BAND?', get_parser=float, set_cmd='SENS:BAND {:.2f}', unit='Hz', vals=Numbers(min_value=1, max_value=15e6)) # Number of averages (also resets averages) self.add_parameter('averages_enabled', label='Averages Enabled', get_cmd="SENS:AVER?", set_cmd="SENS:AVER {}", val_mapping={ True: '1', False: '0' }) self.add_parameter('averages', label='Averages', get_cmd='SENS:AVER:COUN?', get_parser=int, set_cmd='SENS:AVER:COUN {:d}', unit='', vals=Numbers(min_value=1, max_value=65536)) # Setting frequency range self.add_parameter('start', label='Start Frequency', get_cmd='SENS:FREQ:STAR?', get_parser=float, set_cmd='SENS:FREQ:STAR {}', unit='Hz', vals=Numbers(min_value=min_freq, max_value=max_freq)) self.add_parameter('stop', label='Stop Frequency', get_cmd='SENS:FREQ:STOP?', get_parser=float, set_cmd='SENS:FREQ:STOP {}', unit='Hz', vals=Numbers(min_value=min_freq, max_value=max_freq)) self.add_parameter('center', label='Center Frequency', get_cmd='SENS:FREQ:CENT?', get_parser=float, set_cmd='SENS:FREQ:CENT {}', unit='Hz', vals=Numbers(min_value=min_freq, max_value=max_freq)) self.add_parameter('span', label='Frequency Span', get_cmd='SENS:FREQ:SPAN?', get_parser=float, set_cmd='SENS:FREQ:SPAN {}', unit='Hz', vals=Numbers(min_value=min_freq, max_value=max_freq)) # Number of points in a sweep self.add_parameter('points', label='Points', get_cmd='SENS:SWE:POIN?', get_parser=int, set_cmd='SENS:SWE:POIN {}', unit='', vals=Numbers(min_value=1, max_value=100001)) # Electrical delay self.add_parameter('electrical_delay', label='Electrical Delay', get_cmd='CALC:CORR:EDEL:TIME?', get_parser=float, set_cmd='CALC:CORR:EDEL:TIME {:.6e}', unit='s', vals=Numbers(min_value=0, max_value=100000)) # Sweep Time self.add_parameter('sweep_time', label='Time', get_cmd='SENS:SWE:TIME?', get_parser=float, unit='s', vals=Numbers(0, 1e6)) # Sweep Mode self.add_parameter('sweep_mode', label='Mode', get_cmd='SENS:SWE:MODE?', set_cmd='SENS:SWE:MODE {}', vals=Enum("HOLD", "CONT", "GRO", "SING")) # Group trigger count self.add_parameter('group_trigger_count', get_cmd="SENS:SWE:GRO:COUN?", get_parser=int, set_cmd="SENS:SWE:GRO:COUN {}", vals=Ints(1, 2000000)) # Trigger Source self.add_parameter('trigger_source', get_cmd="TRIG:SOUR?", set_cmd="TRIG:SOUR {}", vals=Enum("EXT", "IMM", "MAN")) # Traces self.add_parameter('active_trace', label='Active Trace', get_cmd="CALC:PAR:MNUM?", get_parser=int, set_cmd="CALC:PAR:MNUM {}", vals=Numbers(min_value=1, max_value=24)) # Note: Traces will be accessed through the traces property which # updates the channellist to include only active trace numbers self._traces = ChannelList(self, "PNATraces", PNATrace) self.add_submodule("traces", self._traces) # Add shortcuts to first trace trace1 = self.traces[0] for param in trace1.parameters.values(): self.parameters[param.name] = param # And also add a link to run sweep self.run_sweep = trace1.run_sweep # Set this trace to be the default (it's possible to end up in a # situation where no traces are selected, causing parameter snapshots # to fail) self.active_trace(trace1.trace_num) # Set auto_sweep parameter # If we want to return multiple traces per setpoint without sweeping # multiple times, we should set this to false self.add_parameter('auto_sweep', label='Auto Sweep', set_cmd=None, get_cmd=None, vals=Bool(), initial_value=True) # A default output format on initialisation self.write('FORM REAL,32') self.write('FORM:BORD NORM') self.connect_message()
def __init__(self, name, address, timeout=20, **kwargs): """ Initialises the TPS2012. Args: name (str): Name of the instrument used by QCoDeS address (string): Instrument address as used by VISA timeout (float): visa timeout, in secs. long default (180) to accommodate large waveforms """ super().__init__(name, address, timeout=timeout, **kwargs) self.connect_message() # Scope trace boolean self.trace_ready = False # functions self.add_function('force_trigger', call_cmd='TRIGger FORce', docstring='Force trigger event') self.add_function('run', call_cmd='ACQuire:STATE RUN', docstring='Start acquisition') self.add_function('stop', call_cmd='ACQuire:STATE STOP', docstring='Stop acquisition') # general parameters self.add_parameter('trigger_type', label='Type of the trigger', get_cmd='TRIGger:MAIn:TYPe?', set_cmd='TRIGger:MAIn:TYPe {}', vals=vals.Enum('EDGE', 'VIDEO', 'PULSE')) self.add_parameter('trigger_source', label='Source for the trigger', get_cmd='TRIGger:MAIn:EDGE:SOURce?', set_cmd='TRIGger:MAIn:EDGE:SOURce {}', vals=vals.Enum('CH1', 'CH2')) self.add_parameter('trigger_edge_slope', label='Slope for edge trigger', get_cmd='TRIGger:MAIn:EDGE:SLOpe?', set_cmd='TRIGger:MAIn:EDGE:SLOpe {}', vals=vals.Enum('FALL', 'RISE')) self.add_parameter('trigger_level', label='Trigger level', unit='V', get_cmd='TRIGger:MAIn:LEVel?', set_cmd='TRIGger:MAIn:LEVel {}', vals=vals.Numbers()) self.add_parameter('data_source', label='Data source', get_cmd='DATa:SOUrce?', set_cmd='DATa:SOURce {}', vals=vals.Enum('CH1', 'CH2')) self.add_parameter('horizontal_scale', label='Horizontal scale', unit='s', get_cmd='HORizontal:SCAle?', set_cmd=self._set_timescale, get_parser=float, vals=vals.Enum(5e-9, 10e-9, 25e-9, 50e-9, 100e-9, 250e-9, 500e-9, 1e-6, 2.5e-6, 5e-6, 10e-6, 25e-6, 50e-6, 100e-6, 250e-6, 500e-6, 1e-3, 2.5e-3, 5e-3, 10e-3, 25e-3, 50e-3, 100e-3, 250e-3, 500e-3, 1, 2.5, 5, 10, 25, 50)) # channel-specific parameters channels = ChannelList(self, "ScopeChannels", TPS2012Channel, snapshotable=False) for ch_num in range(1, 3): ch_name = "ch{}".format(ch_num) channel = TPS2012Channel(self, ch_name, ch_num) channels.append(channel) self.add_submodule(ch_name, channel) channels.lock() self.add_submodule("channels", channels) # Necessary settings for parsing the binary curve data self.visa_handle.encoding = 'latin-1' log.info('Set VISA encoding to latin-1') self.write('DATa:ENCdg RPBinary') log.info('Set TPS2012 data encoding to RPBinary' + ' (Positive Integer Binary)') self.write('DATa:WIDTh 2') log.info('Set TPS2012 data width to 2')
def __init__(self, name, address, timeout=5, **kwargs): """ Initialises the LeCroy. Args: name (str): Name of the instrument used by QCoDeS address (string): Instrument address as used by VISA timeout (float): visa timeout, in secs. long default (180) to accommodate large waveforms """ super().__init__(name, address, timeout=timeout, **kwargs) self.connect_message() print("Available Commands: save data, change averages, change timebase, change vertical steps") # Scope trace boolean self.trace_ready = False # functions self.add_function('force_trigger', call_cmd='ARM', docstring='Force trigger event') self.add_function('run', call_cmd='ACQuire:STATE RUN', docstring='Start acquisition') self.add_function('stop', call_cmd='ACQuire:STATE STOP', docstring='Stop acquisition') self.add_function('clsw', docstring='Clear Sweeps', call_cmd='CLSW', ) self.add_function('wait', docstring='Wait to finish acquisition', call_cmd='WAIT' ) self.add_function('wai', docstring='Wait to finish acquisition', call_cmd='*WAI' ) # general parameters self.add_parameter('trigger_type', label='Type of the trigger', get_cmd='TRIGger:MAIn:TYPe?', set_cmd='TRIGger:MAIn:TYPe {}', vals=vals.Enum('EDGE', 'VIDEO', 'PULSE') ) self.add_parameter('trigger_source', label='Source for the trigger', get_cmd='TRIGger:MAIn:EDGE:SOURce?', set_cmd='TRIGger:MAIn:EDGE:SOURce {}', vals=vals.Enum('CH1', 'CH2') ) self.add_parameter('trigger_edge_slope', label='Slope for edge trigger', get_cmd='TRIGger:MAIn:EDGE:SLOpe?', set_cmd='TRIGger:MAIn:EDGE:SLOpe {}', vals=vals.Enum('FALL', 'RISE') ) self.add_parameter('trigger_level', label='Trigger level', unit='V', get_cmd='TRIGger:MAIn:LEVel?', set_cmd='TRIGger:MAIn:LEVel {}', vals=vals.Numbers() ) self.add_parameter('data_source', label='Data source', get_cmd='DATa:SOUrce?', set_cmd='DATa:SOURce {}', vals=vals.Enum('CH1', 'CH2','CH3', 'CH4') ) self.add_parameter('horizontal_scale', label='Horizontal scale', unit='s', get_cmd='HORizontal:SCAle?', set_cmd=self._set_timescale, get_parser=float, vals=vals.Enum(5e-9, 10e-9, 25e-9, 50e-9, 100e-9, 250e-9, 500e-9, 1e-6, 2.5e-6, 5e-6, 10e-6, 25e-6, 50e-6, 100e-6, 250e-6, 500e-6, 1e-3, 2.5e-3, 5e-3, 10e-3, 25e-3, 50e-3, 100e-3, 250e-3, 500e-3, 1, 2.5, 5, 10, 25, 50)) self.add_parameter('samples', set_cmd = "MSIZ {}".format({}), get_cmd = "MSIZ?" ) self.add_function('trg', call_cmd = self._triggers, #get_cmd = "VBS? 'Return=app.Acquisition.C{}".format(chan) + ".AverageSweeps'", ) # channel-specific parameters channels = ChannelList(self, "ScopeChannels", LCRChannel, snapshotable=False) for ch_num in range(0, 5): ch_name = "ch{}".format(ch_num) channel = LCRChannel(self, ch_name, ch_num) channels.append(channel) self.add_submodule(ch_name, channel) channels.lock() self.add_submodule("channels", channels) # Necessary settings for parsing the binary curve data self.visa_handle.encoding = 'latin-1' log.info('Set VISA encoding to latin-1') self.write('DATa:ENCdg RPBinary') log.info('Set LeCroy data encoding to RPBinary' + ' (Positive Integer Binary)') self.write('DATa:WIDTh 2') log.info('Set LCR data width to 2') # Note: This section is no longer needed. for chan in range(5): self.add_parameter('ch{}_avg'.format(chan), set_cmd = "VBS 'app.Acquisition.C{}".format(chan) + ".AverageSweeps={}'", get_cmd = "VBS? 'Return=app.Acquisition.C{}".format(chan) + ".AverageSweeps'" ) self.add_parameter('ch{}_samples'.format(chan), set_cmd = "VBS 'app.Acquisition.C{}".format(chan) + ".Samples={}'", get_cmd = "VBS? 'Return=app.Acquisition.C{}".format(chan) + ".Out.Result.Samples'" )