Source code for qcodes.instrument_drivers.Lakeshore._lakeshore_model_335

from typing import TYPE_CHECKING, ClassVar

import pyvisa.constants
import pyvisa.resources

import qcodes.validators as vals
from qcodes.parameters import Group, GroupParameter

from .lakeshore_base import (
    LakeshoreBase,
    LakeshoreBaseOutput,
    LakeshoreBaseSensorChannel,
)

if TYPE_CHECKING:
    from typing_extensions import Unpack

    from qcodes.instrument import InstrumentBaseKWArgs, VisaInstrumentKWArgs

# There are 2 sensors channels (a.k.a. measurement inputs) in Model 335.
# Unlike other Lakeshore models, Model 335 refers to the channels using
# letters, and not numbers
_channel_name_to_command_map: dict[str, str] = {"A": "A", "B": "B"}

# OUTMODE command of this model refers to the outputs via integer numbers,
# while everywhere else within this model letters are used. This map is
# created in order to preserve uniformity of referencing to sensor channels
# within this driver.
_channel_name_to_outmode_command_map: dict[str, int] = {
    ch_name: num_for_cmd + 1
    for num_for_cmd, ch_name in enumerate(_channel_name_to_command_map.keys())
}
_channel_name_to_outmode_command_map.update({"None": 0})


[docs] class LakeshoreModel335Channel(LakeshoreBaseSensorChannel): """ An InstrumentChannel representing a single sensor on a Lakeshore Model 335. """ SENSOR_STATUSES: ClassVar[dict[int, str]] = { 0: "OK", 1: "Invalid Reading", 16: "Temp Underrange", 32: "Temp Overrange", 64: "Sensor Units Zero", 128: "Sensor Units Overrange", } def __init__( self, parent: "LakeshoreModel335", name: str, channel: str, **kwargs: "Unpack[InstrumentBaseKWArgs]", ): super().__init__(parent, name, channel, **kwargs) # Parameters related to Input Type Parameter Command (INTYPE) self.sensor_type: GroupParameter = 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, "thermocouple": 4, }, parameter_class=GroupParameter, ) """Specifies input sensor type""" self.auto_range_enabled: 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, ) """Specifies if autoranging is enabled. Does not apply for diode sensor type""" self.range: 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, ) """ 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 """ self.compensation_enabled: 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, ) """ 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 """ self.units: 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, ) """ Specifies the preferred units parameter for sensor readings and for the control setpoint (kelvin, celsius, or sensor) """ 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}", )
[docs] class LakeshoreModel335CurrentSource(LakeshoreBaseOutput): """ InstrumentChannel for current sources on Lakeshore Model 335. Class for control outputs 1 and 2 of Lakeshore Model 335 that are variable DC current sources referenced to chassis ground. """ MODES: ClassVar[dict[str, int]] = { "off": 0, "closed_loop": 1, "zone": 2, "open_loop": 3, } RANGES: ClassVar[dict[str, int]] = {"off": 0, "low": 1, "medium": 2, "high": 3} _input_channel_parameter_kwargs: ClassVar[dict[str, dict[str, int]]] = { "val_mapping": _channel_name_to_outmode_command_map } def __init__( self, parent: "LakeshoreModel335", output_name: str, output_index: int, **kwargs: "Unpack[InstrumentBaseKWArgs]", ): super().__init__(parent, output_name, output_index, has_pid=True, **kwargs) self.P.vals = vals.Numbers(0.1, 1000) self.I.vals = vals.Numbers(0.1, 1000) self.D.vals = vals.Numbers(0, 200)
[docs] class LakeshoreModel335(LakeshoreBase): """ Lakeshore Model 335 Temperature Controller Driver """ channel_name_command: ClassVar[dict[str, str]] = _channel_name_to_command_map CHANNEL_CLASS = LakeshoreModel335Channel input_channel_parameter_values_to_channel_name_on_instrument = ( _channel_name_to_command_map ) def __init__( self, name: str, address: str, **kwargs: "Unpack[VisaInstrumentKWArgs]" ) -> None: super().__init__(name, address, print_connect_message=False, **kwargs) if isinstance(self.visa_handle, pyvisa.resources.serial.SerialInstrument): self.visa_handle.baud_rate = 57600 self.visa_handle.data_bits = 7 self.visa_handle.parity = pyvisa.constants.Parity(1) self.output_1 = LakeshoreModel335CurrentSource(self, "output_1", 1) self.output_2 = LakeshoreModel335CurrentSource(self, "output_2", 2) self.connect_message()