Beispiel #1
0
    def __init__(self, parent: 'Model_325', index: int) -> None:

        self._index = index
        name = f"curve_{index}"
        super().__init__(parent, name)

        self.add_parameter("serial_number", parameter_class=GroupParameter)

        self.add_parameter("format",
                           val_mapping={
                               f"{unt}/K": i + 1
                               for i, unt in enumerate(self.valid_sensor_units)
                           },
                           parameter_class=GroupParameter)

        self.add_parameter("limit_value", parameter_class=GroupParameter)

        self.add_parameter("coefficient",
                           val_mapping={
                               "negative": 1,
                               "positive": 2
                           },
                           parameter_class=GroupParameter)

        self.add_parameter("curve_name", parameter_class=GroupParameter)

        Group([
            self.curve_name, self.serial_number, self.format, self.limit_value,
            self.coefficient
        ],
              set_cmd=f"CRVHDR {self._index}, {{curve_name}}, "
              f"{{serial_number}}, {{format}}, {{limit_value}}, "
              f"{{coefficient}}",
              get_cmd=f"CRVHDR? {self._index}")
Beispiel #2
0
    def __init__(self,
                 name: str,
                 initial_a: Optional[int] = None,
                 initial_b: Optional[int] = None,
                 scale_a: Optional[float] = None,
                 get_cmd: Optional[str] = "CMD?") -> None:
        super().__init__(name)

        self._a = 0
        self._b = 0
        self._get_cmd = get_cmd

        self.add_parameter("a",
                           get_parser=int,
                           parameter_class=GroupParameter,
                           docstring="Some succinct description",
                           label="label",
                           unit="SI",
                           initial_value=initial_a,
                           scale=scale_a)

        self.add_parameter("b",
                           get_parser=int,
                           parameter_class=GroupParameter,
                           docstring="Some succinct description",
                           label="label",
                           unit="SI",
                           initial_value=initial_b)

        self.group = Group([self.a, self.b],
                           set_cmd="CMD {a}, {b}",
                           get_cmd=get_cmd)
    def __init__(self, parent, name, channel):
        super().__init__(parent, name, channel)

        # Parameters related to Input Type Parameter Command (INTYPE)
        self.add_parameter('sensor_type',
                           label='Input sensor type',
                           docstring='Specifies input sensor type',
                           val_mapping={'disabled': 0,
                                        'diode': 1,
                                        'platinum_rtd': 2,
                                        'ntc_rtd': 3},
                           parameter_class=GroupParameter)
        self.add_parameter('auto_range_enabled',
                           label='Autoranging',
                           docstring='Specifies if autoranging is enabled. '
                                     'Does not apply for diode sensor type',
                           val_mapping={False: 0, True: 1},
                           parameter_class=GroupParameter)
        self.add_parameter('range',
                           label='Range',
                           docstring='Specifies input range when autorange is '
                                     'not enabled. If autorange is on, the '
                                     'returned value corresponds to the '
                                     'currently auto-selected range. The list '
                                     'of available ranges depends on the '
                                     'chosen sensor type: diode 0-1, platinum '
                                     'RTD 0-6, NTC RTD 0-8. Refer to the page '
                                     '136 of the manual for the lookup table',
                           vals=vals.Numbers(0, 8),
                           parameter_class=GroupParameter)
        self.add_parameter('compensation_enabled',
                           label='Compensation enabled',
                           docstring='Specifies input compensation. Reversal '
                                     'for thermal EMF compensation if input '
                                     'is resistive, room compensation if '
                                     'input is thermocouple. Always 0 if input '
                                     'is a diode',
                           val_mapping={False: 0, True: 1},
                           parameter_class=GroupParameter)
        self.add_parameter('units',
                           label='Preferred units',
                           docstring='Specifies the preferred units parameter '
                                     'for sensor readings and for the control '
                                     'setpoint (kelvin, celsius, or sensor)',
                           val_mapping={'kelvin': 1, 'celsius': 2, 'sensor': 3},
                           parameter_class=GroupParameter)
        self.output_group = Group([self.sensor_type, self.auto_range_enabled,
                                   self.range, self.compensation_enabled,
                                   self.units],
                                  set_cmd=f'INTYPE {self._channel}, '
                                          f'{{sensor_type}}, '
                                          f'{{auto_range_enabled}}, {{range}}, '
                                          f'{{compensation_enabled}}, '
                                          f'{{units}}',
                                  get_cmd=f'INTYPE? {self._channel}')
Beispiel #4
0
    def __init__(self, name, address='192.168.1.152', port=4266, timeout=5, *args, **kwargs):
        super().__init__(name, address, port, timeout, *args, **kwargs)

        self.add_parameter('setpoint',
                           label='Pressure setpoint',
                           unit='psi',
                           get_cmd='PSET?',
                           set_cmd=f'PSET {{}}',
                           vals=vals.Numbers(0.15, 14.25),
                           get_parser=lambda resp: resp.replace(' PSI\r\n', ''))

        self.add_parameter('heater_limit',
                           label='Heater limit',
                           unit='W',
                           get_cmd='HLIM?',
                           set_cmd=f'HLIM {{}}',
                           vals=vals.Numbers(0.1, 10),
                           get_parser=lambda resp: resp.replace(' Watts\r\n', ''))

        self.add_parameter('heater_enabled',
                           label='Heater enabled',
                           get_cmd='HEAT?',
                           set_cmd=f'HEAT {{}}',
                           vals=vals.Enum('ON', 'OFF'),
                           get_parser=lambda resp: resp.replace('\r\n', '')
                           )

        self.chan = 2
        self.add_parameter('channel',
                           label='Channel',
                           docstring='Channel for measuring.',
                           set_cmd=self.set_channel,
                           get_cmd=self.get_channel,
                           vals=vals.Ints(1, 2))

        self.add_parameter('pressure',
                           label='Pressure',
                           unit='psi',
                           parameter_class=GroupParameter)

        self.add_parameter('heater_output',
                           label='Heater output',
                           unit='W',
                           parameter_class=GroupParameter)

        self.measure_group = Group([self.pressure, self.heater_output],
                                   get_cmd=f'MEAS? {self.chan}',
                                   get_parser=self._measure)

        self.connect_message()
Beispiel #5
0
    def __init__(self, parent, output_name, output_index) -> None:
        super().__init__(parent, output_name, output_index, has_pid=True)

        # Add more parameters for OUTMODE command
        # and redefine the corresponding group
        self.add_parameter('polarity',
                           label='Output polarity',
                           docstring='Specifies output polarity (not '
                           'applicable to warm-up heater)',
                           val_mapping=self.POLARITIES,
                           parameter_class=GroupParameter)
        self.add_parameter('use_filter',
                           label='Use filter for readings',
                           docstring='Specifies controlling on unfiltered or '
                           'filtered readings',
                           val_mapping={
                               True: 1,
                               False: 0
                           },
                           parameter_class=GroupParameter)
        self.add_parameter('delay',
                           label='Delay',
                           unit='s',
                           docstring='Delay in seconds for setpoint change '
                           'during Autoscanning',
                           vals=vals.Ints(0, 255),
                           get_parser=int,
                           parameter_class=GroupParameter)
        self.output_group = Group([
            self.mode, self.input_channel, self.powerup_enable, self.polarity,
            self.use_filter, self.delay
        ],
                                  set_cmd=f'OUTMODE {output_index}, {{mode}}, '
                                  f'{{input_channel}}, '
                                  f'{{powerup_enable}}, {{polarity}}, '
                                  f'{{use_filter}}, {{delay}}',
                                  get_cmd=f'OUTMODE? {output_index}')
        self.add_parameter('still',
                           label='Still output',
                           docstring='Specifies heater output in percent '
                           'for heater set to still mode.',
                           vals=vals.Numbers(0, 100),
                           get_cmd='STILL?',
                           set_cmd=self.set_still)

        self.P.vals = vals.Numbers(0.0, 1000)
        self.I.vals = vals.Numbers(0.0, 10000)
        self.D.vals = vals.Numbers(0, 2500)
Beispiel #6
0
    def __init__(self, parent: 'Model_325', name: str, inp: str) -> None:

        if inp not in ["A", "B"]:
            raise ValueError("Please either specify input 'A' or 'B'")

        super().__init__(parent, name)
        self._input = inp

        self.add_parameter('temperature',
                           get_cmd=f'KRDG? {self._input}',
                           get_parser=float,
                           label='Temperature',
                           unit='K')

        self.add_parameter(
            'status',
            get_cmd=f'RDGST? {self._input}',
            get_parser=lambda status: self.decode_sensor_status(int(status)),
            label='Sensor_Status')

        self.add_parameter("type",
                           val_mapping={
                               "Silicon diode": 0,
                               "GaAlAs diode": 1,
                               "100 Ohm platinum/250": 2,
                               "100 Ohm platinum/500": 3,
                               "1000 Ohm platinum": 4,
                               "NTC RTD": 5,
                               "Thermocouple 25mV": 6,
                               "Thermocouple 50 mV": 7,
                               "2.5 V, 1 mA": 8,
                               "7.5 V, 1 mA": 9
                           },
                           parameter_class=GroupParameter)

        self.add_parameter("compensation",
                           vals=Enum(0, 1),
                           parameter_class=GroupParameter)

        Group([self.type, self.compensation],
              set_cmd=f"INTYPE {self._input}, {{type}}, {{compensation}}",
              get_cmd=f"INTYPE? {self._input}")

        self.add_parameter("curve_index",
                           set_cmd=f"INCRV {self._input}, {{}}",
                           get_cmd=f"INCRV? {self._input}",
                           get_parser=int,
                           vals=Numbers(min_value=1, max_value=35))
Beispiel #7
0
    def __init__(self, name: str) -> None:
        super().__init__(name)

        self._a = 0
        self._b = 0

        self.add_parameter("a",
                           get_parser=int,
                           parameter_class=GroupParameter,
                           docstring="Some succinct description",
                           label="label",
                           unit="SI")

        self.add_parameter("b",
                           get_parser=int,
                           parameter_class=GroupParameter,
                           docstring="Some succinct description",
                           label="label",
                           unit="SI")

        Group([self.a, self.b], set_cmd="CMD {a}, {b}", get_cmd="CMD?")
Beispiel #8
0
    def __init__(self, parent: 'B1520A', name: str, **kwargs: Any):
        super().__init__(parent, name, **kwargs)

        self.add_parameter(name='sweep_auto_abort',
                           set_cmd=self._set_sweep_auto_abort,
                           set_parser=constants.Abort,
                           vals=vals.Enum(*list(constants.Abort)),
                           get_cmd=None,
                           docstring=textwrap.dedent("""
                           enables or disables the automatic abort function 
                           for the CV (DC bias) sweep measurement (MM18) and 
                           the pulsed bias sweep measurement (MM20). The 
                           automatic abort function stops the measurement 
                           when one of the following conditions occurs:
                               - NULL loop unbalance condition
                               - IV amplifier saturation condition
                               - Overflow on the AD converter
                           """))
        self.sweep_auto_abort.cache.set(constants.Abort.ENABLED)

        self.add_parameter(name='post_sweep_voltage_condition',
                           set_cmd=self._set_post_sweep_voltage_condition,
                           set_parser=constants.WMDCV.Post,
                           vals=vals.Enum(*list(constants.WMDCV.Post)),
                           get_cmd=None,
                           docstring=textwrap.dedent("""
                           This command also sets the post measurement 
                           condition of the MFCMU. After the measurement is 
                           normally completed, the DC bias sweep source 
                           forces the value specified by the post parameter, 
                           and the pulsed bias sweep source forces 
                           the pulse base value.
                           If the measurement is stopped by the automatic  
                           abort function, the DC bias sweep source forces 
                           the start value, and the pulsed bias sweep source 
                           forces the pulse base value after sweep.
                           """))
        self.post_sweep_voltage_condition.cache.set(constants.WMDCV.Post.START)

        self.add_parameter(name='hold',
                           initial_value=0,
                           vals=vals.Numbers(0, 655.35),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Hold time (in seconds) that is the 
                           wait time after starting measurement 
                           and before starting delay time for 
                           the first step 0 to 655.35, with 10 
                           ms resolution. Numeric expression.
                          """))

        self.add_parameter(name='delay',
                           initial_value=0,
                           vals=vals.Numbers(0, 65.535),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Delay time (in seconds) that is the wait time after
                           starting to force a step output and before 
                            starting a step measurement. 0 to 65.535, 
                            with 0.1 ms resolution. Numeric expression.
                            """))

        self.add_parameter(name='step_delay',
                           initial_value=0,
                           vals=vals.Numbers(0, 1),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                            Step delay time (in seconds) that is the wait time
                            after starting a step measurement and before  
                            starting to force the next step output. 0 to 1, 
                            with 0.1 ms resolution. Numeric expression. If 
                            this parameter is not set, step delay will be 0. If 
                            step delay is shorter than the measurement time, 
                            the B1500 waits until the measurement completes, 
                            then forces the next step output.
                            """))

        self.add_parameter(name='trigger_delay',
                           initial_value=0,
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                            Step source trigger delay time (in seconds) that
                            is the wait time after completing a step output 
                            setup and before sending a step output setup 
                            completion trigger. 0 to the value of ``delay``, with 0.1 ms 
                            resolution. Numeric expression. If this
                            parameter is not set, trigger delay will be 0.
                            """))

        self.add_parameter(name='measure_delay',
                           initial_value=0,
                           unit='s',
                           vals=vals.Numbers(0, 65.535),
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Step measurement trigger delay time (in seconds)
                           that is the wait time after receiving a start step 
                           measurement trigger and before starting a step 
                           measurement. 0 to 65.535, with 0.1 ms resolution. 
                           Numeric expression. If this parameter is not set, 
                           measure delay will be 0.
                           """))

        self._set_sweep_delays_group = Group(
            [
                self.hold, self.delay, self.step_delay, self.trigger_delay,
                self.measure_delay
            ],
            set_cmd='WTDCV '
            '{hold},'
            '{delay},'
            '{step_delay},'
            '{trigger_delay},'
            '{measure_delay}',
            get_cmd=self._get_sweep_delays(),
            get_parser=self._get_sweep_delays_parser)
Beispiel #9
0
    def __init__(self,
                 parent: "LakeshoreBase",
                 output_name: str,
                 output_index: int,
                 has_pid: bool = True):
        super().__init__(parent, output_name)

        self.INVERSE_RANGES: Dict[int, str] = {
            v: k
            for k, v in self.RANGES.items()
        }

        self._has_pid = has_pid
        self._output_index = output_index

        self.add_parameter('mode',
                           label='Control mode',
                           docstring='Specifies the control mode',
                           val_mapping=self.MODES,
                           parameter_class=GroupParameter)
        self.add_parameter('input_channel',
                           label='Input channel',
                           docstring='Specifies which measurement input to '
                           'control from (note that only '
                           'measurement inputs are available)',
                           parameter_class=GroupParameter,
                           **self._input_channel_parameter_kwargs)
        self.add_parameter('powerup_enable',
                           label='Power-up enable on/off',
                           docstring='Specifies whether the output remains on '
                           'or shuts off after power cycle.',
                           val_mapping={
                               True: 1,
                               False: 0
                           },
                           parameter_class=GroupParameter)
        self.output_group = Group(
            [self.mode, self.input_channel, self.powerup_enable],
            set_cmd=f'OUTMODE {output_index}, {{mode}}, '
            f'{{input_channel}}, '
            f'{{powerup_enable}}',
            get_cmd=f'OUTMODE? {output_index}')

        # Parameters for Closed Loop PID Parameter Command
        if self._has_pid:
            self.add_parameter('P',
                               label='Proportional (closed-loop)',
                               docstring='The value for closed control loop '
                               'Proportional (gain)',
                               vals=vals.Numbers(0, 1000),
                               get_parser=float,
                               parameter_class=GroupParameter)
            self.add_parameter('I',
                               label='Integral (closed-loop)',
                               docstring='The value for closed control loop '
                               'Integral (reset)',
                               vals=vals.Numbers(0, 1000),
                               get_parser=float,
                               parameter_class=GroupParameter)
            self.add_parameter('D',
                               label='Derivative (closed-loop)',
                               docstring='The value for closed control loop '
                               'Derivative (rate)',
                               vals=vals.Numbers(0, 1000),
                               get_parser=float,
                               parameter_class=GroupParameter)
            self.pid_group = Group([self.P, self.I, self.D],
                                   set_cmd=f'PID {output_index}, '
                                   f'{{P}}, {{I}}, {{D}}',
                                   get_cmd=f'PID? {output_index}')

        self.add_parameter(
            'output_range',
            label='Heater range',
            docstring='Specifies heater output range. The range '
            'setting has no effect if an output is in '
            'the `Off` mode, and does not apply to '
            'an output in `Monitor Out` mode. '
            'An output in `Monitor Out` mode is '
            'always on.',
            val_mapping=self.RANGES,
            set_cmd=f'RANGE {output_index}, {{}}',
            get_cmd=f'RANGE? {output_index}')

        self.add_parameter('output',
                           label='Output',
                           unit='% of heater range',
                           docstring='Specifies heater output in percent of '
                           'the current heater output range.\n'
                           'Note that when the heater is off, '
                           'this parameter will return the value '
                           'of 0.005.',
                           get_parser=float,
                           get_cmd=f'HTR? {output_index}',
                           set_cmd=False)

        self.add_parameter('setpoint',
                           label='Setpoint value (in sensor units)',
                           docstring='The value of the setpoint in the '
                           'preferred units of the control loop '
                           'sensor (which is set via '
                           '`input_channel` parameter)',
                           vals=vals.Numbers(0, 400),
                           get_parser=float,
                           set_cmd=f'SETP {output_index}, {{}}',
                           get_cmd=f'SETP? {output_index}')

        # Additional non-Visa parameters

        self.add_parameter('range_limits',
                           set_cmd=None,
                           get_cmd=None,
                           vals=vals.Sequence(vals.Numbers(0, 400),
                                              require_sorted=True,
                                              length=len(self.RANGES) - 1),
                           label='Temperature limits for output ranges',
                           unit='K',
                           docstring='Use this parameter to define which '
                           'temperature corresponds to which output '
                           'range; then use the '
                           '`set_range_from_temperature` method to '
                           'set the output range via temperature '
                           'instead of doing it directly')

        self.add_parameter('wait_cycle_time',
                           set_cmd=None,
                           get_cmd=None,
                           vals=vals.Numbers(0, 100),
                           label='Waiting cycle time',
                           docstring='Time between two readings when waiting '
                           'for temperature to equilibrate',
                           unit='s')
        self.wait_cycle_time(0.1)

        self.add_parameter('wait_tolerance',
                           set_cmd=None,
                           get_cmd=None,
                           vals=vals.Numbers(0, 100),
                           label='Waiting tolerance',
                           docstring='Acceptable tolerance when waiting for '
                           'temperature to equilibrate',
                           unit='')
        self.wait_tolerance(0.1)

        self.add_parameter(
            'wait_equilibration_time',
            set_cmd=None,
            get_cmd=None,
            vals=vals.Numbers(0, 100),
            label='Waiting equilibration time',
            docstring='Duration during which temperature has to '
            'be within tolerance',
            unit='s')
        self.wait_equilibration_time(0.5)

        self.add_parameter('blocking_t',
                           label='Setpoint value with blocking until it is '
                           'reached',
                           docstring='Sets the setpoint value, and input '
                           'range, and waits until it is reached. '
                           'Added for compatibility with Loop. Note '
                           'that if the setpoint value is in '
                           'a different range, this function may '
                           'wait forever because that setpoint '
                           'cannot be reached within the current '
                           'range.',
                           vals=vals.Numbers(0, 400),
                           set_cmd=self._set_blocking_t,
                           snapshot_exclude=True)
Beispiel #10
0
    def __init__(self, parent: 'B1517A', name: str, **kwargs: Any):
        super().__init__(parent, name, **kwargs)
        self._sweep_step_parameters: SweepSteps = \
            {"sweep_mode": constants.SweepMode.LINEAR,
             "sweep_range": constants.VOutputRange.AUTO,
             "sweep_start": 0.0,
             "sweep_end": 0.0,
             "sweep_steps": 1,
             "current_compliance": None,
             "power_compliance": None}

        self.add_parameter(name='sweep_auto_abort',
                           set_cmd=self._set_sweep_auto_abort,
                           get_cmd=self._get_sweep_auto_abort,
                           set_parser=constants.Abort,
                           get_parser=constants.Abort,
                           vals=vals.Enum(*list(constants.Abort)),
                           initial_cache_value=constants.Abort.ENABLED,
                           docstring=textwrap.dedent("""
        The WM command enables or disables the automatic abort function for
        the staircase sweep sources and the pulsed sweep source. The
        automatic abort function stops the measurement when one of the
        following conditions occurs:
         - Compliance on the measurement channel
         - Compliance on the non-measurement channel
         - Overflow on the AD converter
         - Oscillation on any channel
        This command also sets the post measurement condition for the sweep
        sources. After the measurement is normally completed, the staircase
        sweep sources force the value specified by the post parameter,
        and the pulsed sweep source forces the pulse base value.

        If the measurement is stopped by the automatic abort function,
        the staircase sweep sources force the start value, and the pulsed
        sweep source forces the pulse base value after sweep.
        """))

        self.add_parameter(name='post_sweep_voltage_condition',
                           set_cmd=self._set_post_sweep_voltage_condition,
                           get_cmd=self._get_post_sweep_voltage_condition,
                           set_parser=constants.WM.Post,
                           get_parser=constants.WM.Post,
                           vals=vals.Enum(*list(constants.WM.Post)),
                           initial_cache_value=constants.WM.Post.START,
                           docstring=textwrap.dedent("""
        Source output value after the measurement is normally completed. If
        this parameter is not set, the sweep sources force the start value.
                                 """))

        self.add_parameter(name='hold_time',
                           initial_value=0.0,
                           vals=vals.Numbers(0, 655.35),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Hold time (in seconds) that is the
                           wait time after starting measurement
                           and before starting delay time for
                           the first step 0 to 655.35 s, with 10
                           ms resolution. Numeric expression.
                          """))

        self.add_parameter(name='delay',
                           initial_value=0.0,
                           vals=vals.Numbers(0, 65.535),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Delay time (in seconds) that is the wait time after
                           starting to force a step output and before
                            starting a step measurement. 0 to 65.535 s,
                            with 0.1 ms resolution. Numeric expression.
                            """))

        self.add_parameter(name='step_delay',
                           initial_value=0.0,
                           vals=vals.Numbers(0, 1),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                            Step delay time (in seconds) that is the wait time
                            after starting a step measurement and before
                            starting to force the next step output. 0 to 1 s,
                            with 0.1 ms resolution. Numeric expression. If
                            this parameter is not set, step delay will be 0. If
                            step delay is shorter than the measurement time,
                            the B1500 waits until the measurement completes,
                            then forces the next step output.
                            """))

        self.add_parameter(name='trigger_delay',
                           initial_value=0.0,
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                            Step source trigger delay time (in seconds) that
                            is the wait time after completing a step output
                            setup and before sending a step output setup
                            completion trigger. 0 to the value of ``delay`` s,
                            with 0.1 ms resolution.
                            If this parameter is not set,
                            trigger delay will be 0.
                            """))

        self.add_parameter(name='measure_delay',
                           initial_value=0.0,
                           unit='s',
                           vals=vals.Numbers(0, 65.535),
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Step measurement trigger delay time (in seconds)
                           that is the wait time after receiving a start step
                           measurement trigger and before starting a step
                           measurement. 0 to 65.535 s, with 0.1 ms resolution.
                           Numeric expression. If this parameter is not set,
                           measure delay will be 0.
                           """))

        self._set_sweep_delays_group = Group(
            [self.hold_time,
             self.delay,
             self.step_delay,
             self.trigger_delay,
             self.measure_delay],
            set_cmd='WT '
                    '{hold_time},'
                    '{delay},'
                    '{step_delay},'
                    '{trigger_delay},'
                    '{measure_delay}',
            get_cmd=self._get_sweep_delays(),
            get_parser=self._get_sweep_delays_parser)

        self.add_parameter(name='sweep_mode',
                           set_cmd=self._set_sweep_mode,
                           get_cmd=self._get_sweep_mode,
                           vals=vals.Enum(*list(constants.SweepMode)),
                           set_parser=constants.SweepMode,
                           snapshot_get=False,
                           docstring=textwrap.dedent("""
                 Sweep mode. Note that Only linear sweep (mode=1 or 3) is
                 available for the staircase sweep with pulsed bias.
                     1: Linear sweep (single stair, start to stop.)
                     2: Log sweep (single stair, start to stop.)
                     3: Linear sweep (double stair, start to stop to start.)
                     4: Log sweep (double stair, start to stop to start.)
                                """))

        self.add_parameter(name='sweep_range',
                           set_cmd=self._set_sweep_range,
                           get_cmd=self._get_sweep_range,
                           vals=vals.Enum(*list(constants.VOutputRange)),
                           set_parser=constants.VOutputRange,
                           snapshot_get=False,
                           docstring=textwrap.dedent("""
        Ranging type for staircase sweep voltage output. Integer expression.
        See Table 4-4 on page 20. The B1500 usually uses the minimum range
        that covers both start and stop values to force the staircase sweep
        voltage. However, if you set `power_compliance` and if the following
        formulas are true, the B1500 uses the minimum range that covers the
        output value, and changes the output range dynamically (20 V range or
        above). Range changing may cause 0 V output in a moment. For the
        limited auto ranging, the instrument never uses the range less than
        the specified range.
         - Icomp > maximum current for the output range
         - Pcomp/output voltage > maximum current for the output range
        """))

        self.add_parameter(name='sweep_start',
                           set_cmd=self._set_sweep_start,
                           get_cmd=self._get_sweep_start,
                           unit='V',
                           vals=vals.Numbers(-25, 25),
                           snapshot_get=False,
                           docstring=textwrap.dedent("""
        Start value of the stair case sweep (in V). For the log sweep,
        start and stop must have the same polarity.
                                """))

        self.add_parameter(name='sweep_end',
                           set_cmd=self._set_sweep_end,
                           get_cmd=self._get_sweep_end,
                           unit='V',
                           vals=vals.Numbers(-25, 25),
                           snapshot_get=False,
                           docstring=textwrap.dedent("""
        Stop value of the DC bias sweep (in V). For the log sweep,start and
        stop must have the same polarity.
                                """))

        self.add_parameter(name='sweep_steps',
                           set_cmd=self._set_sweep_steps,
                           get_cmd=self._get_sweep_steps,
                           vals=vals.Ints(1, 1001),
                           snapshot_get=False,
                           docstring=textwrap.dedent("""
        Number of steps for staircase sweep. Possible  values from 1 to
        1001"""))

        self.add_parameter(name='current_compliance',
                           set_cmd=self._set_current_compliance,
                           get_cmd=self._get_current_compliance,
                           unit='A',
                           vals=vals.Numbers(-40, 40),
                           snapshot_get=False,
                           docstring=textwrap.dedent("""
        Current compliance (in A). Refer to Manual 2016. See Table 4-7 on
        page 24, Table 4-9 on page 26, Table 4-12 on page 27, or Table 4-15
        on page 28 for each measurement resource type. If you do not set
        current_compliance, the previous value is used.
        Compliance polarity is automatically set to the same polarity as the
        output value, regardless of the specified Icomp.
        If the output value is 0, the compliance polarity is positive. If
        you set Pcomp, the maximum Icomp value for the measurement resource
        is allowed, regardless of the output range setting.
                           """))

        self.add_parameter(name='power_compliance',
                           set_cmd=self._set_power_compliance,
                           get_cmd=self._get_power_compliance,
                           unit='W',
                           vals=vals.Numbers(0.001, 80),
                           snapshot_get=False,
                           docstring=textwrap.dedent("""
        Power compliance (in W). Resolution: 0.001 W. If it is not entered,
        the power compliance is not set. This parameter is not available for
        HVSMU. 0.001 to 2 for MPSMU/HRSMU, 0.001 to 20 for HPSMU, 0.001 to
        40 for HCSMU, 0.001 to 80 for dual HCSMU, 0.001 to 3 for MCSMU,
        0.001 to 100 for UHVU
                           """))
Beispiel #11
0
    def __init__(self, parent, name, channel):
        super().__init__(parent, name, channel)

        # Parameters related to Input Channel Parameter Command (INSET)
        self.add_parameter('enabled',
                           label='Enabled',
                           docstring='Specifies whether the input/channel is '
                           'enabled or disabled. At least one '
                           'measurement input channel must be '
                           'enabled. If all are configured to '
                           'disabled, channel 1 will change to '
                           'enabled.',
                           val_mapping={
                               True: 1,
                               False: 0
                           },
                           parameter_class=GroupParameter)
        self.add_parameter('dwell',
                           label='Dwell',
                           docstring='Specifies a value for the autoscanning '
                           'dwell time.',
                           unit='s',
                           get_parser=int,
                           vals=vals.Numbers(1, 200),
                           parameter_class=GroupParameter)
        self.add_parameter('pause',
                           label='Change pause time',
                           docstring='Specifies a value for '
                           'the change pause time',
                           unit='s',
                           get_parser=int,
                           vals=vals.Numbers(3, 200),
                           parameter_class=GroupParameter)
        self.add_parameter('curve_number',
                           label='Curve',
                           docstring='Specifies which curve the channel uses: '
                           '0 = no curve, 1 to 59 = standard/user '
                           'curves. Do not change this parameter '
                           'unless you know what you are doing.',
                           get_parser=int,
                           vals=vals.Numbers(0, 59),
                           parameter_class=GroupParameter)
        self.add_parameter('temperature_coefficient',
                           label='Change pause time',
                           docstring='Sets the temperature coefficient that '
                           'will be used for temperature control if '
                           'no curve is selected (negative or '
                           'positive). Do not change this parameter '
                           'unless you know what you are doing.',
                           val_mapping={
                               'negative': 1,
                               'positive': 2
                           },
                           parameter_class=GroupParameter)
        self.output_group = Group([
            self.enabled, self.dwell, self.pause, self.curve_number,
            self.temperature_coefficient
        ],
                                  set_cmd=f'INSET {self._channel}, '
                                  f'{{enabled}}, {{dwell}}, {{pause}}, '
                                  f'{{curve_number}}, '
                                  f'{{temperature_coefficient}}',
                                  get_cmd=f'INSET? {self._channel}')

        # Parameters related to Input Setup Command (INTYPE)
        self.add_parameter('excitation_mode',
                           label='Excitation mode',
                           docstring='Specifies excitation mode',
                           val_mapping={
                               'voltage': 0,
                               'current': 1
                           },
                           parameter_class=GroupParameter)
        # The allowed values for this parameter change based on the value of
        # the 'excitation_mode' parameter. Moreover, there is a table in the
        # manual that assigns the numbers to particular voltage/current ranges.
        # Once this parameter is heavily used, it can be implemented properly
        # (i.e. using val_mapping, and that val_mapping is updated based on the
        # value of 'excitation_mode'). At the moment, this parameter is added
        # only because it is a part of a group.
        self.add_parameter('excitation_range_number',
                           label='Excitation range number',
                           docstring='Specifies excitation range number '
                           '(1-12 for voltage excitation, 1-22 for '
                           'current excitation); refer to the manual '
                           'for the table of ranges',
                           get_parser=int,
                           vals=vals.Numbers(1, 22),
                           parameter_class=GroupParameter)
        self.add_parameter('auto_range',
                           label='Auto range',
                           docstring='Specifies auto range setting',
                           val_mapping={
                               'off': 0,
                               'current': 1
                           },
                           parameter_class=GroupParameter)
        self.add_parameter('range',
                           label='Range',
                           val_mapping={
                               '2.0 mOhm': 1,
                               '6.32 mOhm': 2,
                               '20.0 mOhm': 3,
                               '63.2 mOhm': 4,
                               '200 mOhm': 5,
                               '632 mOhm': 6,
                               '2.00 Ohm': 7,
                               '6.32 Ohm': 8,
                               '20.0 Ohm': 9,
                               '63.2 Ohm': 10,
                               '200 Ohm': 11,
                               '632 Ohm': 12,
                               '2.00 kOhm': 13,
                               '6.32 kOhm': 14,
                               '20.0 kOhm': 15,
                               '63.2 kOhm': 16,
                               '200 kOhm': 17,
                               '632 kOhm': 18,
                               '2.0 MOhm': 19,
                               '6.32 MOhm': 20,
                               '20.0 MOhm': 21,
                               '63.2 MOhm': 22
                           },
                           parameter_class=GroupParameter)
        self.add_parameter('current_source_shunted',
                           label='Current source shunt',
                           docstring='Current source either not shunted '
                           '(excitation on), or shunted '
                           '(excitation off)',
                           val_mapping={
                               False: 0,
                               True: 1
                           },
                           parameter_class=GroupParameter)
        self.add_parameter('units',
                           label='Preferred units',
                           docstring='Specifies the preferred units parameter '
                           'for sensor readings and for the control '
                           'setpoint (kelvin or ohms)',
                           val_mapping={
                               'kelvin': 1,
                               'ohms': 2
                           },
                           parameter_class=GroupParameter)
        self.output_group = Group([
            self.excitation_mode, self.excitation_range_number,
            self.auto_range, self.range, self.current_source_shunted,
            self.units
        ],
                                  set_cmd=f'INTYPE {self._channel}, '
                                  f'{{excitation_mode}}, '
                                  f'{{excitation_range_number}}, '
                                  f'{{auto_range}}, {{range}}, '
                                  f'{{current_source_shunted}}, '
                                  f'{{units}}',
                                  get_cmd=f'INTYPE? {self._channel}')
Beispiel #12
0
    def __init__(self, name, address, **kwargs):
        super().__init__(name, address, terminator='\n', **kwargs)

        # Add range parameters
        self.add_parameter('range_1',
                           label='Channel 1 range',
                           vals=vals.Ints(1, 4),
                           parameter_class=GroupParameter)
        self.add_parameter('range_2',
                           label='Channel 2 range',
                           vals=vals.Ints(1, 4),
                           parameter_class=GroupParameter)
        self.add_parameter('range_3',
                           label='Channel 3 range',
                           vals=vals.Ints(1, 4),
                           parameter_class=GroupParameter)

        # Add current parameters
        self.add_parameter('current_1',
                           label='Channel 1 current',
                           vals=vals.Ints(0, 100),
                           parameter_class=GroupParameter)
        self.add_parameter('current_2',
                           label='Channel 2 current',
                           vals=vals.Ints(0, 100),
                           parameter_class=GroupParameter)
        self.add_parameter('current_3',
                           label='Channel 3 current',
                           vals=vals.Ints(0, 100),
                           parameter_class=GroupParameter)

        # Add on/off parameters
        self.add_parameter('on_1',
                           label='Channel 1 on',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('on_2',
                           label='Channel 2 on',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('on_3',
                           label='Channel 3 on',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        # Add gated parameters
        self.add_parameter('gated_1',
                           label='Channel 1 gated',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('gated_2',
                           label='Channel 2 gated',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('gated_3',
                           label='Channel 3 gated',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        # Setup group parameter using status command to update all the parameters at once
        status_group_parameters = [
            self.range_1, self.range_2, self.range_3, self.current_1,
            self.current_2, self.current_3, self.on_1, self.on_2, self.on_3,
            self.gated_1, self.gated_2, self.gated_3
        ]
        self.status_group = Group(status_group_parameters,
                                  get_parser=status_parser,
                                  get_cmd='STATUS?')

        # Connect to the instrument and get an IDN
        # self.connect_message()
        print('Connect string:', self.ask('ID?'))
Beispiel #13
0
    def __init__(self, parent: 'KeysightB1500', name: Optional[str],
                 slot_nr: int, **kwargs: Any):
        super().__init__(parent, name, slot_nr, **kwargs)

        self.channels = (ChNr(slot_nr), )
        self.setup_fnc_already_run = False
        self._ranging_mode: constants.RangingMode = constants.RangingMode.AUTO
        self._measurement_range_for_non_auto: Optional[int] = None

        self.add_parameter(name="voltage_dc",
                           unit="V",
                           set_cmd=self._set_voltage_dc,
                           get_cmd=self._get_voltage_dc,
                           snapshot_get=False)

        self.add_parameter(name="voltage_ac",
                           unit="V",
                           set_cmd=self._set_voltage_ac,
                           get_cmd=self._get_voltage_ac,
                           snapshot_get=False)

        self.add_parameter(name="frequency",
                           unit="Hz",
                           set_cmd=self._set_frequency,
                           get_cmd=self._get_frequency,
                           snapshot_get=False)

        self.add_parameter(name="capacitance",
                           get_cmd=self._get_capacitance,
                           snapshot_value=False)

        self.add_submodule('correction', Correction(self, 'correction'))

        self.add_parameter(name="phase_compensation_mode",
                           set_cmd=self._set_phase_compensation_mode,
                           get_cmd=None,
                           set_parser=constants.ADJ.Mode,
                           docstring=textwrap.dedent("""
            This parameter selects the MFCMU phase compensation mode. This
            command initializes the MFCMU. The available modes are captured
            in :class:`constants.ADJ.Mode`:

                - 0: Auto mode. Initial setting.
                - 1: Manual mode.
                - 2: Load adaptive mode.

            For mode=0, the KeysightB1500 sets the compensation data
            automatically. For mode=1, execute the
            :meth:`phase_compensation` method ( the ``ADJ?`` command) to
            perform the phase compensation and set the compensation data.
            For mode=2, the KeysightB1500 performs the phase compensation
            before every measurement. It is useful when there are wide load
            fluctuations by changing the bias and so on."""))

        self.add_submodule('cv_sweep', CVSweeper(self, 'cv_sweep'))

        self.add_parameter(name='adc_coef',
                           initial_value=1,
                           parameter_class=GroupParameter,
                           vals=vals.Ints(1, 1023),
                           docstring=textwrap.dedent("""
            Coefficient used to define the number of averaging samples or
            the averaging time. Integer expression.
                - For mode=0: 1 to 1023. Initial setting/default setting is 2.
                - For mode=2: 1 to 100. Initial setting/default setting is 1.
            """))

        self.add_parameter(name='adc_mode',
                           initial_value=constants.ACT.Mode.PLC,
                           parameter_class=GroupParameter,
                           vals=vals.Enum(*list(constants.ACT.Mode)),
                           set_parser=constants.ACT.Mode,
                           docstring=textwrap.dedent("""
            Sets the number of averaging samples or the averaging time set
            to the A/D converter of the MFCMU

                ``constants.ACT.Mode.AUTO``: Auto mode. Defines the number
                of averaging samples given by the following formula. Then
                initial averaging is the number of averaging samples
                automatically set by the B1500 and you cannot change.

                Number of averaging samples = N x initial averaging

                ``constants.ACT.Mode.PLC``: Power line cycle (PLC) mode.
                Defines the averaging time given by the following formula.

                Averaging time = N / power line frequency
                                       """))

        self._adc_group = Group([self.adc_mode, self.adc_coef],
                                set_cmd='ACT {adc_mode},{adc_coef}',
                                get_cmd=self._get_adc_mode(),
                                get_parser=self._get_adc_mode_parser)

        self.add_parameter(name='ranging_mode',
                           set_cmd=self._set_ranging_mode,
                           vals=vals.Enum(*list(constants.RangingMode)),
                           set_parser=constants.RangingMode,
                           get_cmd=None,
                           docstring=textwrap.dedent("""
            Specifies the measurement range or the measurement ranging type
            of the MFCMU. In the initial setting, the auto ranging is set.
            The range changing occurs immediately after the trigger
            (that is, during the measurements).
            Possible ranging modes are autorange and fixed range.
                           """))

        self.add_parameter(name='measurement_range_for_non_auto',
                           set_cmd=self._set_measurement_range_for_non_auto,
                           get_cmd=None,
                           docstring=textwrap.dedent("""
            Measurement range. Needs to set when ``ranging_mode`` is set to
            PLC. The value should be integer 0 or more. 50 ohm, 100 ohm,
            300 ohm, 1 kilo ohm, 3 kilo ohm, 10 kilo ohm, 30 kilo ohm,
            100 kilo ohm, and 300 kilo ohm are selectable. Available
            measurement ranges depend on the output signal frequency set by
            the FC command."""))

        self.add_parameter(name="measurement_mode",
                           get_cmd=None,
                           set_cmd=self._set_measurement_mode,
                           set_parser=MM.Mode,
                           vals=vals.Enum(*list(MM.Mode)),
                           docstring=textwrap.dedent("""
            Set measurement mode for this module.

            It is recommended for this parameter to use values from
            :class:`.constants.MM.Mode` enumeration.

            Refer to the documentation of ``MM`` command in the programming
            guide for more information.
                            """))

        self.add_parameter(
            name='impedance_model',
            set_cmd=self._set_impedance_model,
            get_cmd=None,
            vals=vals.Enum(*list(constants.IMP.MeasurementMode)),
            set_parser=constants.IMP.MeasurementMode,
            initial_value=constants.IMP.MeasurementMode.Cp_D,
            docstring=textwrap.dedent("""
            The IMP command specifies the parameter measured by the MFCMU.
            Look at the ``constants.IMP.MeasurementMode`` for all the modes.
                           """))

        self.add_parameter(name='ac_dc_volt_monitor',
                           set_cmd=self._set_ac_dc_volt_monitor,
                           get_cmd=None,
                           vals=vals.Ints(0, 1),
                           initial_value=False,
                           docstring=textwrap.dedent("""
            This command enables or disables the data monitor and data
            output of the MFCMU AC voltage and DC voltage.
                0: Disables the data monitor and output. Initial setting.
                1: Enables the data monitor and output.
                           """))

        self.add_parameter(name='cv_sweep_voltages',
                           get_cmd=self._cv_sweep_voltages,
                           unit='V',
                           label='Voltage',
                           docstring=textwrap.dedent("""
            Outputs the tuple of voltages to sweep.  sweep_start, sweep_end
            and sweep_step functions are used to define the values of
            voltages. There are possible modes; linear sweep, log sweep,
            linear 2 way sweep and log 2 way sweep. The  output of
            sweep_mode method is used to decide which mode to use.
                           """))

        self.add_parameter(name='run_sweep',
                           parameter_class=CVSweepMeasurement,
                           docstring=textwrap.dedent("""
            This is MultiParameter. Running the sweep runs the measurement
            on the list of values of cv_sweep_voltages. The output is a
            primary parameter (for ex Capacitance) and a secondary
            parameter (for ex Dissipation) both of whom use the same
            setpoint cv_sweep_voltages. The impedance_model defines exactly
            what will be the primary and secondary parameter. The default
            case is Capacitance and Dissipation.
                           """))
Beispiel #14
0
    def __init__(self, parent: 'Model_325', name: str, loop: int) -> None:

        if loop not in [1, 2]:
            raise ValueError("Please either specify loop 1 or 2")

        super().__init__(parent, name)
        self._loop = loop

        self.add_parameter("control_mode",
                           get_cmd=f"CMODE? {self._loop}",
                           set_cmd=f"CMODE {self._loop},{{}}",
                           val_mapping={
                               "Manual PID": "1",
                               "Zone": "2",
                               "Open Loop": "3",
                               "AutoTune PID": "4",
                               "AutoTune PI": "5",
                               "AutoTune P": "6"
                           })

        self.add_parameter("input_channel",
                           vals=Enum("A", "B"),
                           parameter_class=GroupParameter)

        self.add_parameter("unit",
                           val_mapping={
                               "Kelvin": "1",
                               "Celsius": "2",
                               "Sensor Units": "3"
                           },
                           parameter_class=GroupParameter)

        self.add_parameter('powerup_enable',
                           val_mapping={
                               True: 1,
                               False: 0
                           },
                           parameter_class=GroupParameter)

        self.add_parameter("output_metric",
                           val_mapping={
                               "current": "1",
                               "power": "2",
                           },
                           parameter_class=GroupParameter)

        Group([
            self.input_channel, self.unit, self.powerup_enable,
            self.output_metric
        ],
              set_cmd=f"CSET {self._loop}, {{input_channel}}, {{unit}}, "
              f"{{powerup_enable}}, {{output_metric}}",
              get_cmd=f"CSET? {self._loop}")

        self.add_parameter('P',
                           vals=Numbers(0, 1000),
                           get_parser=float,
                           parameter_class=GroupParameter)

        self.add_parameter('I',
                           vals=Numbers(0, 1000),
                           get_parser=float,
                           parameter_class=GroupParameter)

        self.add_parameter('D',
                           vals=Numbers(0, 1000),
                           get_parser=float,
                           parameter_class=GroupParameter)

        Group([self.P, self.I, self.D],
              set_cmd=f'PID {self._loop}, {{P}}, {{I}}, {{D}}',
              get_cmd=f'PID? {self._loop}')

        if self._loop == 1:
            valid_output_ranges = Enum(0, 1, 2)
        else:
            valid_output_ranges = Enum(0, 1)

        self.add_parameter('output_range',
                           vals=valid_output_ranges,
                           set_cmd=f'RANGE {self._loop}, {{}}',
                           get_cmd=f'RANGE? {self._loop}',
                           val_mapping={
                               "Off": '0',
                               "Low (2.5W)": '1',
                               "High (25W)": '2'
                           })

        self.add_parameter('setpoint',
                           vals=Numbers(0, 400),
                           get_parser=float,
                           set_cmd=f'SETP {self._loop}, {{}}',
                           get_cmd=f'SETP? {self._loop}')

        self.add_parameter("ramp_state",
                           vals=Enum(0, 1),
                           parameter_class=GroupParameter)

        self.add_parameter(
            "ramp_rate",
            vals=Numbers(0, 100 / 60 * 1E3),
            unit="mK/s",
            parameter_class=GroupParameter,
            get_parser=lambda v: float(v) / 60 *
            1E3,  # We get values in K/min,
            set_parser=lambda v: v * 60 * 1E-3  # Convert to K/min
        )

        Group([self.ramp_state, self.ramp_rate],
              set_cmd=f"RAMP {self._loop}, {{ramp_state}}, {{ramp_rate}}",
              get_cmd=f"RAMP? {self._loop}")

        self.add_parameter("is_ramping", get_cmd=f"RAMPST? {self._loop}")

        self.add_parameter("resistance",
                           get_cmd=f"HTRRES? {self._loop}",
                           set_cmd=f"HTRRES {self._loop}, {{}}",
                           val_mapping={
                               25: 1,
                               50: 2,
                           },
                           label='Resistance',
                           unit="Ohm")

        self.add_parameter("heater_output",
                           get_cmd=f"HTR? {self._loop}",
                           get_parser=float,
                           label='Heater Output',
                           unit="%")
Beispiel #15
0
    def __init__(
            self,
            parent: "Model_340",
            output_name: str,
            loop: Optional[int] = None,
            has_pid: bool = True):

        super().__init__(parent, output_name)

        self._loop = loop

        self.add_parameter(
            "range",
            label="heater range",
            docstring="set heater output range",
            val_mapping=self.RANGES,
            set_cmd=f'RANGE {{}}',
            get_cmd=f'RANGE?'
        )

        if self._loop:

            self._loop = loop

            self.add_parameter(
                "setpoint",
                label="setpoint temp",
                docstring="setpoint for heater control loop",
                vals=vals.Numbers(0, 400),
                get_parser=float,
                set_cmd=f'SETP {self._loop}, {{}}',
                get_cmd=f'SETP? {self._loop}'
            )

            self.add_parameter('input_channel',
                               label='Input channel',
                               docstring='Specifies which measurement input to '
                                         'control from (note that only '
                                         'measurement inputs are available)',
                               parameter_class=GroupParameter,
                               get_parser=str,)

            self.add_parameter('units',
                               label='Specifies setpoint units',
                               docstring='Specifies whether the output remains on '
                                         'or shuts off after power cycle.',
                               val_mapping={'Kelvin': 1, 'Celsius': 2, 'Sensor': 3},
                               parameter_class=GroupParameter)

            self.add_parameter('control_loop_status',
                               label='Power-up enable on/off',
                               docstring='Specifies whether the output remains on '
                                         'or shuts off after power cycle.',
                               val_mapping={'on':1, 'off':0},
                               parameter_class=GroupParameter)

            self.add_parameter('powerup_enable',
                               label='Power-up enable on/off',
                               docstring='Specifies whether the output remains on '
                                         'or shuts off after power cycle.',
                               val_mapping={True: 1, False: 0},
                               parameter_class=GroupParameter)

            self.output_group = Group([self.input_channel, self.units,
                                       self.control_loop_status, self.powerup_enable],
                                      set_cmd=f'CSET {self._loop}, '
                                              f'{{input_channel}}, '
                                              f'{{units}}, '
                                              f'{{control_loop_status}}, '
                                              f'{{powerup_enable}}',
                                      get_cmd=f'CSET? {loop}')

        if 'heater' in output_name:

            self.add_parameter('output',
                   label='Output',
                   unit='% of heater range',
                   docstring='Specifies heater output in percent of '
                             'the current heater output range.\n'
                             'Note that when the heater is off, '
                             'this parameter will return the value '
                             'of 0.005.',
                   get_parser=float,
                   get_cmd=f'HTR?',
                   set_cmd=False)
Beispiel #16
0
    def __init__(
        self,
        parent: "Model_340",
        name: str,
        channel: str):

        super().__init__(parent, name)

        self._channel = channel  # Channel on the temperature controller

        self.add_parameter('temperature',
                           get_cmd=f'KRDG? {self._channel}',
                           get_parser=float,
                           label='Temperature',
                           unit='K')

        self.add_parameter('sensor_raw',
                   get_cmd=f'SRDG? {self._channel}',
                   get_parser=float,
                   label='Raw reading',
                   unit='Ohms')

        self.add_parameter('sensor_status',
                   get_cmd=f'RDGST? {self._channel}',
                   get_parser=self._decode_sensor_status,
                   label='Sensor status')

        self.add_parameter('enabled',
                           label='Enabled',
                           docstring='Specifies whether the input/channel is '
                                     'enabled or disabled. At least one '
                                     'measurement input channel must be '
                                     'enabled. If all are configured to '
                                     'disabled, channel 1 will change to '
                                     'enabled.',
                           val_mapping={True: 1, False: 0},
                           parameter_class=GroupParameter)
        self.add_parameter('compensation',
                           label='Dwell',
                           docstring='Specifies a value for the autoscanning '
                                     'dwell time.',
                           unit='s',
                           val_mapping={'off':0, 'on':1, 'pause':2},
                           parameter_class=GroupParameter)

        self.output_group = Group([self.enabled, self.compensation],
                                  set_cmd=f'INSET {self._channel}, '
                                          f'{{enabled}}, {{compensation}}',
                                  get_cmd=f'INSET? {self._channel}')

        # Parameters related to Input Setup Command (INTYPE)
        self.add_parameter('sensor_type',
                           label='Type of sensor connected',
                           docstring='Specifies the type of sensor',
                           get_parser=int,
                           val_mapping=self.SENSOR_TYPES,
                           parameter_class=GroupParameter)
        self.add_parameter('units',
                           label='Preferred units',
                           docstring='Specifies the preferred units parameter '
                                     'for sensor readings and for the control '
                                     'setpoint (kelvin or ohms)',
                           val_mapping={'volts': 1, 'ohms': 2},
                           parameter_class=GroupParameter)
        self.add_parameter('temperature_coefficient',
                          label='Temperature coefficient',
                          docstring='Sets the temperature coefficient that '
                                    'will be used for temperature control if '
                                    'no curve is selected (negative or '
                                    'positive). Do not change this parameter '
                                    'unless you know what you are doing.',
                          val_mapping={'negative': 1, 'positive': 2},
                          parameter_class=GroupParameter)
        self.add_parameter('excitation',
                          label='Current excitation range',
                          docstring='Specifies excitation range',
                          get_parser=int,
                          val_mapping=self.EXCITATIONS,
                          parameter_class=GroupParameter)
        self.add_parameter('range',
                           label='Range',
                           val_mapping=self.RANGES,
                           parameter_class=GroupParameter)

        self.output_group = Group([self.sensor_type, self.units,
                                   self.temperature_coefficient,
                                   self.excitation, self.range],
                                  set_cmd=f'INTYPE {self._channel}, '
                                          f'{{sensor_type}}, {{units}}, '
                                          f'{{temperature_coefficient}}, '
                                          f'{{excitation}}, {{range}}',
                                  get_cmd=f'INTYPE? {self._channel}')
Beispiel #17
0
    def __init__(self, name, address, **kwargs):
        super().__init__(name, address, terminator='\n', **kwargs)

        # Acknowledge type comes back when a command has been sent
        # It tells us if the machine has understood our command
        # 0 = command ok - Command accepted and executed
        # 1 = command error - Command type not excepted
        # 2 = parameter error - Wrong parameters applied
        # 3 = receive error - Received failed, send command again.
        # 4 = not accepted - Illegal data send, ignored.
        self.add_parameter('latest_ack',
                           GroupParameter,
                           label='Acknowledge type from latest command',
                           vals=vals.Ints(0, 4))

        # Status parameter - Gets the system status
        # 1 = start
        # 2 = 3He
        # 3 = 4He
        # 4 = Normal
        # 5 = Recovery
        self.add_parameter('status',
                           GroupParameter,
                           label='System status',
                           vals=vals.Ints(1, 5))
        self.status_group = Group([self.latest_ack, self.status],
                                  get_parser=self.status_parser,
                                  get_cmd='STATUS?')

        # Led status - Tells us what leds are on or off
        # 1 = off
        # 2 = on
        led_group = [self.latest_ack]
        for i in range(1, 65):
            # Create a parameter for each led
            led_label = f'led_x{i + 100}'
            self.add_parameter(led_label,
                               GroupParameter,
                               label=f'Led for key x{i+100}',
                               vals=vals.Ints(1, 2))
            led_group.append(self[led_label])

        # Setup a group to describe the leds (and ack)
        self.led_group = Group(led_group,
                               get_parser=self.led_status_parser,
                               get_cmd='LEDS?')

        # Pressure status (raw ADC value)
        # P1-P7 are normal sensors
        # P8 is a flow sensor
        pressure_group = [self.latest_ack]
        for i in range(1, 9):
            # Create a parameter for each sensor
            pressure_label = f'pressure_p{i}'
            self.add_parameter(pressure_label,
                               GroupParameter,
                               label=f'Pressure sensor p{i}',
                               vals=vals.Ints(0, 999999))
            pressure_group.append(self[pressure_label])

        # Add all the pressure sensors to a group
        self.pressure_group = Group(pressure_group,
                                    get_parser=self.pressure_status_parser,
                                    get_cmd='ADC?')

        # Pressure settings
        # P6 low - P6 value at which it stops condensing 4He
        # P6 high - P6 value at which it stops recovering 4He
        # P7 low - P7 value at which it stops condensing 3He
        # P7 high - P7 value at which it stops recovering 3He
        self.add_parameter('set_p6_low',
                           GroupParameter,
                           label='Low pressure limit on P6',
                           vals=vals.Ints(0, 999999))
        self.add_parameter('set_p6_high',
                           GroupParameter,
                           label='High pressure limit on P6',
                           vals=vals.Ints(0, 999999))
        self.add_parameter('set_p7_low',
                           GroupParameter,
                           label='Low pressure limit on P7',
                           vals=vals.Ints(0, 999999))
        self.add_parameter('set_p7_high',
                           GroupParameter,
                           label='High pressure limit on P7',
                           vals=vals.Ints(0, 999999))

        # Add all the pressure limits to a group
        self.pressure_settings_group = Group(
            [
                self.latest_ack, self.set_p6_low, self.set_p6_high,
                self.set_p7_low, self.set_p7_high
            ],
            get_parser=self.pressure_settings_parser,
            get_cmd="SETTINGS?",
            set_cmd=
            "SETTINGS {set_p6_low},{set_p6_high},{set_p7_low},{set_p7_high}")

        # Keys on the front panel
        # 1 = off
        # 2 = on
        keys_group = [self.latest_ack]
        for i in range(1, 65):
            # Create a parameter for each key
            key_label = f'key_x{i+100}'
            self.add_parameter(key_label,
                               GroupParameter,
                               label=f'Status for key x{i+100}',
                               vals=vals.Ints(1, 2))
            keys_group.append(self[key_label])

        # Add all the keys to a group
        self.keys_group = Group(keys_group,
                                get_parser=self.keys_status_parser,
                                get_cmd='KEYS?')

        # Connect to the instrument and get an IDN
        print('Connect string:', self.ask('ID?'))
Beispiel #18
0
    def __init__(self, parent: 'B1520A', name: str, **kwargs: Any):
        super().__init__(parent, name, **kwargs)

        self.add_parameter(name='sweep_auto_abort',
                           set_cmd=self._set_sweep_auto_abort,
                           get_cmd=self._get_sweep_auto_abort,
                           set_parser=constants.Abort,
                           get_parser=constants.Abort,
                           vals=vals.Enum(*list(constants.Abort)),
                           initial_cache_value=constants.Abort.ENABLED,
                           docstring=textwrap.dedent("""
                           enables or disables the automatic abort function
                           for the CV (DC bias) sweep measurement (MM18) and
                           the pulsed bias sweep measurement (MM20). The
                           automatic abort function stops the measurement
                           when one of the following conditions occurs:
                               - NULL loop unbalance condition
                               - IV amplifier saturation condition
                               - Overflow on the AD converter
                           """))

        self.add_parameter(name='post_sweep_voltage_condition',
                           set_cmd=self._set_post_sweep_voltage_condition,
                           get_cmd=self._get_post_sweep_voltage_condition,
                           set_parser=constants.WMDCV.Post,
                           get_parser=constants.WMDCV.Post,
                           vals=vals.Enum(*list(constants.WMDCV.Post)),
                           initial_cache_value=constants.WMDCV.Post.START,
                           docstring=textwrap.dedent("""
                           This command also sets the post measurement
                           condition of the MFCMU. After the measurement is
                           normally completed, the DC bias sweep source
                           forces the value specified by the post parameter,
                           and the pulsed bias sweep source forces
                           the pulse base value.
                           If the measurement is stopped by the automatic
                           abort function, the DC bias sweep source forces
                           the start value, and the pulsed bias sweep source
                           forces the pulse base value after sweep.
                           """))

        self.add_parameter(name='hold_time',
                           initial_value=0.0,
                           vals=vals.Numbers(0, 655.35),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Hold time (in seconds) that is the
                           wait time after starting measurement
                           and before starting delay time for
                           the first step 0 to 655.35, with 10
                           ms resolution. Numeric expression.
                          """))

        self.add_parameter(name='delay',
                           initial_value=0.0,
                           vals=vals.Numbers(0, 65.535),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Delay time (in seconds) that is the wait time after
                           starting to force a step output and before
                            starting a step measurement. 0 to 65.535,
                            with 0.1 ms resolution. Numeric expression.
                            """))

        self.add_parameter(name='step_delay',
                           initial_value=0.0,
                           vals=vals.Numbers(0, 1),
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                            Step delay time (in seconds) that is the wait time
                            after starting a step measurement and before
                            starting to force the next step output. 0 to 1,
                            with 0.1 ms resolution. Numeric expression. If
                            this parameter is not set, step delay will be 0. If
                            step delay is shorter than the measurement time,
                            the B1500 waits until the measurement completes,
                            then forces the next step output.
                            """))

        self.add_parameter(name='trigger_delay',
                           initial_value=0.0,
                           unit='s',
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                            Step source trigger delay time (in seconds) that
                            is the wait time after completing a step output
                            setup and before sending a step output setup
                            completion trigger. 0 to the value of ``delay``,
                            with 0.1 ms resolution. Numeric expression. If this
                            parameter is not set, trigger delay will be 0.
                            """))

        self.add_parameter(name='measure_delay',
                           initial_value=0.0,
                           unit='s',
                           vals=vals.Numbers(0, 65.535),
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                           Step measurement trigger delay time (in seconds)
                           that is the wait time after receiving a start step
                           measurement trigger and before starting a step
                           measurement. 0 to 65.535, with 0.1 ms resolution.
                           Numeric expression. If this parameter is not set,
                           measure delay will be 0.
                           """))

        self._set_sweep_delays_group = Group(
            [
                self.hold_time, self.delay, self.step_delay,
                self.trigger_delay, self.measure_delay
            ],
            set_cmd='WTDCV '
            '{hold_time},'
            '{delay},'
            '{step_delay},'
            '{trigger_delay},'
            '{measure_delay}',
            get_cmd=self._get_sweep_delays(),
            get_parser=self._get_sweep_delays_parser)

        self.add_parameter(name='sweep_mode',
                           initial_value=constants.SweepMode.LINEAR,
                           vals=vals.Enum(*list(constants.SweepMode)),
                           set_parser=constants.SweepMode,
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                   Sweep mode.
                       1: Linear sweep (single stair, start to stop.)
                       2: Log sweep (single stair, start to stop.)
                       3: Linear sweep (double stair, start to stop to start.)
                       4: Log sweep (double stair, start to stop to start.)
                                  """))

        self.add_parameter(name='sweep_start',
                           initial_value=0.0,
                           unit='V',
                           vals=vals.Numbers(-25, 25),
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                   Start value of the DC bias sweep (in V). For the log  sweep,
                   start and stop must have the same polarity.
                                  """))

        self.add_parameter(name='sweep_end',
                           initial_value=0.0,
                           unit='V',
                           vals=vals.Numbers(-25, 25),
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                   Stop value of the DC bias sweep (in V). For the log sweep,
                   start and stop must have the same polarity.
                                  """))

        self.add_parameter(name='sweep_steps',
                           initial_value=1,
                           vals=vals.Ints(1, 1001),
                           parameter_class=GroupParameter,
                           docstring=textwrap.dedent("""
                   Number of steps for staircase sweep. Possible  values from 1 to
                   1001"""))

        self.add_parameter(name='_chan',
                           initial_value=self.parent.channels[0],
                           parameter_class=GroupParameter)

        self._set_sweep_steps_group = Group(
            [
                self._chan, self.sweep_mode, self.sweep_start, self.sweep_end,
                self.sweep_steps
            ],
            set_cmd='WDCV '
            '{_chan},'
            '{sweep_mode},'
            '{sweep_start},'
            '{sweep_end},'
            '{sweep_steps}',
            get_cmd=self._get_sweep_steps(),
            get_parser=self._get_sweep_steps_parser)
Beispiel #19
0
    def __init__(self, parent, name, channel):
        super().__init__(parent, name)

        self._channel = channel  # Channel on the temperature controller

        # Add the various channel parameters
        self.add_parameter('temperature',
                           get_cmd='KRDG? {}'.format(self._channel),
                           get_parser=float,
                           label='Temperature',
                           unit='K')

        self.add_parameter('mode',
                           label='Remote/local control',
                           get_cmd='MODE?',
                           set_cmd='MODE {{mode}}',
                           val_mapping={'local': 1,
                                        'remote': 2,
                                        'remote and locked': 3})

        self.add_parameter('sensor_raw',
                           get_cmd=f'SRDG? {self._channel}',
                           get_parser=float,
                           label='Raw reading',
                           unit='Ohms')

        self.add_parameter('sensor_status',
                           get_cmd=f'RDGST? {self._channel}',
                           get_parser=self._decode_sensor_status,
                           label='Sensor status')

        self.add_parameter('input_curve',
                           label='Input curve',
                           get_cmd=f'INCRV? {self._channel}',
                           set_cmd=f'INCRV {self._channel}, {{input_curve}}',
                           vals=vals.Ints(0, 60))

        # Parameters related to Input Type Parameter Command (INTYPE)
        self.add_parameter('sensor_type',
                           label='Input sensor type',
                           docstring='Specifies input sensor type',
                           val_mapping={'Special': 0,
                                        'Si diode': 1,
                                        'GaAlAs diode': 2,
                                        '100 ohm Pt/250': 3,
                                        '100 ohm Pt/500': 4,
                                        '1000 ohm Pt': 5,
                                        'Rhodium Iron': 6,
                                        'Carbon-glass': 7,
                                        'Cernox': 8,
                                        'RuOx': 9,
                                        'Germanium': 10,
                                        'Capacitor': 11,
                                        'Thermocouple': 12},
                           parameter_class=GroupParameter)

        self.add_parameter('sensor_units',
                           label='Input sensor units',
                           val_mapping={'Special': 0,
                                        'volts': 1,
                                        'ohms': 2},
                           parameter_class=GroupParameter)

        self.add_parameter('sensor_coefficient',
                           label='Input coefficient',
                           val_mapping={'Special': 0,
                                        'negative': 1,
                                        'positive': 2},
                           parameter_class=GroupParameter)

        self.add_parameter('sensor_excitation',
                           label='Input sensor excitation',
                           val_mapping={'Off': 0,
                                        '30 nA': 1,
                                        '100 nA': 2,
                                        '300 nA': 3,
                                        '1 uA': 4,
                                        '3 uA': 5,
                                        '10 uA': 6,
                                        '30 uA': 7,
                                        '100 uA': 8,
                                        '300 uA': 9,
                                        '1 mA': 10,
                                        '10 mV': 11,
                                        '1 mV': 12},
                           parameter_class=GroupParameter)

        self.add_parameter('sensor_range',
                           label='Input sensor range',
                           val_mapping={'Special': 0,
                                        '1 mV': 1,
                                        '2.5 mV': 2,
                                        '5 mV': 3,
                                        '10 mV': 4,
                                        '25 mV': 5,
                                        '50 mV': 6,
                                        '100 mV': 7,
                                        '250 mV': 8,
                                        '500 mV': 9,
                                        '1 V': 10,
                                        '2.5 V': 11,
                                        '5 V': 12,
                                        '7.5 V': 13},
                           parameter_class=GroupParameter)

        self.sensor_group = Group([self.sensor_type, self.sensor_units, self.sensor_coefficient, self.sensor_excitation,
                                   self.sensor_range],
                                  set_cmd=f'INTYPE {self._channel}, '
                                          f'{{sensor_type}}, {{sensor_units}}, {{sensor_coefficient}}, '
                                          f'{{sensor_excitation}}, {{sensor_range}}',
                                  get_cmd=f'INTYPE? {self._channel}')

        self.add_parameter('input_enabled',
                           label='input enabled',
                           val_mapping={False: 0,
                                        True: 1},
                           vals=vals.Bool(),
                           parameter_class=GroupParameter)

        self.add_parameter('input_compensation',
                           label='input compensation',
                           val_mapping={'off': 0,
                                        'on': 1,
                                        'pause': 2},
                           parameter_class=GroupParameter)

        self.input_group = Group([self.input_enabled, self.input_compensation],
                                 set_cmd=f'INSET {self._channel}, {{input_enabled}}, {{input_compensation}}',
                                 get_cmd=f'INSET? {self._channel}')
Beispiel #20
0
    def __init__(self,
                 name: str,
                 address: str,
                 terminator: str = '\n',
                 **kwargs: Any):
        """
        Create an instance of the instrument.

        Args:
            name: Name of the instrument instance
            address: Visa-resolvable instrument address.
        """
        super().__init__(name, address, terminator=terminator, **kwargs)

        idn = self.IDN.get()

        self.has_firmware_a_02_10_or_above = (
                LooseVersion(idn["firmware"]) >= LooseVersion("A.02.10")
        )

        self.has_option_001 = '001' in self._options()
        self._dc_bias_v_level_range: Union[Numbers, Enum]
        if self.has_option_001:
            self._v_level_range = Numbers(0, 20)
            self._i_level_range = Numbers(0, 0.1)
            self._imp_range = Enum(0.1, 1, 10, 100, 300, 1000, 3000, 10000,
                                   30000, 100000)
            self._dc_bias_v_level_range = Numbers(-40, 40)
        else:
            self._v_level_range = Numbers(0, 2)
            self._i_level_range = Numbers(0, 0.02)
            self._imp_range = Enum(1, 10, 100, 300, 1000, 3000, 10000, 30000,
                                   100000)
            self._dc_bias_v_level_range = Enum(0, 1.5, 2)

        self._measurement_pair = MeasurementPair(
            "CPD",
            ("capacitance", "dissipation_factor"),
            ("F", "")
        )

        self.add_parameter(
            "frequency",
            get_cmd=":FREQuency?",
            set_cmd=":FREQuency {}",
            get_parser=float,
            unit="Hz",
            vals=Numbers(20, 2E6),
            docstring="Gets and sets the frequency for normal measurement."
        )

        self.add_parameter(
            "current_level",
            get_cmd=self._get_current_level,
            set_cmd=self._set_current_level,
            unit="A",
            vals=self._i_level_range,
            docstring="Gets and sets the current level for measurement signal."
        )

        self.add_parameter(
            "voltage_level",
            get_cmd=self._get_voltage_level,
            set_cmd=self._set_voltage_level,
            unit="V",
            vals=self._v_level_range,
            docstring="Gets and sets the AC bias voltage level for measurement "
                      "signal."
        )

        self.add_parameter(
            "measurement_function",
            get_cmd=":FUNCtion:IMPedance?",
            set_cmd=self._set_measurement
        )

        self.add_parameter(
            "range",
            get_cmd=":FUNCtion:IMPedance:RANGe?",
            set_cmd=self._set_range,
            unit='Ohm',
            vals=self._imp_range,
            docstring="Selects the impedance measurement range, also turns "
                      "the auto range function OFF."
        )

        self.add_parameter(
            "imp_autorange_enabled",
            get_cmd=":FUNCtion:IMPedance:RANGe:AUTO?",
            set_cmd=":FUNCtion:IMPedance:RANGe:AUTO {}",
            val_mapping=create_on_off_val_mapping(on_val="1",
                                                  off_val="0"),
            docstring="Enables the auto-range for impedance measurement."
        )

        self.add_parameter(
            "dc_bias_enabled",
            get_cmd=":BIAS:STATe?",
            set_cmd=":BIAS:STATe {}",
            vals=Bool(),
            val_mapping=create_on_off_val_mapping(on_val="1",
                                                  off_val="0"),
            docstring="Enables DC bias. DC bias is automatically turned "
                      "off after recalling the state from memory."
        )

        self.add_parameter(
            "dc_bias_voltage_level",
            get_cmd=":BIAS:VOLTage:LEVel?",
            set_cmd=":BIAS:VOLTage:LEVel {}",
            get_parser=float,
            unit="V",
            vals=self._dc_bias_v_level_range,
            docstring="Sets the DC bias voltage. Setting does not "
                      "implicitly turn the DC bias ON."
        )

        self.add_parameter(
            "meas_time_mode",
            val_mapping={"short": "SHOR", "medium": "MED", "long": "LONG"},
            parameter_class=GroupParameter
        )

        self.add_parameter(
            "averaging_rate",
            vals=Ints(1, 256),
            parameter_class=GroupParameter,
            get_parser=int,
            docstring="Averaging rate for the measurement."
        )

        self._aperture_group = Group(
            [self.meas_time_mode,
             self.averaging_rate],
            set_cmd=":APERture {meas_time_mode},{averaging_rate}",
            get_cmd=":APERture?"
        )

        if self.has_firmware_a_02_10_or_above:
            self.add_parameter(
                "dc_bias_autorange_enabled",
                get_cmd=":BIAS:RANGe:AUTO?",
                set_cmd=":BIAS:RANGe:AUTO {}",
                vals=Bool(),
                val_mapping=create_on_off_val_mapping(on_val="1",
                                                      off_val="0"),
                docstring="Enables DC Bias range AUTO setting. When DC bias "
                          "range is fixed (not AUTO), '#' is displayed in "
                          "the BIAS field of the display."
            )

        self.add_parameter(
            "signal_mode",
            initial_value=None,
            vals=Enum("Voltage", "Current", None),
            parameter_class=ManualParameter,
            docstring="This parameter tracks the signal mode which is being "
                      "set."
        )

        self.add_submodule(
            "_correction",
            Correction4980A(self, "correction")
        )
        self._set_signal_mode_on_driver_initialization()
        self.connect_message()
Beispiel #21
0
class LC_TCS(VisaInstrument):
    def __init__(self, name, address, **kwargs):
        super().__init__(name, address, terminator='\n', **kwargs)

        # Add range parameters
        self.add_parameter('range_1',
                           label='Channel 1 range',
                           vals=vals.Ints(1, 4),
                           parameter_class=GroupParameter)
        self.add_parameter('range_2',
                           label='Channel 2 range',
                           vals=vals.Ints(1, 4),
                           parameter_class=GroupParameter)
        self.add_parameter('range_3',
                           label='Channel 3 range',
                           vals=vals.Ints(1, 4),
                           parameter_class=GroupParameter)

        # Add current parameters
        self.add_parameter('current_1',
                           label='Channel 1 current',
                           vals=vals.Ints(0, 100),
                           parameter_class=GroupParameter)
        self.add_parameter('current_2',
                           label='Channel 2 current',
                           vals=vals.Ints(0, 100),
                           parameter_class=GroupParameter)
        self.add_parameter('current_3',
                           label='Channel 3 current',
                           vals=vals.Ints(0, 100),
                           parameter_class=GroupParameter)

        # Add on/off parameters
        self.add_parameter('on_1',
                           label='Channel 1 on',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('on_2',
                           label='Channel 2 on',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('on_3',
                           label='Channel 3 on',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        # Add gated parameters
        self.add_parameter('gated_1',
                           label='Channel 1 gated',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('gated_2',
                           label='Channel 2 gated',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })
        self.add_parameter('gated_3',
                           label='Channel 3 gated',
                           vals=vals.Bool(),
                           parameter_class=GroupParameter,
                           val_mapping={
                               True: 1,
                               False: 0
                           })

        # Setup group parameter using status command to update all the parameters at once
        status_group_parameters = [
            self.range_1, self.range_2, self.range_3, self.current_1,
            self.current_2, self.current_3, self.on_1, self.on_2, self.on_3,
            self.gated_1, self.gated_2, self.gated_3
        ]
        self.status_group = Group(status_group_parameters,
                                  get_parser=status_parser,
                                  get_cmd='STATUS?')

        # Connect to the instrument and get an IDN
        # self.connect_message()
        print('Connect string:', self.ask('ID?'))

    def get_all_params(self):
        # Get the status of the system
        self.range_1.get()

    # Sets the current for a channel in microamps
    def set_current(self, channel, current):
        # Set the current
        self.ask(f'SETDAC {channel} 0 {current}')

        # Update the status
        self.status_group.update()

    def toggle_channel_on(self, channel):
        # Determine which channel to toggle
        toggle_ch1, toggle_ch2, toggle_ch3 = 0, 0, 0
        if channel == 1:
            toggle_ch1 = 1
        if channel == 2:
            toggle_ch2 = 1
        if channel == 3:
            toggle_ch3 = 1

        # Toggle the channel
        self.ask(
            f'SETUP 0,0,{toggle_ch1},0,0,0,{toggle_ch2},0,0,0,{toggle_ch3},0')

        # Update the status
        self.status_group.update()

    def toggle_channel_gated(self, channel):
        # Determine which channel to toggle
        toggle_ch1, toggle_ch2, toggle_ch3 = 0, 0, 0
        if channel == 1:
            toggle_ch1 = 1
        if channel == 2:
            toggle_ch2 = 1
        if channel == 3:
            toggle_ch3 = 1

        # Toggle the channel
        self.ask(
            f'SETUP 0,0,0,{toggle_ch1},0,0,0,{toggle_ch2},0,0,0,{toggle_ch3}')

        # Update the status
        self.status_group.update()