← Back to overview
Student Tasks

Workshop Track Assignments

Detailed Python, PyTestLab, and instrumentation challenges to keep every team on track.

No DUT required — loop the AWG to the oscilloscope via BNC. PSU and DMM available for cross-checks.

Lab Setup & Safety

Keep the bench consistent and safe before any script touches an instrument:

  • Keep AWG amplitude <= 1 Vpp and offset at 0 V unless a mentor says otherwise.
  • Start with DC coupling on the scope. Enable the 20 MHz bandwidth limit when running noise sweeps.
  • Verify the BNC loopback from AWG CH1 to Scope CH1 before you call read_channels.
  • PSU and DMM stay idle unless you are on Track B3. Use them only for validation and cross-checks.

Track A — Warm-up (Beginner-friendly)

A1 — Hello, Oscilloscope (Sine @ 1 kHz)

Goal: Capture a waveform via Python and verify both frequency and amplitude.

Wiring: AWG CH1 → Scope CH1 (BNC). AWG: 1 kHz sine, 1.0 Vpp, 0 V offset.

Steps
  1. Connect to the scope with PyTestLab (simulation fallback is fine if needed).
  2. Configure CH1 scale/offset, set an edge trigger, and acquire one frame.
  3. Compute frequency and Vpp in Python, then plot the time-domain trace.

Acceptance: |f_meas − 1 kHz| <= 2%; |Vpp_meas − 1.0 V| <= 5%.

Starter snippet
from pytestlab import AutoInstrument
from pytestlab.plotting import PlotSpec
import numpy as np

scope = AutoInstrument.from_config("keysight/DSOX1204G", simulate=False)
scope.connect_backend()
scope.channel(1).setup(scale=0.2, coupling="DC").enable()
scope.trigger.setup_edge(source="CH1", level=0.1)
trace = scope.read_channels(1)                 # MeasurementResult with DataFrame
fig = trace.plot(PlotSpec(title="CH1"))       # save/show as needed
scope.close()

A2 — Duty Cycle Explorer (Square @ 1 kHz)

Goal: Measure duty cycle plus rise and fall times.

Wiring: Same as A1. AWG: 1 kHz square, 1.0 Vpp.

Steps
  1. Capture the waveform using the same PyTestLab flow.
  2. Compute duty cycle (%) and 10–90% rise/fall times.
  3. Record results and keep plots ready for check-in.

Acceptance: Duty within ±2% of the AWG setpoint. Record rise/fall times in your notes.

Track B — Core Measurement Automation (Intermediate)

B1 — Frequency Sweep (Flatness)

Goal: Automate a frequency sweep and measure amplitude versus frequency.

Wiring: AWG → Scope CH1. AWG sine 0.8 Vpp.

Plan
  1. Sweep 100 Hz to 100 kHz (log steps).
  2. For each frequency, acquire the trace and compute Vpp.
  3. Plot |Vpp(f)| and report droop at 100 kHz relative to 1 kHz in dB.
Session skeleton
from pytestlab.measurements import MeasurementSession
import numpy as np

with MeasurementSession("Flatness") as s:
    s.parameter("freq", np.logspace(2, 5, 25), unit="Hz")
    awg  = s.instrument("awg",  "keysight/33500B", simulate=False)
    scop = s.instrument("scope","keysight/DSOX1204G", simulate=False)

    @s.acquire
    def step(freq, awg, scop):
        awg.channel(1).setup_sine(frequency=float(freq), amplitude=0.8)
        scop.trigger.setup_edge(source="CH1", level=0.2)
        tr = scop.read_channels(1)
        return {
            "freq": float(freq),
            "vpp": tr.dataframe()["Voltage (V)"].max()
            - tr.dataframe()["Voltage (V)"].min(),
        }

    exp = s.run()
    # TODO: convert to dB relative to 1 kHz and plot

B2 — Aliasing Demo (Sample Rate & Timebase)

Goal: Show aliasing by pushing the input frequency near or above the timebase Nyquist point.

Steps
  1. Keep the scope timebase fixed.
  2. Increase the AWG frequency until aliasing appears.
  3. Log the true input frequency versus the apparent alias frequency and capture a plot.

Acceptance: One slide or note explaining the aliasing region, plus a plot illustrating the effect.

B3 — PSU + DMM Cross-Check (DC Accuracy)

Goal: Compare PSU setpoint versus measured DMM voltage and log the error.

Wiring: PSU CH1 → DMM (DC volts). Do not connect to the scope for this task.

Steps
  1. Sweep 1.0 V to 5.0 V in 1 V steps.
  2. Hold each point for ~2 s before reading the DMM.
  3. Record setpoint, measured value, and percent error.

Acceptance: Table with setpoint, measured voltage, and error (%).

Track C — Reproducibility & Tooling (Advanced, optional)

C1 — Record & Replay

Goal: Record one complete B1 sweep and replay it later without mismatches.

Steps
  1. Use pytestlab replay record during a full sweep.
  2. Run pytestlab replay run to validate the log.
  3. Attach the replay YAML and confirm zero sequence mismatches.

C2 — Noise & Bandwidth Limit

Goal: Quantify RMS noise with the scope bandwidth limit off versus 20 MHz.

Wiring: AWG idle (0 V). Terminate or short scope CH1 if possible.

Steps
  1. Measure RMS noise with bandwidth limit off.
  2. Enable the 20 MHz limit and repeat.
  3. Report RMS_off versus RMS_20MHz and the percentage reduction.

Logistics & Grouping

  • Pair newer students on Track A → B1 for confidence before tackling advanced work.
  • Experienced attendees choose B1 + C1 or B2 + C2.
  • Total time budget is two hours: A1 (15 min), A2 (15 min), B1 (40 min), B3 (20 min) with 30 min slack.
  • Mentors circulate to approve PSU usage and to sanity check automation scripts.

Bench & Config (template)

Update the model names and addresses to match your bench before connecting:

bench.yaml
bench_name: "Workshop Bench"
simulate: false
instruments:
  scope:
    profile: "keysight/DSOX1204G"   # change to your model
    address: "auto"                  # or VISA/LAN address
  awg:
    profile: "keysight/33500B"
    address: "auto"
  psu:
    profile: "keysight/EDU36311A"
    address: "auto"
  dmm:
    profile: "keysight/34470A"
    address: "auto"

Need discovery? Run pytestlab instruments list from the CLI and paste the addresses into your config.

Submission Checklist

  • One plot from A1 or B1 (PNG or PDF) with labeled axes.
  • One table (CSV) from B3 or B1 with frequency, Vpp, and droop (dB).
  • A short note (<= 150 words): what changed in your code and one thing you learned.