See also

A Jupyter notebook version of this tutorial can be downloaded here.

Basic Sourcing and Measurement#

In this tutorial we will demonstrate basic sourcing and measurement operations for programming a QSM module. This includes sourcing voltage or current from a given module output and measuring the current on a given channel.

Setup#

First, we are going to import the required packages.

[ ]:
from __future__ import annotations

from qcodes.instrument import find_or_create_instrument

from qblox_instruments import Cluster, ClusterType

Scan For Clusters#

We scan for the available devices connected via ethernet using the Plug & Play functionality of the Qblox Instruments package (see Plug & Play for more info).

!qblox-pnp list

[ ]:
cluster_ip = "10.10.200.42"
cluster_name = "cluster0"

Connect to Cluster#

We now make a connection with the Cluster.

[ ]:
cluster: Cluster = find_or_create_instrument(
    Cluster,
    recreate=True,
    name=cluster_name,
    identifier=cluster_ip,
    dummy_cfg=(
        {
            2: ClusterType.CLUSTER_QCM,
            4: ClusterType.CLUSTER_QRM,
            6: ClusterType.CLUSTER_QCM_RF,
            8: ClusterType.CLUSTER_QRM_RF,
            10: ClusterType.CLUSTER_QTM,
            12: ClusterType.CLUSTER_QRC,
            16: ClusterType.CLUSTER_QSM,
        }
        if cluster_ip is None
        else None
    ),
)

cluster.reset()
print(cluster.get_system_status())

Get connected modules#

[ ]:
# QSM modules
modules = cluster.get_connected_modules(lambda mod: mod.is_qsm_type)
# This uses the module of the correct type with the lowest slot index
module = list(modules.values())[0]

We use the first and fifth channel of the QSM in loopback configuration throughout this tutorial.

Basic Voltage Sourcing#

All channels can be used as a voltage source within the range of -10V to 10V. As an example, we will set the output voltage of the first QSM channel (O1). We need to set the source mode to ground before we set a value for the cutoff filter,

[ ]:
module.io_channel0.source_mode("ground")
module.io_channel0.low_pass_filter_cutoff(
    10.0
)  # Adjust the low pass filter cut off as needed. The allowed values are 10 Hz, 10kHz and 250kHz.

With the low pass filter cut off is set, we can now start with sourcing the voltage as seen below:

[ ]:
module.io_channel0.source_mode(
    "v_source"
)  # Set the source mode to "v_source" in order to source voltage.
module.io_channel0.slew_rate(10.0)  # Adjust the slew rate as needed, between 0.019 V/s and 20 V/s.
module.io_channel0.coarse_voltage(0.05)  # Adjust the coarse voltage between -10 V and +10 V
module.io_channel0.fine_voltage(0.001)  # Adjust the fine voltage between 0 and 0.0025, if needed.
# Note: The coarse voltage and fine voltage settings are additive!

If the channel is connected to a voltage sensitive device that should not receive a higher voltage than a certain value, it is possible to set a safe voltage range for that channel. Once this setting is in place, the module output value will not be set outside the given range, even if prompted to do so.

[ ]:
module.io_channel0.set_safe_voltage_range(-0.1, 0.1)

# If you now try to set the output voltage to 5.0 for example, you will receive a ValueError:
try:
    module.io_channel0.coarse_voltage(5)
except ValueError:
    print("Stopped setting unsafe voltage!")

Basic Current Sourcing#

All channels on the QSM can also be used as a current source with range of -50 mA up to +50 mA. In this part of the tutorial, we modify the setup by connecting the first channel of the QSM to a resistor of choice to showcase the functionality of current sourcing. In this tutorial, a 250 \(\omega\) was used. Once the setup is complete, for current sourcing we need to change the source_mode() to source current i.e.:

[ ]:
module.io_channel0.source_mode(
    "i_source"
)  # Set the source mode to `i_source` to source current on QSM O1.

The value of the source current depends on the given load through which it passes. In this setup, we have the resistance of 250 \(\omega\), thus the current is set to

[ ]:
module.io_channel0.set_current_wait(
    5.5e-4
)  # Set current to 0.55 mA and wait until the current has settled.

To confirm if the source current value matches with set current, one can directly measure the reflection of the current by executing the following:

[ ]:
module.io_channel0.measure_current()

More on current measurement is presented in the next section of the tutorial.

If the channel is connected to a device that is sensitive to certain currents, then a safe current range (similar to setting a safe voltage range) can be set for each IO channel. This ensures that the current sourced to the device is within its threshold.

[ ]:
module.io_channel0.set_safe_current_range(-1e-5, 1e-5)

# The QSM will not accept the current value that does not satisfy the given range:
try:
    module.io_channel0.set_current_wait(3.15e-4)
except ValueError:
    print("Unsafe current was used!")

Basic Current Measurement#

For current measurement, one must keep in mind that the output impendance of a QSM channel is 2 \(\Omega\), and that the maximum current that can be safely provided to a channel is 50mA.

[ ]:
try:
    module.io_channel4.source_mode(
        "ground"
    )  # Ground the current measurement path internally for accuracy.
    module.io_channel4.measure_mode(
        "automatic"
    )  # Available measure modes are "automatic", "coarse", "fine_nanoampere" and "fine_picoampere". The automatic mode will choose the applicable option based on sourced voltage or current.
    module.io_channel4.integration_time(
        10e-3
    )  # Adjust the integration time between 10 microseconds and 10 seconds.
    module.io_channel4.measure_current()
except TypeError:
    pass  # Workaround for known issue with dummy module.

Additional Functionalities#

It is possible block execution until the voltage value that is set at the output of a channel is stabilized. The rate in which the output stabilizes is governed by the slew rate.

[ ]:
module.io_channel0.set_voltage_wait(0.075)

It is possible to bypass the slew rate that was set for a channel output to immediately set the voltage output to a desired value.

[ ]:
module.io_channel0.set_voltage_instant(0.0)

It is possible to obtain the current configuration of a given channel.

[ ]:
module.io_channel0.get_io_channel_config()

Similarly, it is possible to define such a dictionary as desired and set it as the new channel configuration.

[ ]:
settings = {
    "channel": 0,
    "coarse_voltage": 0.1,
    "fine_voltage": 0.0005,
    "integration_time": 0.1,
    "low_pass_filter_cutoff": 10000,
    "measure_mode": "coarse",
    "slew_rate": 1.0,
    "source_mode": "v_source",
}
module.io_channel0.set_io_channel_config(settings)

This functionality can be verified by printing out an updated snapshot of the channel parameters.

[ ]:
module.io_channel0.print_readable_snapshot(update=True)