Source code for qcodes_contrib_drivers.drivers.Ametek.SR_7270

# This Python file uses the following encoding: utf-8

"""
Created by Elyjah <elyjah.kiyooka@cea.fr>, Jan 2022

"""

from qcodes.instrument import VisaInstrument
from qcodes import validators as vals
from qcodes.utils import DelayedKeyboardInterrupt
from qcodes.validators import ComplexNumbers

[docs] class Signalrecovery7270(VisaInstrument): """ This is the qcodes driver for the Ametex Signal Recovery Model 7270 DSP Lockin amplifier Note: ask_raw command has been rewritten (bottom) to also read an echo to remove from buffer. write_raw command have been rewritten to also read after writing using ask_raw. """ def __init__(self, name: str, address: str, terminator='\n\x00', **kwargs): super().__init__(name, address, terminator=terminator, device_clear = True, **kwargs) idn = self.IDN.get() self.model = idn['model'] self.add_parameter(name='x', label='Lock-In X', get_cmd='X.', get_parser=float, unit='V', vals = vals.Numbers(), docstring="Gets X lockin component in V; " "only gettable.") self.add_parameter('y', label='Lock-In Y', get_cmd='Y.', get_parser=float, unit='V', vals = vals.Numbers(), docstring="Gets Y lockin component in V; " "only gettable.") self.add_parameter('xy', label='Lock-In XY Complex', get_cmd=self._get_complex_voltage, unit='V', vals = ComplexNumbers(), docstring="Complex voltage parameter " "calculated from X, Y phase using " "Z = X + j*Y") self.add_parameter(name='r', label='Lock-In R', get_cmd='MAG.', get_parser=float, unit='V', vals = vals.Numbers(), docstring="Gets magnitude of XY lockin components in V; " "only gettable.") self.add_parameter(name='phase', label='Lock-In Phase', get_cmd='PHA.', get_parser=float, unit='Degrees', vals = vals.Numbers(), docstring="Gets the polar phase of lockin in degrees; " "only gettable.") self.add_parameter(name='frequency', label='Reference Frequency', get_cmd='FRQ.', get_parser=float, unit='Hz', vals = vals.Numbers(), docstring="Gets frequency of demodulator in Hz; " "only gettable.") self.add_parameter(name='osc_amplitude', label='Oscillator Amplitude', unit='V', set_cmd='OA. {}', set_parser=float, get_cmd='OA.', get_parser=float, vals=vals.Numbers(min_value=0, max_value=5), docstring="Get and set oscillator output amplitude in V;" "Output is in rms values" "gettable and settable.") self.add_parameter(name='osc_frequency', label='Oscillator Frequency', unit='Hz', set_cmd='OF. {}', set_parser=float, get_cmd='OF.', get_parser=float, vals=vals.Numbers(min_value=10, max_value=250000), docstring="Get and set oscillator output frequency in Hz; " "gettable and settable.") self.add_parameter(name='reference', label='Reference Input', get_cmd='IE', set_cmd='IE {}', val_mapping = {'INT': 0, 'EXT_rear': 1, 'EXT_front': 2}, docstring="Get and set which reference signal is used; " "gettable and settable.") self.add_parameter(name='noise_mode', label='Noise mode', get_cmd='NOISEMODE', set_cmd='NOISEMODE {}', initial_value='OFF', val_mapping = {'OFF': 0, 'ON': 1}, docstring=("Get and set the noise mode used. " "Should always leave off as it " "will change the values of TC " "and the low pass filter slope.")) self.add_parameter(name='I_mode', label='Current mode', get_cmd='IMODE', set_cmd='IMODE {}', val_mapping = {'CURRENT_MODE_OFF': 0, 'CURRENT_MODE_ON_HIGH_BW': 1, 'CURRENT_MODE_ON_LOW_BW': 2}, docstring=("Get and set if current or voltage is to be measured" "n Input mode" "0 Current mode off - voltage mode input enabled" "1 High bandwidth current mode enabled -" "connect signal to B (I) input connector" "2 Low noise current mode enabled -" "connect signal to B (I) input connector " "If n = 0 then the input configuration " "is determined by the VMODE command. " "If n > 0 then current mode " "is enabled irrespective of the VMODE setting.")) self.add_parameter(name='V_mode', label='Voltage mode', get_cmd='VMODE', set_cmd='VMODE {}', val_mapping = {'INPUTS_GNDED': 0, 'A_INPUT_ONLY': 1, '-B_INPUT_ONLY': 2, 'A_B_DIFFERENTIAL': 3}, docstring=("Get and set how the voltage is to be measured: " "INPUTS_GNDED:, 'A_INPUT_ONLY', '-B_INPUT_ONLY', or 'A-B DIFFERENTIAL.' " "Note that the IMODE command takes precedence over the VMODE command.")) self.add_parameter(name='osc_sync', label='Synchronize oscillator', get_cmd='SYNCOSC', set_cmd='SYNCOSC {}', initial_value='OFF', val_mapping = {'OFF': 0, 'ON': 1}, docstring=("Get and set if the oscillator synchronizes " "Syncs to the external reference signal " "can only be used in external reference mode.")) self.add_parameter(name='sensitivity', label='Sensitivity', unit='V', get_cmd='SEN', set_cmd='SEN {}', val_mapping={ 2e-9: 1, 5e-9: 2, 10e-9: 3, 20e-9: 4, 50e-9: 5, 100e-9: 6, 200e-9: 7, 500e-9: 8, 1e-6: 9, 2e-6: 10, 5e-6: 11, 10e-6: 12, 20e-6: 13, 50e-6: 14, 100e-6: 15, 200e-6: 16, 500e-6: 17, 1e-3: 18, 2e-3: 19, 5e-3: 20, 10e-3: 21, 20e-3: 22, 50e-3: 23, 100e-3: 24, 200e-3: 25, 500e-3: 26, 1: 27}, docstring=("Set measurement input sensitivity; " "only settable.")) self.add_parameter(name='timeconstant', label='Time constant', unit='s', get_cmd='TC', set_cmd='TC {}', val_mapping={ 10e-6: 0, 20e-6: 1, 50e-6: 2, 100e-6: 3, 200e-6: 4, 500e-6: 5, 1e-3: 6, 2e-3: 7, 5e-3: 8, 10e-3: 9, 20e-3: 10, 50e-3: 11, 100e-3: 12, 200e-3: 13, 500e-3: 14, 1: 15, 2: 16, 5: 17, 10: 18, 20: 19, 50: 20, 100: 21, 200: 22, 500: 23, 1e+3: 24, 2e+3: 25, 5e+3: 26, 10e+3: 27, 20e+3: 28, 50e+3: 29, 100e+3: 30}, docstring=("Set measurement time constant; " "only settable."))
[docs] def ask_raw(self, cmd:str) -> str: """ Reimplementaion of ask function to handle lockin echo. Args: cmd: Command to be sent (asked) to lockin. Raises: Runtimeerror: If the response does not end with the expected terminators '\\n\\x00' or '\\x00' Returns: str: Return string from lockin with terminator character stripped of. """ with DelayedKeyboardInterrupt(): self.visa_handle.clear() response = self.visa_handle.query(cmd) if response.endswith('\x00'): resp = response[:-1] if resp.endswith('\n'): return resp[:-1] else: return resp else: return response
[docs] def write_raw(self, cmd:str) -> None: """ Reimplementation of write function to handle lockin echo. Calls on ask_raw (defined above) to read echo. Args: cmd: Command to be sent (asked) to lockin. """ with DelayedKeyboardInterrupt(): status = self.ask_raw(cmd)
[docs] def get_idn(self): """ Rewrite default get_idn commmand since SR7270 uses different IDN command. vendor is hard input; model is called; serial and firmware remain unknown. Returns: Dict of 'vendor', 'model', 'serial', 'firmware' """ response = self.ask_raw('IDN?') idparts = ['Ametek', response, None, None] return dict(zip(('vendor', 'model', 'serial', 'firmware'), idparts))
def _get_complex_voltage(self) -> complex: """ Function to get XY lockin components and return a complex number. Returns: complex: x + j*y as one complex number """ XY = self.ask_raw('XY.') x = float(XY.split(',',1)[0]) y = float(XY.split(',',1)[1]) return x + 1j*y