Skip to content

Commit

Permalink
Merge pull request #73 from ThorstenGroh/feature/RohdeSchwarz_HMP
Browse files Browse the repository at this point in the history
Feature/Rohde&Schwarz HMP series
  • Loading branch information
jenshnielsen authored Sep 11, 2020
2 parents e79a5ff + 1841a63 commit 497f1ce
Show file tree
Hide file tree
Showing 6 changed files with 324 additions and 0 deletions.
176 changes: 176 additions & 0 deletions docs/examples/Rohde_Schwarz_HMP4040.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# QCoDeS Example with R&S HMP4040 Power Supply"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import qcodes as qc\n",
"import qcodes_contrib_drivers.drivers.RohdeSchwarz.HMP4040 as hmp4040"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create the instrument (in this case a HMP4040 connected via USB to the ASRL4::INSTR address)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Connected to: ROHDE&SCHWARZ HMP4040 (serial:101920, firmware:HW50020003/SW2.62) in 0.12s\n"
]
}
],
"source": [
"ps = hmp4040.RohdeSchwarzHMP4040('ps-1', 'ASRL4::INSTR')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can set voltage and/or current to any channel."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"ps.ch1.set_voltage.set(0.05)\n",
"ps.ch2.set_current.set(0.2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The set voltage and current can be read out."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.05\n",
"0.2\n"
]
}
],
"source": [
"print(ps.ch1.set_voltage.get())\n",
"print(ps.ch2.set_current.get())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Channel(s) should be turned on, as well as the master on/off"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"ps.ch1.state('ON')\n",
"ps.state('ON')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Voltage, current and power can be measured"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"V1= 0.05\n",
"I1= 0.005\n",
"P1= 0.00025\n"
]
}
],
"source": [
"print('V1=', ps.ch1.voltage.get())\n",
"print('I1=', ps.ch1.current.get())\n",
"print('P1=', ps.ch1.power.get())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And finally turned off"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"ps.ch1.state('OFF')\n",
"ps.state('OFF')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.7"
},
"nbsphinx": {
"execute": "never"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
9 changes: 9 additions & 0 deletions qcodes_contrib_drivers/drivers/RohdeSchwarz/HMP2020.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .private.HMP import _RohdeSchwarzHMP


class RohdeSchwarzHMP4040(_RohdeSchwarzHMP):
"""
This is the qcodes driver for the Rohde & Schwarz HMP2020 Power Supply
"""
def __init__(self, name, address, **kwargs):
super().__init__(name, address, model_no=2020, **kwargs)
9 changes: 9 additions & 0 deletions qcodes_contrib_drivers/drivers/RohdeSchwarz/HMP2030.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .private.HMP import _RohdeSchwarzHMP


class RohdeSchwarzHMP4040(_RohdeSchwarzHMP):
"""
This is the qcodes driver for the Rohde & Schwarz HMP2030 Power Supply
"""
def __init__(self, name, address, **kwargs):
super().__init__(name, address, model_no=2030, **kwargs)
9 changes: 9 additions & 0 deletions qcodes_contrib_drivers/drivers/RohdeSchwarz/HMP4030.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .private.HMP import _RohdeSchwarzHMP


class RohdeSchwarzHMP4030(_RohdeSchwarzHMP):
"""
This is the qcodes driver for the Rohde & Schwarz HMP4030 Power Supply
"""
def __init__(self, name, address, **kwargs):
super().__init__(name, address, model_no=4030, **kwargs)
9 changes: 9 additions & 0 deletions qcodes_contrib_drivers/drivers/RohdeSchwarz/HMP4040.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .private.HMP import _RohdeSchwarzHMP


class RohdeSchwarzHMP4040(_RohdeSchwarzHMP):
"""
This is the qcodes driver for the Rohde & Schwarz HMP4040 Power Supply
"""
def __init__(self, name, address, **kwargs):
super().__init__(name, address, model_no=4040, **kwargs)
112 changes: 112 additions & 0 deletions qcodes_contrib_drivers/drivers/RohdeSchwarz/private/HMP.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from qcodes import VisaInstrument, validators as vals
from qcodes import InstrumentChannel, ChannelList
from functools import partial


class RohdeSchwarzHMPChannel(InstrumentChannel):
def __init__(self, parent, name, channel):
super().__init__(parent, name)
self.channel = channel
self.max_current = self.get_max_current()

self._scpi_commands = {"set_voltage": "SOURce:VOLTage:LEVel:IMMediate:AMPLitude",
"set_current": "SOURce:CURRent:LEVel:IMMediate:AMPLitude",
"state": "OUTPut:STATe",
"voltage": "MEASure:SCALar:VOLTage:DC",
"current": "MEASure:SCALar:CURRent:DC"
}

self.add_parameter("set_voltage",
label='Target voltage output',
set_cmd=partial(self.send_cmd, "set_voltage"),
get_cmd=partial(self.send_cmd, "set_voltage", None),
get_parser=float,
unit='V',
vals=vals.Numbers(0, 32.050)
)
self.add_parameter("set_current",
label='Target current output',
set_cmd=partial(self.send_cmd, "set_current"),
get_cmd=partial(self.send_cmd, "set_current", None),
get_parser=float,
unit='A',
vals=vals.Numbers(0.5e-3, self.max_current)
)
self.add_parameter('state',
label='Output enabled',
set_cmd=partial(self.send_cmd, "state"),
get_cmd=partial(self.send_cmd, "state", None),
val_mapping={'ON': 1, 'OFF': 0},
vals=vals.Enum('ON', 'OFF')
)
self.add_parameter("voltage",
label='Measured voltage',
get_cmd=partial(self.send_cmd, "voltage", None),
get_parser=float,
unit='V',
)
self.add_parameter("current",
label='Measured current',
get_cmd=partial(self.send_cmd, "current", None),
get_parser=float,
unit='A',
)
self.add_parameter("power",
label='Measured power',
get_cmd=self._get_power,
get_parser=float,
unit='W',
)

def get_max_current(self):
if self.parent.model_no > 4000:
return 10
elif self.parent.model_no == 2020 and self.channel == 1:
return 10
return 5

def send_cmd(self, param, value):
self.write(f"INSTrument:NSELect {self.channel:d}")
if value is None:
return self.ask(f"{self._scpi_commands[param]}?")
else:
return self.write(f"{self._scpi_commands[param]} {value}")

def _get_power(self):
curr = float(self.send_cmd("current", None))
volt = float(self.send_cmd("voltage", None))
return curr * volt


class _RohdeSchwarzHMP(VisaInstrument):
"""
This is the general HMP Power Supply driver class that implements shared parameters and functionality
among all similar power supplies from Rohde & Schwarz.
This driver was written to be inherited from by a specific driver (e.g. HMP4040).
"""

def __init__(self, name, address, model_no, **kwargs):
super().__init__(name, address, terminator="\n", **kwargs)
self.model_no = model_no

self.add_parameter('state',
label='Output enabled',
set_cmd='OUTPut:GENeral {}',
get_cmd='OUTPut:GENeral?',
val_mapping={'ON': 1, 'OFF': 0},
vals=vals.Enum('ON', 'OFF')
)
# number of channels can be calculated from model number
num_channels = (self.model_no % 100) // 10
# channel-specific parameters
channels = ChannelList(self, "SupplyChannel", RohdeSchwarzHMPChannel, snapshotable=False)
for ch_num in range(1, num_channels + 1):
ch_name = "ch{}".format(ch_num)
channel = RohdeSchwarzHMPChannel(self, ch_name, ch_num)
channels.append(channel)
self.add_submodule(ch_name, channel)
channels.lock()
self.add_submodule("channels", channels)

self.connect_message()

0 comments on commit 497f1ce

Please sign in to comment.