-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Rigol and Keithley driver classes
- Loading branch information
TNO-Helios
committed
Dec 5, 2024
1 parent
91c7dc4
commit a1a3f59
Showing
2 changed files
with
248 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
from qcodes import VisaInstrument | ||
from qcodes.utils.validators import Numbers | ||
|
||
class RigolDP932E(VisaInstrument): | ||
""" | ||
QCoDeS driver for the Rigol DP932E Programmable DC Power Supply. | ||
""" | ||
|
||
def __init__(self, name: str, address: str, **kwargs): | ||
super().__init__(name, address, **kwargs) | ||
|
||
# Add parameters for each channel | ||
for channel in range(1, 4): | ||
self.add_parameter(f'voltage_{channel}', | ||
label=f'Channel {channel} Voltage', | ||
unit='V', | ||
get_cmd=f':MEASure:VOLTage? CH{channel}', | ||
set_cmd=f':APPLy CH{channel},{{}}', | ||
get_parser=float, | ||
vals=Numbers(0, 31.5)) # According to manual, max voltage is 31.5V for DP932E | ||
|
||
self.add_parameter(f'current_{channel}', | ||
label=f'Channel {channel} Current', | ||
unit='A', | ||
get_cmd=f':MEASure:CURRent? CH{channel}', | ||
set_cmd=f':APPLy CH{channel},,,{{}}', | ||
get_parser=float, | ||
vals=Numbers(0, 3.15)) # According to manual, max current is 3.15A for DP932E | ||
|
||
self.add_parameter(f'output_{channel}', | ||
label=f'Channel {channel} Output', | ||
get_cmd=f':OUTPut:STATe? CH{channel}', | ||
set_cmd=f':OUTPut:STATe {{}} CH{channel}', | ||
val_mapping={'ON': 1, 'OFF': 0}) | ||
|
||
# Reset the instrument | ||
self.write('*RST') | ||
self.connect_message() | ||
|
||
def reset(self): | ||
"""Resets the instrument to its default settings.""" | ||
self.write('*RST') | ||
|
||
def enable_output(self, channel: int): | ||
"""Enables the output for the specified channel.""" | ||
self.write(f':OUTPut CH{channel},ON') | ||
|
||
def disable_output(self, channel: int): | ||
"""Disables the output for the specified channel.""" | ||
self.write(f':OUTPut CH{channel},OFF') | ||
|
||
def measure_voltage(self, channel: int) -> float: | ||
"""Measures the voltage at the output terminal of the specified channel.""" | ||
return float(self.ask(f':MEASure:VOLTage? CH{channel}')) | ||
|
||
def measure_current(self, channel: int) -> float: | ||
"""Measures the current at the output terminal of the specified channel.""" | ||
return float(self.ask(f':MEASure:CURRent? CH{channel}')) | ||
|
||
def set_voltage(self, channel: int, voltage: float): | ||
"""Sets the output voltage for the specified channel.""" | ||
self.write(f':APPLy CH{channel},{voltage}') | ||
|
||
def set_current(self, channel: int, current: float): | ||
"""Sets the output current for the specified channel.""" | ||
self.write(f':APPLy CH{channel},,,{current}') | ||
|
||
def set_output_state(self, channel: int, state: str): | ||
"""Sets the output state (ON/OFF) for the specified channel.""" | ||
self.write(f':OUTPut:STATe {state},CH{channel}') | ||
|
||
def measure_power(self, channel: int) -> float: | ||
"""Measures the power at the output terminal of the specified channel.""" | ||
return float(self.ask(f':MEASure:POWEr? CH{channel}')) | ||
|
173 changes: 173 additions & 0 deletions
173
src/qcodes_contrib_drivers/drivers/Tektronix/Keithley_2401.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
from qcodes import VisaInstrument | ||
from qcodes.utils.validators import Numbers | ||
import numpy as np | ||
import time | ||
|
||
|
||
class Keithley2400(VisaInstrument): | ||
""" | ||
QCoDeS driver for Keithley 2400 SourceMeter. | ||
Provides functionality for sourcing and measuring voltage, current, and resistance. | ||
Includes support for voltage sweeps and detailed parameter configuration. | ||
""" | ||
|
||
def __init__(self, name: str, address: str, **kwargs): | ||
""" | ||
Initialize the Keithley 2400 SourceMeter. | ||
Args: | ||
name (str): Name of the instrument. | ||
address (str): Visa address of the instrument. | ||
""" | ||
super().__init__(name, address, terminator='\n', **kwargs) | ||
|
||
# Parameters | ||
self.add_parameter( | ||
'voltage', | ||
label='Set Voltage', | ||
unit='V', | ||
get_cmd=':SOUR:VOLT:LEV:IMM:AMPL?', | ||
set_cmd=':SOUR:VOLT:LEV:IMM:AMPL {:.4f}', | ||
get_parser=float, | ||
vals=Numbers(-210, 210) | ||
) | ||
|
||
self.add_parameter( | ||
'current', | ||
label='Measured Current', | ||
unit='A', | ||
get_cmd=self._measure_current | ||
) | ||
|
||
self.add_parameter( | ||
'set_current', | ||
label='Set Current', | ||
unit='A', | ||
get_cmd=':SOUR:CURR:LEV:IMM:AMPL?', | ||
set_cmd=':SOUR:CURR:LEV:IMM:AMPL {:.4f}', | ||
get_parser=float, | ||
vals=Numbers(-1.05, 1.05) # Adjust the range based on the Keithley 2400 specs | ||
) | ||
|
||
self.add_parameter( | ||
'measured_voltage', | ||
label='Measured Voltage', | ||
unit='V', | ||
get_cmd=self._measure_voltage | ||
) | ||
|
||
self.add_parameter( | ||
'resistance', | ||
label='Measured Resistance', | ||
unit='Ohm', | ||
get_cmd=self._measure_resistance | ||
) | ||
|
||
self.add_parameter( | ||
'output', | ||
label='Output State', | ||
get_cmd=':OUTP?', | ||
set_cmd=':OUTP {}', | ||
val_mapping={'on': 1, 'off': 0} | ||
) | ||
|
||
self.add_parameter( | ||
'current_range', | ||
label='Current Range', | ||
get_cmd=':SENS:CURR:RANG?', | ||
set_cmd=':SENS:CURR:RANG {:.4f}', | ||
get_parser=float, | ||
vals=Numbers(1e-9, 1e1) | ||
) | ||
|
||
self.add_parameter( | ||
'auto_range', | ||
label='Auto Range', | ||
get_cmd=':SENS:CURR:RANG:AUTO?', | ||
set_cmd=':SENS:CURR:RANG:AUTO {}', | ||
val_mapping={True: 'ON', False: 'OFF'} | ||
) | ||
|
||
self.add_parameter( | ||
'sweep_voltage', | ||
label='Sweep Voltage', | ||
unit='V', | ||
set_cmd=self.set_voltage | ||
) | ||
|
||
self.connect_message() | ||
|
||
def _measure_voltage(self): | ||
""" | ||
Measure the voltage in the selected range or auto-range. | ||
Returns: | ||
float: Measured voltage in volts. | ||
""" | ||
self.write(':FUNC "VOLT"') | ||
self.write(':FORM:ELEM VOLT') | ||
response = self.ask(':READ?') | ||
return float(response) | ||
|
||
def _measure_current(self): | ||
""" | ||
Measure the current in the selected range or auto-range. | ||
Returns: | ||
float: Measured current in amperes. | ||
""" | ||
self.write(':FUNC "CURR"') | ||
self.write(':FORM:ELEM CURR') | ||
response = self.ask(':READ?') | ||
return float(response) | ||
|
||
def _measure_resistance(self): | ||
""" | ||
Measure the resistance in the selected range. | ||
Returns: | ||
float: Measured resistance in ohms. | ||
""" | ||
self.write(':FUNC "RES"') | ||
self.write(':FORM:ELEM RES') | ||
response = self.ask(':READ?') | ||
return float(response) | ||
|
||
def enable_output(self, state: bool = True): | ||
""" | ||
Enable or disable the output. | ||
Args: | ||
state (bool): Set True to enable, False to disable. | ||
""" | ||
self.output('on' if state else 'off') | ||
|
||
def set_voltage(self, voltage: float): | ||
""" | ||
Set the output voltage. | ||
Args: | ||
voltage (float): The voltage level to set in volts. | ||
""" | ||
self.voltage(voltage) | ||
|
||
def sweep_voltage_measure(self, voltage_start: float, voltage_stop: float, steps: int): | ||
""" | ||
Sweep voltage from start to stop in specified steps and measure voltage and current. | ||
Args: | ||
voltage_start (float): Starting voltage. | ||
voltage_stop (float): Ending voltage. | ||
steps (int): Number of steps. | ||
Returns: | ||
list of dict: Contains 'voltage_set', 'voltage_measured', and 'current_measured'. | ||
""" | ||
voltage_values = np.linspace(voltage_start, voltage_stop, steps) | ||
measurements = [] | ||
self.write(':FUNC "VOLT","CURR"') | ||
self.write(':FORM:ELEM VOLT,CURR') | ||
|
||
for voltage in voltage_values: | ||
self.voltage(voltage) | ||
time.sleep(0.1) # Allow settling | ||
response = self.ask(':READ?') | ||
voltage_measured, current_measured = map(float, response.split(',')) | ||
measurements.append({ | ||
'voltage_set': voltage, | ||
'voltage_measured': voltage_measured, | ||
'current_measured': current_measured | ||
}) | ||
return measurements |