This page was generated from docs/examples/driver_examples/Qcodes example with Keysight 34980A Switch Mainframe and Modules.ipynb. Interactive online version: Binder badge.

QCoDeS Example with Keysight 34980A Multifunction Switch / Measure Mainframe and Modules

Instrument Short info

The 34980A Multifunction Switch / Measure Unit is a compact, economical, one-box solution for medium to high-density switch/measure applications. It requires different types of modules, such as Matrix Modules, Multiplexer Modules, and RF & Microwave Modules, for different applications. In this example notebook, I’ll forcus on the Matrix Modules.

There are four different Matrix Modules, 34931A, 34932A, 34933A, and 34934A. Each can be configured into different layout, such as 4x8, 8x32 matrix. In this example notebook, two 34934A modules are connected to slot 1 and slot 2 of the 34980A system.

Each 34934A module is configured into a 8x64 matrix (8 rows, 64 columns), and connected with each other by rows. As a result, they form a 8x128 matrix (8 rows, 128 columns).

[1]:
from IPython.display import Markdown, display
from pyvisa.errors import VisaIOError

from qcodes.instrument_drivers.Keysight import Keysight34980A
[2]:
# instantiate the Swith Matrix
try:
    switch_matrix = Keysight34980A("swmx", "TCPIP0::1.1.1.1::inst0::INSTR")
    print('using physical instrument')
except (ValueError, VisaIOError):
    # Below is an example how to set up the mock instrument

    switch_matrix = Keysight34980A('switch_matrix_sim',
                                   address='GPIB::1::INSTR',
                                   pyvisa_sim_file="keysight_34980A.yaml")
    display(Markdown("""**Note: using simulated instrument.**

Due to limitations in pyvisa-sim the behavior will be different. See the keysight_34980A.yaml file for more detial."""))
[swmx(Keysight34980A)] Could not connect at TCPIP0::1.1.1.1::inst0::INSTR
Traceback (most recent call last):
  File "C:\Users\jenielse\source\repos\Qcodes\qcodes\instrument\visa.py", line 116, in _connect_and_handle_error
    visa_handle, visabackend = self._open_resource(address, visalib)
  File "C:\Users\jenielse\source\repos\Qcodes\qcodes\instrument\visa.py", line 139, in _open_resource
    resource_manager = pyvisa.ResourceManager()
  File "C:\Users\jenielse\Miniconda3\envs\qcodespip310\lib\site-packages\pyvisa\highlevel.py", line 2992, in __new__
    visa_library = open_visa_library(visa_library)
  File "C:\Users\jenielse\Miniconda3\envs\qcodespip310\lib\site-packages\pyvisa\highlevel.py", line 2899, in open_visa_library
    wrapper = _get_default_wrapper()
  File "C:\Users\jenielse\Miniconda3\envs\qcodespip310\lib\site-packages\pyvisa\highlevel.py", line 2858, in _get_default_wrapper
    raise ValueError(
ValueError: Could not locate a VISA implementation. Install either the IVI binary or pyvisa-py.
WARNING:root:For slot 3, no configuration moduleconnected, or safety interlock jumper removed. Making any connection is not allowed
Connected to: Keysight 34980A (serial:1000, firmware:0.1) in 0.06s

Note: using simulated instrument.

Due to limitations in pyvisa-sim the behavior will be different. See the keysight_34980A.yaml file for more detial.

[3]:
# show the module information for each occupied slot
switch_matrix.system_slots_info
[3]:
{1: {'vendor': 'Agilent Technologies',
  'model': '34934A-8x64',
  'serial': 'MY56480560',
  'firmware': '1.01'},
 2: {'vendor': 'Agilent Technologies',
  'model': '34934A-8x64',
  'serial': 'MY56480559',
  'firmware': '1.01'}}

Each module is defined as an instance of the submodule class. To access the module in slot n, use the following:

switch_matrix.module[n]

where n is the slot number

[4]:
# to access the module installed in slot 1:
switch_matrix.module[1]
[4]:
<Keysight34934A: swmx_slot_1_34934A of Keysight34980A: swmx>
[5]:
# to access the module installed in slot 2:
switch_matrix.module[2]
[5]:
<Keysight34934A: swmx_slot_2_34934A of Keysight34980A: swmx>

It is also possible to access each module via the following:

[6]:
# to access the module installed in slot 1:
switch_matrix.slot_1_34934A
[6]:
<Keysight34934A: swmx_slot_1_34934A of Keysight34980A: swmx>
[7]:
# to access the module installed in slot 1:
switch_matrix.slot_2_34934A
[7]:
<Keysight34934A: swmx_slot_2_34934A of Keysight34980A: swmx>

Basic Switch control, module level

For each module, any of the 8 row can be connected to any of the 64 column.

[8]:
switch_matrix.module[1].connect(2, 34)     # connect row 2 to column 34, , for module in slot 1
print(switch_matrix.module[1].is_closed(2, 34)) # check if row 2 is connected to column 34
True
[9]:
switch_matrix.slot_1_34934A.disconnect(2, 34)  # disconnect row 2 from column 34, for module in slot 1
print(switch_matrix.module[1].is_open(2, 34))   # check if row 2 is disconnect from column 34
True
[10]:
switch_matrix.module[2].connect(3, 45)     # connect row 3 to column 45, , for module in slot 2
print(switch_matrix.module[2].is_closed(3, 45)) # check if row 3 is connected to column 45
True

We expect the following command to raise an exception because the column value 67 is out of range for module in slot 1.

[11]:
try:
    switch_matrix.module[1].connect(5, 67)
except ValueError as err:
    print(err)
row/column value out of range

Because the two 8x64 matrices are connected by row to form a 8x128 matrix, user should convert column 67 to the correct column in the second module: 67-64=3, then use the connect function of module in slot 2:

switch_matrix.module_in_slot[2].connect_path(5, 3)

[12]:
switch_matrix.module[2].connect(5, 3)
print(switch_matrix.module[2].is_closed(5, 3))
True

To connect multiple channels: (again, the channels should belong to the one module)

[13]:
connections = [(3, 14), (1, 59), (2, 6)]
switch_matrix.module[2].connect_paths(connections)
print(switch_matrix.module[2].are_closed(connections))
[True, True, True]
[14]:
switch_matrix.module[2].disconnect_paths(connections)
print(switch_matrix.module[2].are_open(connections))
[True, True, True]

About safety interlock

The Safety Interlock feature prevents connections to the Analog Buses if no terminal block or properly-wired cable is connected to the module. When a module is in safety interlock state, all the channels are disconnected/open, user can not connect/close any channels.

In the event of safety interlock, there will be a warning message. In the following example I manually changed the flag, DO NOT do this in the real situation.

[15]:
switch_matrix.module[2]._is_locked = True # DO NOT perform this action in real situation
[16]:
switch_matrix.module[2].connect(1,2)
WARNING:root:Warning: no configuration module connected, or safety interlock enabled. Making any connection is not allowed

Actions which make not atempt to connect any channels are still work:

[17]:
switch_matrix.module[2].is_open(3,4)
[17]:
True

For module 34934A only

There is a relay protection mode for 34934A module. The fastest switching speeds for relays in a given signal path are achieved using the FIXed or ISOlated modes, followed by the AUTO100 and AUTO0 modes. There may be a maximum of 200 Ohm of resistance, which can only be bypassed by “AUTO0” mode. See user’s guide and programmer’s reference for detailed explanation.

[18]:
# to see the current protection mode of the module in slot 1:
switch_matrix.module[1].protection_mode()
[18]:
'AUTO100'
[19]:
# to set the protection mode to 'AUTO0', for module in slot 1:
switch_matrix.module[1].protection_mode('AUTO0')
switch_matrix.module[1].protection_mode()
[19]:
'AUTO0'

Basic Switch control, instrument level

We can disconnect all the channels in a certain module, or all the installed modules

[20]:
# to disconnect the channels in module installed in slot 1
switch_matrix.disconnect_all(1)
[21]:
# to disconnect the channels in all installed modules
switch_matrix.disconnect_all()

So, when to use connect, connect_paths, is_closed, or are_closed?

Yes, it seem very confusing because of the path/paths, and is/are.

The reason for the singular/plural is that the module can work with one row and column pair (r, c), or a list of row and column pairs [(r1, c1), (r2, c2)].

When work with single row-column pair, use the singular version of functions - instrument.module.connect(r, c) - instrument.module.is_closed(r,c)

When work with list of row-column pairs, use the plural version of functions - instrument.module.connect_paths([(r1, c1), (r2, c2)]) - instrument.module.are_closed([(r1, c1), (r2, c2)])

[ ]: