From 03cc8c934cbb78694694e4f4f16eb312e4b24e53 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 11 Nov 2026 14:32:47 +0100 Subject: [PATCH 1/3] Add GPIB::3 and GPIB::4 resources to Keithley 2600 sim file Instruments sharing a pyvisa-sim address share state, so more addresses are needed to simulate several independent Keithley 2600 instruments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../newsfragments/99999.improved_driver | 2 + src/qcodes/instrument/sims/Keithley_2600.yaml | 6 +++ tests/drivers/test_keithley_26xx.py | 39 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 docs/changes/newsfragments/99999.improved_driver diff --git a/docs/changes/newsfragments/99999.improved_driver b/docs/changes/newsfragments/99999.improved_driver new file mode 100644 index 000000000000..16dba3836cd6 --- /dev/null +++ b/docs/changes/newsfragments/99999.improved_driver @@ -0,0 +1,2 @@ +The `Keithley_2600.yaml` pyvisa-sim file now also defines the resources `GPIB::3::INSTR` and `GPIB::4::INSTR`, +so that up to four simulated Keithley 2600 instruments with independent state can be used at the same time. diff --git a/src/qcodes/instrument/sims/Keithley_2600.yaml b/src/qcodes/instrument/sims/Keithley_2600.yaml index 7086d4432205..2c2606d82698 100644 --- a/src/qcodes/instrument/sims/Keithley_2600.yaml +++ b/src/qcodes/instrument/sims/Keithley_2600.yaml @@ -203,3 +203,9 @@ resources: GPIB::2::INSTR: device: Keithley + + GPIB::3::INSTR: + device: Keithley + + GPIB::4::INSTR: + device: Keithley diff --git a/tests/drivers/test_keithley_26xx.py b/tests/drivers/test_keithley_26xx.py index 0ddfd44b6d1c..ceee8e4c9844 100644 --- a/tests/drivers/test_keithley_26xx.py +++ b/tests/drivers/test_keithley_26xx.py @@ -47,6 +47,45 @@ def test_idn(driver: Keithley2614B) -> None: } == driver.IDN() +@pytest.fixture(scope="function", name="drivers_at_gpib_3_and_4") +def _make_drivers_at_gpib_3_and_4() -> ( + "Generator[tuple[Keithley2614B, Keithley2614B], None, None]" +): + driver_3 = Keithley2614B( + "Keithley_2600_3", + address="GPIB::3::INSTR", + pyvisa_sim_file="Keithley_2600.yaml", + ) + try: + driver_4 = Keithley2614B( + "Keithley_2600_4", + address="GPIB::4::INSTR", + pyvisa_sim_file="Keithley_2600.yaml", + ) + except Exception: + driver_3.close() + raise + + yield driver_3, driver_4 + driver_3.close() + driver_4.close() + + +def test_additional_sim_addresses_have_independent_state( + drivers_at_gpib_3_and_4: "tuple[Keithley2614B, Keithley2614B]", +) -> None: + driver_3, driver_4 = drivers_at_gpib_3_and_4 + + assert driver_3.IDN()["model"] == "2601B" + assert driver_4.IDN()["model"] == "2601B" + + driver_3.smua.volt(1.5) + driver_4.smua.volt(-0.5) + + assert driver_3.smua.volt() == 1.5 + assert driver_4.smua.volt() == -0.5 + + def test_smu_channels_and_their_parameters(driver: Keithley2614B) -> None: assert {"smua", "smub"} == set(driver.submodules.keys()) From a4e4a51da837239627f8789275aa9ad888907943 Mon Sep 17 00:00:00 2001 From: "Jens H. Nielsen" Date: Wed, 11 Nov 2026 14:39:35 +0100 Subject: [PATCH 2/3] Test four simultaneous simulated Keithley 2600 instruments Replace the GPIB::3/GPIB::4 test with one that opens Keithley2600 instruments on GPIB::1-4 at once and checks each keeps its own smua.volt value. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/drivers/test_keithley_26xx.py | 57 +++++++++++------------------ 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/tests/drivers/test_keithley_26xx.py b/tests/drivers/test_keithley_26xx.py index ceee8e4c9844..9995f7d6603c 100644 --- a/tests/drivers/test_keithley_26xx.py +++ b/tests/drivers/test_keithley_26xx.py @@ -8,6 +8,7 @@ from qcodes.dataset import LinSweep from qcodes.instrument_drivers.Keithley import ( + Keithley2600, Keithley2600MeasurementStatus, Keithley2614B, ) @@ -47,43 +48,27 @@ def test_idn(driver: Keithley2614B) -> None: } == driver.IDN() -@pytest.fixture(scope="function", name="drivers_at_gpib_3_and_4") -def _make_drivers_at_gpib_3_and_4() -> ( - "Generator[tuple[Keithley2614B, Keithley2614B], None, None]" -): - driver_3 = Keithley2614B( - "Keithley_2600_3", - address="GPIB::3::INSTR", - pyvisa_sim_file="Keithley_2600.yaml", - ) +def test_four_sim_addresses_have_independent_state() -> None: + voltages = {1: 1.5, 2: -0.5, 3: 0.25, 4: 2.0} + drivers: list[Keithley2600] = [] try: - driver_4 = Keithley2614B( - "Keithley_2600_4", - address="GPIB::4::INSTR", - pyvisa_sim_file="Keithley_2600.yaml", - ) - except Exception: - driver_3.close() - raise - - yield driver_3, driver_4 - driver_3.close() - driver_4.close() - - -def test_additional_sim_addresses_have_independent_state( - drivers_at_gpib_3_and_4: "tuple[Keithley2614B, Keithley2614B]", -) -> None: - driver_3, driver_4 = drivers_at_gpib_3_and_4 - - assert driver_3.IDN()["model"] == "2601B" - assert driver_4.IDN()["model"] == "2601B" - - driver_3.smua.volt(1.5) - driver_4.smua.volt(-0.5) - - assert driver_3.smua.volt() == 1.5 - assert driver_4.smua.volt() == -0.5 + for gpib_address in voltages: + drivers.append( + Keithley2600( + f"Keithley_2600_{gpib_address}", + address=f"GPIB::{gpib_address}::INSTR", + pyvisa_sim_file="Keithley_2600.yaml", + ) + ) + + for driver, voltage in zip(drivers, voltages.values(), strict=True): + driver.smua.volt(voltage) + + for driver, voltage in zip(drivers, voltages.values(), strict=True): + assert driver.smua.volt() == voltage + finally: + for driver in drivers: + driver.close() def test_smu_channels_and_their_parameters(driver: Keithley2614B) -> None: From 50d0568090369dd9ce5426637899f7b877ef9371 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Wed, 11 Nov 2026 14:44:03 +0100 Subject: [PATCH 3/3] Rename 99999.improved_driver to 8756.improved_driver --- .../newsfragments/{99999.improved_driver => 8756.improved_driver} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/changes/newsfragments/{99999.improved_driver => 8756.improved_driver} (100%) diff --git a/docs/changes/newsfragments/99999.improved_driver b/docs/changes/newsfragments/8756.improved_driver similarity index 100% rename from docs/changes/newsfragments/99999.improved_driver rename to docs/changes/newsfragments/8756.improved_driver