Beispiel #1
0
    def _connect(self) -> None:
        """Connects the device to the data server.

        Instantiates the device controller from :mod:`zhinst-toolkit`, sets up 
        the data server and connects the device the data server. This method is 
        called from `__init__` of the :class:`BaseInstrument` class.

        """
        self._controller = tk.HDAWG(
            self._name,
            self._serial,
            interface=self._interface,
            host=self._host,
            port=self._port,
            api=self._api,
        )
        self._controller.setup()
        self._controller.connect_device(nodetree=False)
        self.connect_message()
        self._get_nodetree_dict()
        # initialize ChannelList of AWGs
        channel_list = ChannelList(self, "awgs", AWG)
        for i in range(4):
            channel_list.append(AWG(f"awg-{i}", i, self, self._controller))
        channel_list.lock()
        self.add_submodule("awgs", channel_list)
Beispiel #2
0
 def _init_awg_channels(self):
     # initialize ChannelList of AWGs
     channel_list = ChannelList(self, "awgs", AWG)
     for i in range(4):
         channel_list.append(AWG(f"awg-{i}", i, self, self._controller))
     channel_list.lock()
     self.add_submodule("awgs", channel_list)
Beispiel #3
0
 def _init_readout_channels(self):
     # init submodules for ReadoutChannels
     channel_list = ChannelList(self, "channels", Channel)
     for i in range(10):
         channel_list.append(Channel(f"ch-{i}", i, self, self._controller))
     channel_list.lock()
     self.add_submodule("channels", channel_list)
Beispiel #4
0
 def _init_qachannels(self):
     # init submodules for QAChannels
     num_qachannels = self._controller.num_qachannels()
     channel_list = ChannelList(self, "qachannels", QAChannel)
     for i in range(num_qachannels):
         channel_list.append(
             QAChannel(f"qachannel-{i}", i, self, self._controller))
     channel_list.lock()
     self.add_submodule("qachannels", channel_list)
Beispiel #5
0
    def __init__(self, name, address, silent=False, **kwargs):
        """
        Args:
            name (string): The name of the instrument used internally
                by QCoDeS. Must be unique.
            address (string): The VISA resource name.
            silent (Optional[bool]): If True, no connect message is printed.
        """

        warnings.warn(
            "This driver is old and will be removed "
            "from QCoDeS soon. Please use the "
            "WaveformGenerator_33XXX from the file "
            "instrument_drivers/Keysight/KeysightAgilent_33XXX"
            " instead.", UserWarning)

        super().__init__(name, address, **kwargs)

        channels = ChannelList(self,
                               "Channels",
                               KeysightChannel,
                               snapshotable=False)
        for i in range(1, 3):
            channel = KeysightChannel(self, 'ch{}'.format(i), i)
            channels.append(channel)
        channels.lock()
        self.add_submodule('channels', channels)

        self.add_parameter('sync_source',
                           label='Source of sync function',
                           set_cmd='OUTPut:SYNC:SOURce {}',
                           get_cmd='OUTPut:SYNC:SOURce?',
                           val_mapping={
                               1: 'CH1',
                               2: 'CH2'
                           },
                           vals=vals.Enum(1, 2))

        self.add_parameter('sync_output',
                           label='Sync output state',
                           set_cmd='OUTPut:SYNC {}',
                           get_cmd='OUTPut:SYNC?',
                           val_mapping={
                               'ON': 1,
                               'OFF': 0
                           },
                           vals=vals.Enum('ON', 'OFF'))

        self.add_function('force_trigger', call_cmd='*TRG')

        self.add_function('sync_channel_phases', call_cmd='PHAS:SYNC')

        if not silent:
            self.connect_message()
Beispiel #6
0
 def _init_integrations(self):
     # init submodules for Integration Units
     num_integrations = self._readout.device.num_integrations_per_qachannel(
     )
     channel_list = ChannelList(self, "integrations", Integration)
     for i in range(num_integrations):
         channel_list.append(
             Integration(f"integration-{i}", i, self, self._readout))
     channel_list.lock()
     self.add_submodule("integrations", channel_list)
     self._readout._init_integrations()
Beispiel #7
0
    def __init__(self, name, address, **kwargs):
        super().__init__(name, address, 5, '\r\n', **kwargs)

        # configure the port
        if 'ASRL' not in address:
            self.visa_handle.baud_rate = 38400  # USB has no baud rate parameter
        self.visa_handle.stop_bits = pyvisa.constants.StopBits.one
        self.visa_handle.parity = pyvisa.constants.Parity.none
        self.visa_handle.read_termination = '\r\n'
        self.parameters.pop('IDN')  # Get rid of this parameter

        # for security check the ID from the device
        self.idn = self.ask("ver")
        log.debug("Main version:", self.idn)
        if not self.idn.startswith("attocube ANC300"):
            raise RuntimeError("Invalid device ID found: " + str(self.idn))

        # Now request all serial numbers of the axis modules. The first 6 chars are the id
        # of the module type. This will be used to enable special parameters.
        # Instantiate the axis channels only for available axis
        axischannels = ChannelList(self,
                                   "Anc300Channels",
                                   Anc300Axis,
                                   snapshotable=False)
        for ax in range(1, 7 + 1):
            try:
                tmp = self.ask('getser {}'.format(ax))
                name = 'axis{}'.format(ax)
                axischan = Anc300Axis(self, name, ax, tmp[:6])
                axischannels.append(axischan)
                self.add_submodule(name, axischan)
            except:
                pass
        axischannels.lock()
        self.add_submodule('axis_channels', axischannels)

        # instantiate the trigger channels even if they could not be tested
        triggerchannels = ChannelList(self,
                                      "Anc300Trigger",
                                      Anc300TriggerOut,
                                      snapshotable=False)
        for ax in [1, 2, 3]:
            name = 'trigger{}'.format(ax)
            trigchan = Anc300TriggerOut(self, name, ax)
            triggerchannels.append(trigchan)
            self.add_submodule(name, trigchan)
        triggerchannels.lock()
        self.add_submodule('trigger_channels', triggerchannels)
Beispiel #8
0
    def __init__(self, name, address, port=23):
        super().__init__(name, address, port)
        self.flush_connection()

        channels = ChannelList(self, "Channels", MC_channel,
                               snapshotable=False)

        _chanlist = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
        _max_channel_number = int(self.IDN()['model'][3])
        _chanlist = _chanlist[0:_max_channel_number]

        for c in _chanlist:
            channel = MC_channel(self, f'channel_{c}', c)
            channels.append(channel)
            self.add_submodule(f'channel_{c}', channel)
        channels.lock()
        self.add_submodule('channels', channels)

        self.connect_message()
Beispiel #9
0
    def _add_submodules_recursively(self, parent, treedict: Dict) -> None:
        """
        Recursively add submodules (ZINodes) for each node in the ZI node tree.
        At the leaves create a parameter. Create a ChannelList as submodules
        whenever a node is enumerated, e.g. 'dev8030/sigouts/*/on'.
        
        Arguments:
            parent (InstrumentChannel): parent QCoDeS object, either 
                Instrument(-Channel) or ZINode
            treedict (dict): dictionary specifying the (sub-)tree of the ZI 
                node hirarchy

        """
        for key, value in treedict.items():
            if all(isinstance(k, int) for k in value.keys()):
                # if enumerated node
                if "Node" in list(value.values())[0].keys():
                    # if at leave, don't create ChannelList but parameter with "{key}{i}"
                    for k in value.keys():
                        self._add_parameter_from_dict(parent, f"{key}{k}",
                                                      value[k])
                else:
                    # else, create ChannelList to hold all enumerated ZINodes
                    channel_list = ChannelList(parent, key, ZINode)
                    for k in value.keys():
                        ch_name = f"{key}{k}"
                        ch = ZINode(parent, ch_name)
                        channel_list.append(ch)
                        self._add_submodules_recursively(ch, treedict[key][k])
                    channel_list.lock()
                    parent.add_submodule(key, channel_list)
            else:
                # if not enumerated ZINode
                if "Node" in value.keys():
                    # if at leave add a parameter to the node
                    self._add_parameter_from_dict(parent, key, value)
                else:
                    # if not at leave, create ZINode as submodule
                    module = ZINode(parent, key)
                    parent.add_submodule(key, module)
                    self._add_submodules_recursively(module, treedict[key])
Beispiel #10
0
    def add_channels(self):
        channels = ChannelList(
            self, "Channels", self.CHANNEL_CLASS, snapshotable=False)

        _chanlist = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
        self._deprecated_attributes = {
            f'channel_{k}': k
            for k in _chanlist
        }

        _max_channel_number = self.get_number_of_channels()
        _chanlist = _chanlist[0:_max_channel_number]

        for c in _chanlist:
            channel = self.CHANNEL_CLASS(self, f'channel_{c}', c)
            channels.append(channel)
            attribute_name = f'channel_{c}'
            self.add_submodule(attribute_name, channel)
            self.add_submodule(c, channel)
            self._deprecated_attributes[attribute_name] = c
        channels.lock()
        self.add_submodule('channels', channels)
Beispiel #11
0
    def __init__(self, name: str, library: ANC350v3Lib, inst_no: int = 0):
        super().__init__(name)

        if isinstance(library, ANC350v4Lib):
            self._version_no = 4
        elif isinstance(library, ANC350v3Lib):
            self._version_no = 3
        else:
            raise NotImplementedError(
                "Only version 3 and 4 of ANC350's driver-DLL are currently "
                "supported")

        self._lib = library
        self._device_no = inst_no
        self._device_handle = self._lib.connect(inst_no)

        axischannels = ChannelList(self, "Anc350Axis", Anc350Axis)
        for nr, axis in enumerate(['x', 'y', 'z']):
            axis_name = f"{axis}_axis"
            axischannel = Anc350Axis(parent=self, name=axis_name, axis=nr)
            axischannels.append(axischannel)
            self.add_submodule(axis_name, axischannel)
        axischannels.lock()
        self.add_submodule("axis_channels", axischannels)
Beispiel #12
0
    def __init__(self,
                 name,
                 address,
                 num_chans=48,
                 update_currents=True,
                 **kwargs):
        """
        Instantiates the instrument.

        Args:
            name (str): The instrument name used by qcodes
            address (str): The VISA name of the resource
            num_chans (int): Number of channels to assign. Default: 48
            update_currents (bool): Whether to query all channels for their
                current current value on startup. Default: True.

        Returns:
            QDac object
        """
        super().__init__(name, address, **kwargs)
        self._output_n_lines = 50
        handle = self.visa_handle
        self._get_status_performed = False
        # This is the baud rate on power-up. It can be changed later but
        # you must start out with this value.
        handle.baud_rate = 480600
        handle.parity = visa.constants.Parity(0)
        handle.data_bits = 8
        self.set_terminator('\n')
        # TODO: do we want a method for write termination too?
        handle.write_termination = '\n'
        # TODO: do we need a query delay for robust operation?
        self._write_response = ''

        if self._get_firmware_version() < 0.170202:
            raise RuntimeError('''
                               Obsolete QDAC Software version detected.
                               QCoDeS only supports version 0.170202 or newer.
                               Contact [email protected] for an update.
                               ''')

        self.num_chans = num_chans

        # Assigned slopes. Entries will eventually be [chan, slope]
        self._slopes = []
        # Function generators (used in _set_voltage)
        self._fgs = set(range(1, 9))
        self._assigned_fgs = {}  # {chan: fg}
        # Sync channels
        self._syncoutputs = []  # Entries: [chan, syncchannel]

        self.chan_range = range(1, 1 + self.num_chans)
        self.channel_validator = vals.Ints(1, self.num_chans)

        channels = ChannelList(self,
                               "Channels",
                               QDacChannel,
                               snapshotable=False,
                               multichan_paramclass=QDacMultiChannelParameter)

        for i in self.chan_range:
            channel = QDacChannel(self, f'chan{i:02}', i)
            channels.append(channel)
            # Should raise valueerror if name is invalid (silently fails now)
            self.add_submodule(f'ch{i:02}', channel)
        channels.lock()
        self.add_submodule('channels', channels)

        for board in range(6):
            for sensor in range(3):
                label = f'Board {board}, Temperature {sensor}'
                self.add_parameter(name=f'temp{board}_{sensor}',
                                   label=label,
                                   unit='C',
                                   get_cmd=f'tem {board} {sensor}',
                                   get_parser=self._num_verbose)

        self.add_parameter(name='cal',
                           set_cmd='cal {}',
                           vals=self.channel_validator)
        # TO-DO: maybe it's too dangerous to have this settable.
        # And perhaps ON is a better verbose mode default?
        self.add_parameter(name='verbose',
                           set_cmd='ver {}',
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        self.add_parameter(name='fast_voltage_set',
                           label='fast voltage set',
                           get_cmd=None,
                           set_cmd=None,
                           vals=vals.Bool(),
                           initial_value=False,
                           docstring=""""Deprecated with no functionality""")
        # Initialise the instrument, all channels DC (unbind func. generators)
        for chan in self.chan_range:
            # Note: this call does NOT change the voltage on the channel
            self.write(f'wav {chan} 0 1 0')

        self.verbose.set(False)
        self.connect_message()
        log.info('[*] Querying all channels for voltages and currents...')
        self._update_cache(readcurrents=update_currents)
        self._update_currents = update_currents
        log.info('[+] Done')
Beispiel #13
0
    def __init__(self,
                 name: str,
                 address: str,
                 timeout: float = 20,
                 **kwargs: Any):
        """
        Initialises the DS4000.

        Args:
            name: Name of the instrument used by QCoDeS
            address: Instrument address as used by VISA
            timeout: visa timeout, in secs. long default (180)
                to accommodate large waveforms
        """

        # Init VisaInstrument. device_clear MUST NOT be issued, otherwise communications hangs
        # due a bug in firmware
        super().__init__(name,
                         address,
                         device_clear=False,
                         timeout=timeout,
                         **kwargs)
        self.connect_message()

        self._check_firmware_version()

        # functions
        self.add_function('run',
                          call_cmd=':RUN',
                          docstring='Start acquisition')
        self.add_function('stop',
                          call_cmd=':STOP',
                          docstring='Stop acquisition')
        self.add_function('single',
                          call_cmd=':SINGle',
                          docstring='Single trace acquisition')
        self.add_function('force_trigger',
                          call_cmd='TFORce',
                          docstring='Force trigger event')
        self.add_function("auto_scale",
                          call_cmd=":AUToscale",
                          docstring="Perform autoscale")

        # general parameters
        self.add_parameter('trigger_type',
                           label='Type of the trigger',
                           get_cmd=':TRIGger:MODE?',
                           set_cmd=':TRIGger:MODE {}',
                           vals=vals.Enum('EDGE', 'PULS', 'RUNT', 'NEDG',
                                          'SLOP', 'VID', 'PATT', 'RS232',
                                          'IIC', 'SPI', 'CAN', 'FLEX', 'USB'))
        self.add_parameter('trigger_mode',
                           label='Mode of the trigger',
                           get_cmd=':TRIGger:SWEep?',
                           set_cmd=':TRIGger:SWEep {}',
                           vals=vals.Enum('AUTO', 'NORM', 'SING'))
        self.add_parameter("time_base",
                           label="Horizontal time base",
                           get_cmd=":TIMebase:MAIN:SCALe?",
                           set_cmd=":TIMebase:MAIN:SCALe {}",
                           get_parser=float,
                           unit="s/div")
        self.add_parameter("sample_point_count",
                           label="Number of the waveform points",
                           get_cmd=":WAVeform:POINts?",
                           set_cmd=":WAVeform:POINts {}",
                           get_parser=int,
                           vals=Ints(min_value=1))
        self.add_parameter("enable_auto_scale",
                           label="Enable or disable autoscale",
                           get_cmd=":SYSTem:AUToscale?",
                           set_cmd=":SYSTem:AUToscale {}",
                           get_parser=bool,
                           vals=Bool())

        channels = ChannelList(self,
                               "Channels",
                               RigolDS4000Channel,
                               snapshotable=False)

        for channel_number in range(1, 5):
            channel = RigolDS4000Channel(self, f"ch{channel_number}",
                                         channel_number)
            channels.append(channel)

        channels.lock()
        self.add_submodule('channels', channels)
Beispiel #14
0
    def __init__(self,
                 name: str,
                 address: str,
                 max_frequency: float,
                 reset: bool = False,
                 **kwargs: Any):
        super().__init__(name, address, terminator='\n', **kwargs)
        self._max_frequency = max_frequency
        # Reference commands
        self.add_parameter(name='frequency',
                           label='Frequency',
                           unit='Hz',
                           get_cmd='FREQ?',
                           set_cmd='FREQ {}',
                           get_parser=float,
                           vals=Numbers(min_value=1e-3,
                                        max_value=self._max_frequency))
        self.add_parameter(name='sine_outdc',
                           label='Sine out dc level',
                           unit='V',
                           get_cmd='SOFF?',
                           set_cmd='SOFF {}',
                           get_parser=float,
                           vals=Numbers(min_value=-5, max_value=5))
        self.add_parameter(name='amplitude',
                           label='Amplitude',
                           unit='V',
                           get_cmd='SLVL?',
                           set_cmd='SLVL {}',
                           get_parser=float,
                           vals=Numbers(min_value=0, max_value=2))
        self.add_parameter(name='harmonic',
                           label='Harmonic',
                           get_cmd='HARM?',
                           get_parser=int,
                           set_cmd='HARM {:d}',
                           vals=Ints(min_value=1, max_value=99))
        self.add_parameter(name='phase',
                           label='Phase',
                           unit='deg',
                           get_cmd='PHAS?',
                           set_cmd='PHAS {}',
                           get_parser=float,
                           vals=Numbers(min_value=-3.6e5, max_value=3.6e5))
        # Signal commands
        self.add_parameter(name='sensitivity',
                           label='Sensitivity',
                           get_cmd='SCAL?',
                           set_cmd='SCAL {:d}',
                           get_parser=self._get_sensitivity,
                           set_parser=self._set_sensitivity)
        self.add_parameter(name='filter_slope',
                           label='Filter slope',
                           unit='dB/oct',
                           get_cmd='OFSL?',
                           set_cmd='OFSL {}',
                           val_mapping={
                               6: 0,
                               12: 1,
                               18: 2,
                               24: 3
                           })
        self.add_parameter(name='sync_filter',
                           label='Sync filter',
                           get_cmd='SYNC?',
                           set_cmd='SYNC {}',
                           val_mapping={
                               'OFF': 0,
                               'ON': 1
                           })
        self.add_parameter(name='noise_bandwidth',
                           label='Noise bandwidth',
                           unit='Hz',
                           get_cmd='ENBW?',
                           get_parser=float)
        self.add_parameter(name='signal_strength',
                           label='Signal strength indicator',
                           get_cmd='ILVL?',
                           get_parser=int)
        self.add_parameter(name='signal_input',
                           label='Signal input',
                           get_cmd='IVMD?',
                           get_parser=self._get_input_config,
                           set_cmd='IVMD {}',
                           set_parser=self._set_input_config,
                           vals=Enum(*self._INPUT_SIGNAL_TO_N.keys()))
        self.add_parameter(name='input_range',
                           label='Input range',
                           unit='V',
                           get_cmd='IRNG?',
                           set_cmd='IRNG {}',
                           val_mapping={
                               1: 0,
                               300e-3: 1,
                               100e-3: 2,
                               30e-3: 3,
                               10e-3: 4
                           })
        self.add_parameter(name='input_config',
                           label='Input configuration',
                           get_cmd='ISRC?',
                           set_cmd='ISRC {}',
                           val_mapping={
                               'a': 0,
                               'a-b': 1
                           })
        self.add_parameter(name='input_shield',
                           label='Input shield',
                           get_cmd='IGND?',
                           set_cmd='IGND {}',
                           val_mapping={
                               'float': 0,
                               'ground': 1
                           })
        self.add_parameter(name='input_gain',
                           label='Input gain',
                           unit='ohm',
                           get_cmd='ICUR?',
                           set_cmd='ICUR {}',
                           val_mapping={
                               1e6: 0,
                               100e6: 1
                           })
        self.add_parameter(name='adv_filter',
                           label='Advanced filter',
                           get_cmd='ADVFILT?',
                           set_cmd='ADVFILT {}',
                           val_mapping={
                               'OFF': 0,
                               'ON': 1
                           })
        self.add_parameter(name='input_coupling',
                           label='Input coupling',
                           get_cmd='ICPL?',
                           set_cmd='ICPL {}',
                           val_mapping={
                               'ac': 0,
                               'dc': 1
                           })
        self.add_parameter(name='time_constant',
                           label='Time constant',
                           unit='s',
                           get_cmd='OFLT?',
                           set_cmd='OFLT {}',
                           val_mapping={
                               1e-6: 0,
                               3e-6: 1,
                               10e-6: 2,
                               30e-6: 3,
                               100e-6: 4,
                               300e-6: 5,
                               1e-3: 6,
                               3e-3: 7,
                               10e-3: 8,
                               30e-3: 9,
                               100e-3: 10,
                               300e-3: 11,
                               1: 12,
                               3: 13,
                               10: 14,
                               30: 15,
                               100: 16,
                               300: 17,
                               1e3: 18,
                               3e3: 19,
                               10e3: 20,
                               30e3: 21
                           })

        self.add_parameter(
            name="external_reference_trigger",
            label="External reference trigger mode",
            get_cmd="RTRG?",
            set_cmd="RTRG {}",
            val_mapping={
                "SIN": 0,
                "POS": 1,
                "POSTTL": 1,
                "NEG": 2,
                "NEGTTL": 2,
            },
            docstring="The triggering mode for synchronization of the "
            "internal reference signal with the externally provided "
            "one")

        self.add_parameter(name="reference_source",
                           label="Reference source",
                           get_cmd="RSRC?",
                           set_cmd="RSRC {}",
                           val_mapping={
                               "INT": 0,
                               "EXT": 1,
                               "DUAL": 2,
                               "CHOP": 3
                           },
                           docstring="The source of the reference signal")

        self.add_parameter(
            name="external_reference_trigger_input_resistance",
            label="External reference trigger input resistance",
            get_cmd="REFZ?",
            set_cmd="REFZ {}",
            val_mapping={
                "50": 0,
                "50OHMS": 0,
                0: 0,
                "1M": 1,
                "1MEG": 1,
                1: 1,
            },
            docstring="Input resistance of the input for the external "
            "reference signal")

        # Auto functions
        self.add_function('auto_range', call_cmd='ARNG')
        self.add_function('auto_scale', call_cmd='ASCL')
        self.add_function('auto_phase', call_cmd='APHS')

        # Data transfer
        # first 4 parameters from a list of 16 below.
        self.add_parameter('X',
                           label='In-phase Magnitude',
                           get_cmd='OUTP? 0',
                           get_parser=float,
                           unit='V')
        self.add_parameter('Y',
                           label='Out-phase Magnitude',
                           get_cmd='OUTP? 1',
                           get_parser=float,
                           unit='V')
        self.add_parameter('R',
                           label='Magnitude',
                           get_cmd='OUTP? 2',
                           get_parser=float,
                           unit='V')
        self.add_parameter('P',
                           label='Phase',
                           get_cmd='OUTP? 3',
                           get_parser=float,
                           unit='deg')

        # CH1/CH2 Output Commands
        self.add_parameter('X_offset',
                           label='X offset ',
                           unit='%',
                           get_cmd='COFP? 0',
                           set_cmd='COFP 0, {}',
                           get_parser=float,
                           vals=Numbers(min_value=-999.99, max_value=999.99))
        self.add_parameter('Y_offset',
                           label='Y offset',
                           unit='%',
                           get_cmd='COFP? 1',
                           set_cmd='COFP 1, {}',
                           get_parser=float,
                           vals=Numbers(min_value=-999.99, max_value=999.99))
        self.add_parameter('R_offset',
                           label='R offset',
                           unit='%',
                           get_cmd='COFP? 2',
                           set_cmd='COFP 2, {}',
                           get_parser=float,
                           vals=Numbers(min_value=-999.99, max_value=999.99))
        self.add_parameter('X_expand',
                           label='X expand multiplier',
                           get_cmd='CEXP? 0',
                           set_cmd='CEXP 0, {}',
                           val_mapping={
                               'OFF': '0',
                               'X10': '1',
                               'X100': '2'
                           })
        self.add_parameter('Y_expand',
                           label='Y expand multiplier',
                           get_cmd='CEXP? 1',
                           set_cmd='CEXP 1, {}',
                           val_mapping={
                               'OFF': 0,
                               'X10': 1,
                               'X100': 2
                           })
        self.add_parameter('R_expand',
                           label='R expand multiplier',
                           get_cmd='CEXP? 2',
                           set_cmd='CEXP 2, {}',
                           val_mapping={
                               'OFF': 0,
                               'X10': 1,
                               'X100': 2
                           })

        # Aux input/output
        for i in [0, 1, 2, 3]:
            self.add_parameter(f'aux_in{i}',
                               label=f'Aux input {i}',
                               get_cmd=f'OAUX? {i}',
                               get_parser=float,
                               unit='V')
            self.add_parameter(f'aux_out{i}',
                               label=f'Aux output {i}',
                               get_cmd=f'AUXV? {i}',
                               get_parser=float,
                               set_cmd=f'AUXV {i}, {{}}',
                               unit='V')

        # Data channels:
        # 'DAT1' (green), 'DAT2' (blue), 'DAT3' (yellow), 'DAT4' (orange)
        data_channels = ChannelList(self,
                                    "data_channels",
                                    SR86xDataChannel,
                                    snapshotable=False)
        for num, color in zip(range(self._N_DATA_CHANNELS),
                              ('green', 'blue', 'yellow', 'orange')):
            cmd_id = f"{num}"
            cmd_id_name = f"DAT{num + 1}"
            ch_name = f"data_channel_{num + 1}"

            data_channel = SR86xDataChannel(self, ch_name, cmd_id, cmd_id_name,
                                            color)

            data_channels.append(data_channel)
            self.add_submodule(ch_name, data_channel)

        data_channels.lock()
        self.add_submodule("data_channels", data_channels)

        # Interface
        self.add_function('reset', call_cmd='*RST')

        self.add_function('disable_front_panel', call_cmd='OVRM 0')
        self.add_function('enable_front_panel', call_cmd='OVRM 1')

        buffer = SR86xBuffer(self, f"{self.name}_buffer")
        self.add_submodule("buffer", buffer)

        self.input_config()
        self.connect_message()
Beispiel #15
0
    def __init__(self,
                 name: str,
                 address: str,
                 num_channels: int,
                 timeout: float = 10,
                 **kwargs) -> None:
        """
        Args:
            name: The name used internally by QCoDeS in the DataSet
            address: The VISA resource name of the instrument
            timeout: The VISA timeout time (in seconds)
            num_channels: Number of channels on the AWG
        """

        self.num_channels = num_channels

        super().__init__(name,
                         address,
                         timeout=timeout,
                         terminator='\n',
                         **kwargs)

        # The 'model' value begins with 'AWG'
        self.model = self.IDN()['model'][3:]

        if self.model not in ['70001A', '70002A', '5208']:
            raise ValueError('Unknown model type: {}. Are you using '
                             'the right driver for your instrument?'
                             ''.format(self.model))

        self.add_parameter('current_directory',
                           label='Current file system directory',
                           set_cmd='MMEMory:CDIRectory "{}"',
                           get_cmd='MMEMory:CDIRectory?',
                           vals=vals.Strings())

        self.add_parameter('mode',
                           label='Instrument operation mode',
                           set_cmd='INSTrument:MODE {}',
                           get_cmd='INSTrument:MODE?',
                           vals=vals.Enum('AWG', 'FGEN'))

        ##################################################
        # Clock parameters

        self.add_parameter('sample_rate',
                           label='Clock sample rate',
                           set_cmd='CLOCk:SRATe {}',
                           get_cmd='CLOCk:SRATe?',
                           unit='Sa/s',
                           get_parser=float,
                           vals=SRValidator(self))

        self.add_parameter('clock_source',
                           label='Clock source',
                           set_cmd='CLOCk:SOURce {}',
                           get_cmd='CLOCk:SOURce?',
                           val_mapping={
                               'Internal': 'INT',
                               'Internal, 10 MHZ ref.': 'EFIX',
                               'Internal, variable ref.': 'EVAR',
                               'External': 'EXT'
                           })

        self.add_parameter('clock_external_frequency',
                           label='External clock frequency',
                           set_cmd='CLOCk:ECLock:FREQuency {}',
                           get_cmd='CLOCk:ECLock:FREQuency?',
                           get_parser=float,
                           unit='Hz',
                           vals=vals.Numbers(6.25e9, 12.5e9))

        # We deem 2 channels too few for a channel list
        if self.num_channels > 2:
            chanlist = ChannelList(self,
                                   'Channels',
                                   AWGChannel,
                                   snapshotable=False)

        for ch_num in range(1, num_channels + 1):
            ch_name = 'ch{}'.format(ch_num)
            channel = AWGChannel(self, ch_name, ch_num)
            self.add_submodule(ch_name, channel)
            if self.num_channels > 2:
                chanlist.append(channel)

        if self.num_channels > 2:
            chanlist.lock()
            self.add_submodule('channels', chanlist)

        # Folder on the AWG where to files are uplaoded by default
        self.wfmxFileFolder = "\\Users\\OEM\\Documents"
        self.seqxFileFolder = "\\Users\\OEM\Documents"

        self.current_directory(self.wfmxFileFolder)

        self.connect_message()
Beispiel #16
0
    def __init__(self, name, address, update_currents=False, **kwargs):
        """
        Instantiates the instrument.

        Args:
            name (str): The instrument name used by qcodes
            address (str): The VISA name of the resource
            update_currents (bool): Whether to query all channels for their
                current sensor value on startup, which takes about 0.5 sec
                per channel. Default: False.

        Returns:
            QDac object
        """

        super().__init__(name, address, **kwargs)
        handle = self.visa_handle
        self._get_status_performed = False

        # Communication setup + firmware check
        handle.baud_rate = 480600
        handle.parity = visa.constants.Parity(0)
        handle.data_bits = 8
        self.set_terminator('\n')
        handle.write_termination = '\n'
        self._write_response = ''
        firmware_version = self._get_firmware_version()
        if firmware_version < 1.07:
            LOG.warning(f"Firmware version: {firmware_version}")
            raise RuntimeError('''
                No QDevil QDAC detected or the firmware version is obsolete.
                This driver only supports version 1.07 or newer. Please
                contact [email protected] for a firmware update.
                ''')

        # Initialse basic information and internal book keeping
        self.num_chans = self._get_number_of_channels()
        num_boards = int(self.num_chans / 8)
        self._output_n_lines = self.num_chans + 2
        self._chan_range = range(1, 1 + self.num_chans)
        self.channel_validator = vals.Ints(1, self.num_chans)
        self._reset_bookkeeping()

        # Add channels (and channel parameters)
        channels = ChannelList(self,
                               "Channels",
                               QDacChannel,
                               snapshotable=False,
                               multichan_paramclass=QDacMultiChannelParameter)

        for i in self._chan_range:
            channel = QDacChannel(self, f'chan{i:02}', i)
            channels.append(channel)
            self.add_submodule(f'ch{i:02}', channel)
        channels.lock()
        self.add_submodule('channels', channels)

        # Updatechannel  sync port validator according to number of boards
        self._num_syns = max(num_boards - 1, 1)
        for chan in self._chan_range:
            self.channels[chan - 1].sync.vals = vals.Ints(0, self._num_syns)

        # Add non-channel parameters
        for board in range(num_boards):
            for sensor in range(3):
                label = f'Board {board}, Temperature {sensor}'
                self.add_parameter(name=f'temp{board}_{sensor}',
                                   label=label,
                                   unit='C',
                                   get_cmd=f'tem {board} {sensor}',
                                   get_parser=self._num_verbose)

        self.add_parameter(name='cal',
                           set_cmd='cal {}',
                           vals=vals.Ints(0, self.num_chans))

        self.add_parameter(name='mode_force',
                           label='Mode force',
                           get_cmd=None,
                           set_cmd=None,
                           vals=vals.Bool(),
                           initial_value=False)

        # Due to a firmware bug in 1.07 voltage ranges are always reported
        # vebosely. So for future compatibility we set verbose True
        self.write('ver 1')
        self._update_voltage_ranges()
        # The driver require verbose mode off except for the above command
        self.write('ver 0')
        self._verbose = False  # Just so that the code can check the state
        self.connect_message()
        LOG.info('[*] Querying all channels for voltages and currents...')
        self._update_cache(update_currents=update_currents)
        self._update_currents = update_currents
        self._load_state()
        LOG.info('[+] Done')
    def __init__(self, name, address, silent=False, **kwargs):
        """
        Args:
            name (string): The name of the instrument used internally
                by QCoDeS. Must be unique.
            address (string): The VISA resource name.
            silent (Optional[bool]): If True, no connect message is printed.
        """

        super().__init__(name, address, **kwargs)

        def errorparser(rawmssg):
            """
            Parses the error message.

            Args:
                rawmssg (str): The raw return value of 'SYSTem:ERRor?'

            Returns:
                tuple (int, str): The error code and the error message.
            """
            code = int(rawmssg.split(',')[0])
            mssg = rawmssg.split(',')[1].strip().replace('"', '')

            return code, mssg

        channels = ChannelList(self,
                               "Channels",
                               KeysightChannel,
                               snapshotable=False)
        for i in range(1, 3):
            channel = KeysightChannel(self, 'ch{}'.format(i), i)
            channels.append(channel)
        channels.lock()
        self.add_submodule('channels', channels)

        self.add_parameter('sync_source',
                           label='Source of sync function',
                           set_cmd='OUTPut:SYNC:SOURce {}',
                           get_cmd='OUTPut:SYNC:SOURce?',
                           val_mapping={
                               1: 'CH1',
                               2: 'CH2'
                           },
                           vals=vals.Enum(1, 2))

        self.add_parameter('sync_output',
                           label='Sync output state',
                           set_cmd='OUTPut:SYNC {}',
                           get_cmd='OUTPut:SYNC?',
                           val_mapping={
                               'ON': 1,
                               'OFF': 0
                           },
                           vals=vals.Enum('ON', 'OFF'))

        self.add_parameter('error',
                           label='Error message',
                           get_cmd='SYSTem:ERRor?',
                           get_parser=errorparser)

        self.add_function('force_trigger', call_cmd='*TRG')

        self.add_function('sync_channel_phases', call_cmd='PHAS:SYNC')

        if not silent:
            self.connect_message()
Beispiel #18
0
    def __init__(self, name, address, timeout=2, **kwargs):
        """
        Initialises the Rigol DS1000
        
        Args:
            name (str) of the instrument
            address (string) Visa address for the instrument
            timeout (float) visa timeout
        """
        super().__init__(name, address, device_clear=False, timeout=timeout, **kwargs)
        self.connect_message()

        # functions
        self.add_function('run',
                          call_cmd=':RUN',
                          docstring='Start acquisition')
        self.add_function('stop',
                          call_cmd=':STOP',
                          docstring='Stop acquisition')
        self.add_function('single',
                          call_cmd=':SINGle',
                          docstring='Single trace acquisition')
        self.add_function('force_trigger',
                          call_cmd='TFORce',
                          docstring='Force trigger event')

        #acquire mode parameters
        self.add_parameter("acquire_type",
                label='type of aquire being used by oscilloscope',
                get_cmd=':ACQ:TYPE?',
                set_cmd='ACQ:TYPE {}',
                vals=vals.Enum('NORMAL', 'AVERAGE', 'PEAKDETECT'))
        self.add_parameter("acquire_mode",
                label="mode of aquisition being used by oscillioscope",
                get_cmd=':ACQ:MODE?',
                set_cmd=':ACQ:MODE {}',
                vals = vals.Enum('RTIM', 'ETIM')
                )
        self.add_parameter("acquire_averages",
                label="the average number in averages mode",
                get_cmd=':ACQ:AVER?',
                set_cmd=':ACQ:AVER {}',
                vals=vals.Enum('2', '4', '8', '16', '32', '64', '128', '256'))
        #note to self: aquire sampling rate parameters to go under channel class
        self.add_parameter("acquire_mem_depth",
                label='depth of memory being used by oscilloscope',
                get_cmd=':ACQ:MEMDepth?',
                set_cmd=':ACQ:MEMDepth {}',
                vals = vals.Enum('LONG', 'NORM'))

        #display parameters
        self.add_parameter("display_type",
                label='display type between samples, either vector or dot',
                get_cmd=':DISP:TYPE?',
                set_cmd=':DISP:TYPE {}',
                vals = vals.Enum('VECT', 'DOTS'))
        self.add_parameter("display_grid",
                label='controls/queries if the oscilloscope display has a grid',
                get_cmd=':DISP:GRID?',
                set_cmd=':DISP:GRID {}',
                vals = vals.Enum('FULL', 'HALF', 'NONE'))
        self.add_parameter("display_persist",
                label="controls/queries if the waveform record point persists or refreshes",
                get_cmd=':DISP:PERS?',
                set_cmd=':DiSP:PERS {}',
                vals = vals.Enum('ON', 'OFF'))
        self.add_parameter("display_mnud",
                label="timing for menus hiding automatically",
                get_cmd=':DISP:MNUD?',
                set_cmd=':DISP:MNUD {}',
                vals = vals.Enum('1', '2', '5', '10', '20', 'Infinite')
                )
        self.add_parameter("display_mnus",
                label="status of the menus",
                get_cmd=':DISP:MNUS?',
                set_cmd=':DISP:MNUS {}',
                vals = vals.Enum('ON', 'OFF'))
        #note to self - add display clear parameter
        self.add_parameter("display_brightness",
                label="set and get the brightness of the grid for the oscilloscope",
                get_cmd=':DISP:BRIG?',
                set_cmd=':DISP:BRIG {}',
                get_parser=int,
                vals=vals.Ints(0,32))
        self.add_parameter("display_intensity",
                label="set the brightness of the waveform",
                get_cmd=':DISP:INT?',
                set_cmd=':DISP:INT {}',
                get_parser=int,
                vals=vals.Ints(0,32))

        # Channel parameters
        channels = ChannelList(self, "Channels", RigolDS1000Channel, snapshotable=False)

        for channel_number in [1, 2]:
            channel = RigolDS1000Channel(self, "ch{}".format(channel_number), channel_number)
            channels.append(channel)

        for channel_number in ['MATH', 'FFT']:
            channel = RigolDS1000Channel(self, "ch_{}".format(channel_number), channel_number)
            channels.append(channel)

        channels.lock()
        self.add_submodule('channels', channels)

        #timebase parameters
        self.add_parameter("time_base_mode",
                label="the scan mode of the horizontal time base",
                get_cmd=":TIM:MODE?",
                set_cmd=":TIM:MODE {}",
                vals = vals.Enum('MAIN', 'DEL'))
        #note to self, decide how to deal with timebase offset parameter.
        self.add_parameter("time_base_offset",
                label="controls the main and delayed mode offset",
                get_cmd=":TIM:OFFS?",
                set_cmd=":TIM:OFFS {}",
                get_parser=float,
                unit="s")
        
        self.add_parameter("time_base_scale",
                label="the scale of the horizontal time base",
                get_cmd=":TIM:SCAL?",
                set_cmd=":TIM:SCAL {}",
                get_parser=float,
                unit="s/div")
        self.add_parameter("time_base_format",
                label="the format of the time base",
                get_cmd=":TIM:FORM?",
                set_cmd=":TIM:FORM {}",
                vals=vals.Enum('X-Y', 'Y-T', 'SCANNING')
                )
        #trigger commands
        self.add_parameter("trigger_mode",
                label="sets and queries the trigger mode",
                get_cmd=":TRIG:MODE?",
                set_cmd=":TRIG:MODE {}",
                vals = vals.Enum('EDGE', 'PULSE', 'VIDEO', 'SLOPE',
                    'PATTERN','DURATION', 'ALTERNATION')
                )
        self.add_parameter("trigger_source",
                label="sets and queries the trigger source",
                get_cmd = ":TRIG:{}:SOUR?".format(self.trigger_mode()),
                set_cmd = ":TRIG:{}:SOUR {}".format(self.trigger_mode(), "{}")
                #get_cmd = self.source_get_cmd,
                #set_cmd = self.source_set_cmd,
                )
        self.add_parameter("trigger_level",
                label="sets and queries the trigger level",
                get_cmd=":TRIG:{}:LEV?".format(self.trigger_mode()),
                set_cmd=":TRIG:{}:LEV {}".format(self.trigger_mode(), "{}"),
                #get_cmd = self.level_get_cmd,
                get_parser = float,
                #set_cmd = self.level_set_cmd,
                unit = "V"
                #vals = vals.permissiveInts(-6*#vertical scale, 6*#vertical scale())
                )
        self.add_parameter("trigger_sweep",
                label="sets and queries the trigger sweep",
                get_cmd =":TRIG:{}:SWE?".format(self.trigger_mode()),
                set_cmd =":TRIG:{}:SWE {}".format(self.trigger_mode(), "{}"),
                #get_cmd = self.sweep_get_cmd,
                #set_cmd = self.sweep_set_cmd,
                vals = vals.Enum("AUTO","NORM","SING")
                )
        self.add_parameter("trigger_coupling",
                label="sets and queries the coupling",
                get_cmd = ":TRIG:{}:COUP?".format(self.trigger_mode()),
                set_cmd = ":TRIG:{}:COUP {}".format(self.trigger_mode(), "{}"),
                vals = vals.Enum("DC","AC","HF","LF")
                )
        self.add_parameter("trigger_holdoff",
                label="sets and queries the trigger holdoff",
                get_cmd = ":TRIG:HOLD?",
                set_cmd = ":TRIG:HOLD {}",
                get_parser = float,
                unit = 's'
               )

        # Waveform
        self.add_parameter("waveform_points_mode",
                   label="Number of the waveform points",
                   get_cmd=":WAVEFORM:POINTS:MODE?",
                   set_cmd=":WAVEFORM:POINTS:MODE {}",
                   vals = vals.Enum("NORM","MAX","RAW"),
                   get_parser=str,
                  )
Beispiel #19
0
    def __init__(self,name:str,
                      address:str,
                      num_chans:int=16,
                      init_start:bool=False,
                      synchronous_enable:bool=True,
                      synchronous_delay:float=1,
                      synchronous_threshold:float=1e-5,
                      **kwargs: Any) -> None:
        """
        Instantiate the instrument.

        Args:
            name: The instrument name used by qcodes
            address: The VISA name of the resource
            num_chans: Number of channels to assign. Default: 16
            init_start: If true set all channels to 0V, 1.2V range and switch
                then on.
            synchronous_enable: If true, block the communication until the set voltage
                is reached. The communication is block through a simple while loop
                with a waiting time "synchronous_delay" at each iteration until the
                set voltage and the measured voltage difference is below
                "synchronous_threshold".
            synchronous_delay: Time between to voltage measurement in second.
            synchronous_threshold: Threshold to unblock communication in volt.

        Returns:
            ITest object
        """
        super().__init__(name, address=address,
                               terminator='\n',
                               device_clear=False,
                               **kwargs)

        self.idn = self.get_idn()
        self.num_chans = num_chans
        self.chan_range = range(1,self.num_chans+1)

        # Create the channels
        channels = ChannelList(parent=self,
                               name='Channels',
                               chan_type=iTestChannel,
                               multichan_paramclass=iTestMultiChannelParameter)

        for i in self.chan_range:

            channel = iTestChannel(self, name='chan{:02}'.format(i),
                                         chan_num=i)
            channel.synchronous_enable(synchronous_enable)
            channel.synchronous_delay(synchronous_delay)
            channel.synchronous_threshold(synchronous_threshold)
            channels.append(channel)
            self.add_submodule('ch{:02}'.format(i),channel)

        channels.lock()
        self.add_submodule('channels',channels)

        if init_start:
            for channel in self.channels:
                channel.v.set(0)
                channel.v_range(1.2)
                channel.start()

        self.connect_message()
Beispiel #20
0
    def _connect(self) -> None:
        """Connects the device to the data server.

        Instantiates the device controller from :mod:`zhinst-toolkit`, sets up 
        the data server and connects the device the data server. This method is 
        called from `__init__` of the :class:`BaseInstrument` class.

        """
        self._controller = tk.UHFQA(
            self._name,
            self._serial,
            interface=self._interface,
            host=self._host,
            port=self._port,
            api=self._api,
        )
        self._controller.setup()
        self._controller.connect_device(nodetree=False)
        self.connect_message()
        self._get_nodetree_dict()
        # init submodules for ReadoutChannels and AWG
        channel_list = ChannelList(self, "channels", Channel)
        for i in range(10):
            channel_list.append(Channel(f"ch-{i}", i, self, self._controller))
        channel_list.lock()
        self.add_submodule("channels", channel_list)
        self.add_submodule("awg", AWG("awg", self, self._controller))
        # add custom parameters as QCoDeS parameters
        self.add_parameter(
            "crosstalk_matrix",
            docstring=
            "The 10x10 crosstalk suppression matrix that multiplies the 10 signal paths. Can be set only partially.",
            get_cmd=self._controller.crosstalk_matrix,
            set_cmd=self._controller.crosstalk_matrix,
            label="Crosstalk Matrix",
        )
        sources = [
            "Crosstalk",
            "Integration",
            "Threshold",
            "Crosstalk Correlation",
            "Threshold Correlation",
            "Rotation",
        ]
        self.add_parameter(
            "result_source",
            docstring=
            f"The signal source for QA Results. Has to be one of {sources}.",
            get_cmd=self._controller.result_source,
            set_cmd=self._controller.result_source,
            label="Result Source",
            vals=vals.Enum(*sources),
        )
        self.add_parameter(
            "integration_time",
            docstring=
            "The integration time used for demodulation in seconds. Can be up to 2.27 us when using weighted integration and up to 50 us in spectroscopy mode.",
            get_cmd=self._controller.integration_time,
            set_cmd=self._controller.integration_time,
            label="Integration Time",
            vals=vals.Numbers(0, 50e-6),
        )
        self.add_parameter(
            "averaging_mode",
            docstring=self._controller.averaging_mode._description,
            get_cmd=self._controller.averaging_mode,
            set_cmd=self._controller.averaging_mode,
            label="Averaging Mode",
            vals=vals.Enum("Cyclic", "Sequential"),
        )