Source code for qcodes_contrib_drivers.drivers.StanfordResearchSystems.SR570

from typing import Any, Optional

import qcodes.validators as vals
from pyvisa.constants import Parity, StopBits
from pyvisa.resources.serial import SerialInstrument
from pyvisa.resources.tcpip import TCPIPSocket
from qcodes.instrument.visa import VisaInstrument
from qcodes.parameters import ParameterBase, create_on_off_val_mapping


[docs] class SR570(VisaInstrument): """ QCoDeS driver for the Stanford Research Systems SR570 Low-Noise Current Preamplifier. This is a real driver and it will talk to your instrument (as opposed to SR560 from QCoDeS). It *can't listen to it*, so make sure that you either reset or set parameters before reading them. (Resetting the device will update the parameters' value with their reset value as per documentation.) The device can also be accessed via TCP/IP if exposed via something like: .. code-block:: console socat /dev/ttyUSB0,echo=0,b9600,cstopb=1,parenb=0,raw tcp-listen:20570,reuseaddr,nodelay """ def __init__(self, name: str, address: str, **kwargs: Any): super().__init__(name, address, **kwargs) if isinstance(self.visa_handle, TCPIPSocket): # allow connection to remote serial device over TCP/IP address self.visa_handle.write_termination = "\r\n" self.visa_handle.read_termination = "" # but there's no read else: assert isinstance(self.visa_handle, SerialInstrument) serial: SerialInstrument = self.visa_handle # 9600 Baud DCE, 8 bit, no parity, 2 stop bits serial.baud_rate = 9600 serial.parity = Parity.none serial.stop_bits = StopBits.two serial.write_termination = "\r\n" serial.read_termination = "" # but there's no read self.connect_message() # fmt:off sensitivity = [ 1e-12, 2e-12, 5e-12, 10e-12, 20e-12, 50e-12, 100e-12, 200e-12, 500e-12, 1e-9, 2e-9, 5e-9, 10e-9, 20e-9, 50e-9, 100e-9, 200e-9, 500e-9, 1e-6, 2e-6, 5e-6, 10e-6, 20e-6, 50e-6, 100e-6, 200e-6, 500e-6, 1e-3 ] input_offset_current = [ 1e-12, 2e-12, 5e-12, 10e-12, 20e-12, 50e-12, 100e-12, 200e-12, 500e-12, 1e-9, 2e-9, 5e-9, 10e-9, 20e-9, 50e-9, 100e-9, 200e-9, 500e-9, 1e-6, 2e-6, 5e-6, 10e-6, 20e-6, 50e-6, 100e-6, 200e-6, 500e-6, 1e-3, 2e-3, 5e-3 ] filter_type = [ "6db_highpass", "12db_highpass", "6db_bandpass", "6db_lowpass", "12db_lowpass", "none", ] filter_freq = [ 0.03, 0.1, 0.3, 1, 3, 10, 30, 100, 300, 1e+3, 3e+3, 10e+3, 30e+3, 100e+3, 300e+3, 1e+6, ] gain_modes = [ "low_noise", "high_bandwidth", "low_drift" ] # fmt:on on_off_val_mapping = create_on_off_val_mapping(on_val=1, off_val=0) self._reset_defaults: dict[str, Any] = {} self.add_parameter( "sensitivity", get_cmd=None, set_cmd="SENS {}", val_mapping={scale: n for n, scale in enumerate(sensitivity)}, unit="A/V", ) self._reset_defaults["sensitivity"] = 1e-6 self.add_parameter( "sensitivity_uncalibrated_mode", get_cmd=None, set_cmd="SUCM {}", val_mapping=create_on_off_val_mapping(on_val=1, off_val=0), ) self._reset_defaults["sensitivity_uncalibrated_mode"] = False self.add_parameter( "sensitivity_uncalibrated_vernier", get_cmd=None, set_cmd="SUCV {}", vals=vals.Ints(0, 100), unit="%", ) self.add_parameter( "input_offset_current_status", get_cmd=None, set_cmd="IOON {}", val_mapping=on_off_val_mapping, ) self._reset_defaults["input_offset_current_status"] = False self.add_parameter( "input_offset_current_level", get_cmd=None, set_cmd="IOLV {}", val_mapping={scale: n for n, scale in enumerate(input_offset_current)}, unit="A", ) self._reset_defaults["input_offset_current_level"] = 1e-12 self.add_parameter( "input_offset_current_sign", get_cmd=None, set_cmd="IOSN {}", val_mapping={+1: 0, -1: 1}, ) self._reset_defaults["input_offset_current_sign"] = +1 self.add_parameter( "input_offset_uncalibrated_mode", get_cmd=None, set_cmd="IOUC {}", val_mapping=on_off_val_mapping, ) self._reset_defaults["input_offset_uncalibrated_mode"] = False self.add_parameter( "input_offset_uncalibrated_vernier", get_cmd=None, set_cmd="IOUV {}", vals=vals.MultiTypeAnd( vals.Numbers(-100, 100), vals.PermissiveMultiples(0.1) ), set_parser=lambda v: int(v * 10), unit="%", ) self.add_parameter( "bias_voltage_status", get_cmd=None, set_cmd="BSON {}", val_mapping=on_off_val_mapping, ) self._reset_defaults["bias_voltage_status"] = False self.add_parameter( "bias_voltage", get_cmd=None, set_cmd="BSLV {}", vals=vals.Numbers(-5.0, +5.0), set_parser=lambda v: int(v * 1000), unit="V", ) self._reset_defaults["bias_voltage"] = 0.0 self.add_parameter( "filter_type", get_cmd=None, set_cmd="FLTT {}", val_mapping={fltt: n for n, fltt in enumerate(filter_type)}, ) self._reset_defaults["filter_type"] = "none" self.add_parameter( "filter_lowpass_frequency", get_cmd=None, set_cmd="LFRQ {}", val_mapping={f: n for n, f in enumerate(filter_freq)}, unit="Hz", ) self._reset_defaults["filter_lowpass_frequency"] = 1e6 self.add_parameter( "filter_highpass_frequency", get_cmd=None, set_cmd="HFRQ {}", val_mapping={f: n for n, f in enumerate(filter_freq[:12])}, unit="Hz", ) self._reset_defaults["filter_highpass_frequency"] = 0.03 self.add_function("reset_overload_condition", call_cmd="ROLD") self.add_parameter( "gain_mode", get_cmd=None, set_cmd="GNMD {}", val_mapping={mode: n for n, mode in enumerate(gain_modes)}, ) self._reset_defaults["gain_mode"] = gain_modes[0] self.add_parameter( "invert", get_cmd=None, set_cmd="INVT {}", val_mapping=on_off_val_mapping ) self._reset_defaults["invert"] = False self.add_parameter( "blank", get_cmd=None, set_cmd="BLNK {}", val_mapping=on_off_val_mapping ) self._reset_defaults["blank"] = False
[docs] def reset(self) -> None: self.write("*RST") p: ParameterBase for p in self.parameters.values(): if not hasattr(p, "cache"): continue p.cache.invalidate() for name, value in self._reset_defaults.items(): p = self.parameters[name] if not hasattr(p, "cache"): continue p.cache.set(value)
[docs] def get_idn(self) -> dict[str, Optional[str]]: vendor = "Stanford Research Systems" model = "SR570" serial = None firmware = None return { "vendor": vendor, "model": model, "serial": serial, "firmware": firmware, }