Skip to content

feat(awg): add keysight 33500b awg driver - #359

Draft
LizzyC-115 wants to merge 10 commits into
mainfrom
lizzychanpaibool/instro-540-add-keysight-33500b-awg-driver
Draft

feat(awg): add keysight 33500b awg driver#359
LizzyC-115 wants to merge 10 commits into
mainfrom
lizzychanpaibool/instro-540-add-keysight-33500b-awg-driver

Conversation

@LizzyC-115

Copy link
Copy Markdown
Contributor

Summary

Adding support for a new AWG device. This PR builds on the AWGBaseDriver and InstroAWG framework already in main and implements those functions for the Keysight 33500B series.

Type of change

  • Bug fix (fix)
  • New feature (feat)
  • Breaking change (feat! / fix!)
  • Refactor (refactor)
  • Documentation (docs)
  • Chore / tooling (chore)

Verification

Screenshot 2026-08-06 at 12 48 21 PM Screenshot 2026-08-06 at 12 48 59 PM

Tests

  • Unit tests added or updated
  • Existing tests cover this change
  • No tests — explain why:

Checklist

  • PR title follows Conventional Commits (e.g. feat(driver): add support for Keysight E36300)
  • I have read CONTRIBUTING.md
  • Documentation updated if user-facing behavior changed
  • Code follows the style/conventions of the surrounding code

@mintlify

mintlify Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
instro 🟢 Ready View Preview Aug 6, 2026, 5:19 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@LizzyC-115
LizzyC-115 force-pushed the lizzychanpaibool/instro-540-add-keysight-33500b-awg-driver branch from e8b7795 to 0dad42b Compare August 6, 2026 17:24
@LizzyC-115
LizzyC-115 marked this pull request as ready for review August 6, 2026 17:31
@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown

PR author is not in the allowed authors list.

@LizzyC-115
LizzyC-115 requested a review from nhschwab August 6, 2026 17:34
@LizzyC-115
LizzyC-115 marked this pull request as draft August 6, 2026 18:47
@LizzyC-115 LizzyC-115 linked an issue Aug 6, 2026 that may be closed by this pull request
@claude

claude Bot commented Aug 6, 2026

Copy link
Copy Markdown

Claude finished @LizzyC-115's task in 2m 46s —— View job


Review complete

Tasks

  • Gather context (PR diff, AGENTS.md/CONTRIBUTING.md conventions)
  • Run /code-review --comment over the diff
  • Post review findings

Overview

Keysight33500B mirrors the existing RigolDG1022Z shape closely: composes VisaDriver (accepts str | VisaConfig), owns its own lifecycle/state (_arb_waveforms, _channel_mod_types), keeps a per-driver check_errors/duplicated _check_channel, and doesn't leak any shared abstraction into AWGDriverBase. Registration (drivers/__init__.py), docs (README table, awg.mdx, docs/reference/src/instruments/awg.md), and the mocked-transport + hardware test pair all follow established repo conventions — no structural concerns. Test suite size (572 lines) is in line with the Rigol precedent (583 lines), not excessive for the number of waveform/modulation branches covered.

One inline nit posted:

  • packages/instro-unstable/instro/unstable/awg/types.py:13 — a whitespace-only change unrelated to this PR (turns a blank line into one with trailing spaces). Likely an accidental edit; should be reverted per scope discipline.

No other defects, convention divergences, or missing coverage found. Nice work matching the existing driver pattern closely.

Comment thread packages/instro-unstable/instro/unstable/awg/types.py Outdated
@LizzyC-115 LizzyC-115 changed the title driver: add keysight 33500b awg driver feat(awg): add keysight 33500b awg driver Aug 6, 2026
self._visa.write(f"{prefix}:PHAS {magnitude}")
else:
raise AssertionError(f"unhandled ModulationType {mod_type}")
self._visa.write(f"{prefix}:STAT ON")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keysight 33500B require it's SCPI commands to use the modulation type to enable modulation. However, there is no "query for modulation type" SCPI command. The most we can do is check if a modulation type if ON. So, to avoid having software states, choosing to enable modulation in the set_modulation function where the modulation type is unambiguous and force modulation_enable() to disable only.

Comment on lines +228 to +238
"""Disables modulation"""
_check_channel(channel)
if enable:
raise ValueError(
"the Keysight 33500B enables modulation as part of set_modulation;"
" modulation_enable only supports disabling (enable=False)"
)
with self._visa.lock():
for prefix in _MOD_SCPI_PREFIX.values():
self._visa.write(f"{prefix}:STAT OFF")
self.check_errors()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Echoing from above function: Keysight 33500B require it's SCPI commands to use the modulation type to enable modulation. However, there is no "query for modulation type" SCPI command. The most we can do is check if a modulation type if ON. So, to avoid having software states, choosing to enable modulation in the set_modulation function where the modulation type is unambiguous and force modulation_enable() to disable only.

@LizzyC-115
LizzyC-115 marked this pull request as ready for review August 7, 2026 15:05
@claude

claude Bot commented Aug 7, 2026

Copy link
Copy Markdown

Claude finished @LizzyC-115's task in 3m 20s —— View job


Reviewing PR #359

  • Gather context (PR diff since prior review, AGENTS.md conventions)
  • Re-run /code-review --comment over the current diff
  • Post review findings

Overview

Re-reviewed after the modulation logic update (commits 0dad42b..1195ceb). The prior whitespace nit in types.py:13 is resolved (clean blank line now). No new inline comments — the driver still mirrors RigolDG1022Z's shape and conventions cleanly.

One design note worth surfacing (not a defect): Keysight33500B.modulation_enable only accepts enable=False and raises ValueError on Trueset_modulation enables as a side effect instead. This is a genuine hardware constraint, not scope creep: the 33500B has independent AM:STAT/FM:STAT/etc. per modulation type with no MOD:TYP query (unlike the Rigol, which has :SOUR{ch}:MOD:TYP?), so there's no unambiguous way to re-enable a specific type without re-specifying it — confirmed against rigol_dg1022z.py:219,228-232. AWGDriverBase.modulation_enable is an optional (NotImplementedError-by-default) method, so this doesn't violate the base contract, and the restriction is enforced with a clear error message and covered by both the software test (test_33) and hardware test (test_21). Reasonable given the instrument's actual SCPI surface.

Checked: driver registration (drivers/__init__.py import + __all__), VisaDriver composition (str | VisaConfig), per-driver check_errors, docs sync (README, awg.mdx, docs/reference/src/instruments/awg.md), reentrant visa.lock() usage in set_modulationget_waveform (confirmed RLock, no deadlock), and wire-level test coverage for all six modulation types plus the enable/disable and query paths. No structural or convention issues found.

@LizzyC-115
LizzyC-115 marked this pull request as draft August 7, 2026 18:26
Comment on lines -43 to -46
@abc.abstractmethod
def check_errors(self) -> None:
"""Check the instrument error queue."""

@LizzyC-115 LizzyC-115 Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file only contains removals of check errors. The reasoning for this change was detailed in this issue here: #369

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

driver: add Keysight 33500B AWG driver

1 participant