1. Safety first
- Account for waveform peak voltage plus DC offset. A 2 Vpp waveform is ±1 V around its offset.
- Confirm whether the load is 50 Ω or high impedance. A mismatched load can produce an unexpected terminal voltage.
- Never rely on this application as a safety-rated interlock. Use independent isolation, current limiting, attenuation, and emergency shutdown where required.
- Configure with outputs off. Enable only the channel you intend to energize.
2. GUI orientation
| Area | Purpose |
|---|---|
| File → Add unit | Creates an independent instrument session tab. |
| File → Show Log | Shows the live, device-specific log for the selected top-level tab. |
| File → Documentation | Displays this exact HTML documentation inside the application. |
| + Add unit | Shortcut for creating another instrument tab. |
| CH1 / CH2 | Basic waveform, level, phase, load, and output controls. |
| Modulation | AM, FM, and PM configuration. |
| Sweep / Burst | Frequency sweep and N-cycle burst controls. |
| Arbitrary | Editable samples, CSV import, and volatile-memory upload. |
| Saved States | Lists and recalls .RSF configurations from the generator's ten internal USER slots. |
| Counter | Counter enable, measurements, and shutdown. |
| System / SCPI | Reset, status, synchronization, safe output-off, and unrestricted SCPI. |
Red controls disconnect, disable, reset, or stop active behavior. Gray controls are locked in the current state. Connection selectors remain gray while connected so an active endpoint cannot be changed accidentally.
3. Install and launch
Install the complete package from PyPI
py -m pip install cds_rigol_dg1022z
cds_rigol_dg1022z_gui
The standard package installs the Python driver, desktop GUI, Ethernet transport, direct USB-TMC support, PyVISA support, HTML documentation, and bundled Rigol manuals. No separate GUI or documentation package is required.
Minimal Python import
from cds_rigol_dg1022z import DG1022Z, discover_usb_connections
Command-line entry points
# Desktop application
cds_rigol_dg1022z_gui
# Command-line instrument utility
cds_rigol_dg1022z --discover-usb
cds_rigol_dg1022z --discover-ethernet
Development installation
git clone https://gitlab.com/test_equipments/rigol_dg1022z.git
cd rigol_dg1022z
py -m pip install -e ".[test,build]"
pytest -q
All numeric Python values use base units: hertz, volts, seconds, degrees, and ohms. The GUI’s kHz, MHz, mV, µs, and ms selectors are conveniences that convert to base units before sending SCPI.
3A. Package updates
Version indicator and checks
The GUI checks PyPI in the background at startup. The top indicator displays Version X · Latest only after PyPI confirms the installed release is current. Select File → Check for updates to repeat the check. If PyPI is unreachable or the computer is offline, the automatic check is silently skipped and instrument operation continues normally.
Install an available update
- Select Update now in the top banner.
- Confirm that the application may close.
- A separate updater waits for the GUI process to exit so Windows releases the launcher and package files.
- The updater runs pip in the same Python environment.
- After installation, the GUI reopens automatically and checks the installed version again.
python -m pip install --upgrade cds_rigol_dg1022z
Nothing is installed without explicit confirmation. Closing before installation prevents the Windows error OSError: The process cannot access the file because it is being used by another process.
Failure and manual recovery
If pip fails, the updater reopens the application and displays the error. Full updater output is saved at %TEMP%\cds_rigol_dg1022z-update.log. Close every running copy of the GUI before running the manual command above. Frozen standalone executables skip pip-package updates.
4. Connect instruments
Ethernet
GUI
- On the generator, open Utility → I/O Config → LAN.
- Select Scan network. The application scans the local and entered-IP /24 networks on SCPI port 5555.
- Select the identified model/serial/IP, or enter an address manually.
- Select Connect.
- Confirm model and serial appear. Endpoint controls become gray.
Python
from cds_rigol_dg1022z import DG1022Z
dg = DG1022Z.ethernet(
"192.168.1.100",
port=5555,
timeout=5.0,
)
dg.open()
print(dg.identify())
# ... operate ...
dg.close()Python Ethernet discovery
from cds_rigol_dg1022z import discover_ethernet
for device in discover_ethernet():
print(device.host, device.model, device.serial_number)
devices = discover_ethernet(hints=["192.168.1.100"])
Discovery makes short concurrent TCP connections and sends *IDN?. Only compatible Rigol DG identities are listed. Host firewalls, routed/VLAN networks, and networks larger than /24 may require entering the IP manually.
USB discovery and connection
from cds_rigol_dg1022z import DG1022Z, discover_usb_connections
devices = discover_usb_connections()
for item in devices:
print(item.backend, item.serial_number, item.resource_name)
selected = devices[0]
if selected.backend == "visa":
dg = DG1022Z.visa(selected.resource_name, timeout=5.0)
else:
dg = DG1022Z.usb(selected.serial_number, timeout=5.0)
with dg:
print(dg.identify())
Connection lock and disconnect
After a successful GUI connection, transport, address/device, and refresh controls lock. Select the red Disconnect button to close only that tab’s transport and unlock its selectors. In Python, call dg.close() or use a with block.
5. Multiple devices
GUI
Create one top-level tab per generator. Each tab owns its transport, state, USB reservation, and log. The same USB serial cannot be selected twice.
Python
from contextlib import ExitStack
from cds_rigol_dg1022z import DG1022Z
with ExitStack() as stack:
left = stack.enter_context(
DG1022Z.ethernet("192.168.1.101")
)
right = stack.enter_context(
DG1022Z.ethernet("192.168.1.102")
)
print(left.identify())
print(right.identify())
left.channel(1).frequency = 1_000
right.channel(1).frequency = 2_000VISA transports share a reference-counted process manager, while each device keeps its own resource handle. Closing one instrument does not deliberately invalidate another.
6. Channels, waveforms, and outputs
Apply a waveform
ch1 = dg.channel(1)
ch1.configure_sine(
frequency=1_000,
amplitude=2.0,
offset=0.25,
phase=90,
)
# Generic form supports SIN, SQU, RAMP, PULS, NOIS, or ARB.
ch2 = dg.channel(2)
ch2.configure("SQU", 10_000, 1.0, 0.0, 0.0)
GUI equivalent: select CH1 or CH2, choose Shape, enter Frequency, Amplitude, Offset, Phase, and Load, then select Apply waveform.
Noise
# Noise accepts amplitude and offset only.
ch1.configure_noise(amplitude=1.0, offset=0.0)
Noise has a model-defined bandwidth rather than a programmable waveform frequency, and phase does not apply. The GUI therefore disables Frequency and Phase for NOIS. The driver sends the Rigol form :SOUR1:APPL:NOIS 1,0.
Individual settings and queries
ch1.frequency = 2_500
ch1.amplitude = 1.5
ch1.offset = -0.1
ch1.set_phase(45)
ch1.set_load(50) # or "INF"
ch1.set_polarity(False)
print(ch1.frequency)
print(ch1.amplitude)
print(ch1.offset)
print(ch1.output_enabled)
Output control
# Verify all limits and wiring first.
ch1.output_enabled = True
# Turn it off explicitly when finished.
ch1.output_enabled = False
# Emergency convenience operation for both channels:
dg.outputs_off()
dg.outputs_off(), then confirm the front panel.7. AM, FM, and PM modulation
GUI: choose channel, modulation type, internal shape, modulation frequency, and depth/deviation; select Enable modulation. Use the red Disable modulation before switching modes.
ch = dg.channel(1)
# AM: depth percent, internal rate, shape
ch.configure_am(80, 1_000, "SIN")
# FM: frequency deviation in Hz, internal rate, shape
ch.configure_fm(5_000, 200, "SQU")
# PM: phase deviation in degrees, internal rate, shape
ch.configure_pm(90, 100, "TRI")
# Turns off AM, FM, PM, ASK, FSK, PSK, and PWM states.
ch.disable_modulation()
Advanced ASK/FSK/PSK/PWM settings remain available through dg.write(...) and the bundled programming guide.
8. Frequency sweep and burst
Sweep
ch = dg.channel(1)
ch.configure_sine(1_000, 1.0)
ch.configure_sweep(
start=100,
stop=100_000,
seconds=2.0,
spacing="LOG", # LIN, LOG, or STEP
direction="UP",
)
# Python exposes explicit sweep shutdown:
ch.disable_sweep()
N-cycle burst
ch.configure_burst(
cycles=10,
period=1.0,
trigger_source="INT",
)
ch.trigger_burst()
ch.disable_burst()
GUI: configure the base waveform first, then use Sweep / Burst. Trigger now issues the channel burst trigger. Raw SCPI is available for external trigger, gated burst, polarity, and model-specific advanced options.
9. Arbitrary waveforms
GUI workflow
- Select Load Example or Load CSV.
- Edit the one-value-per-line samples. Normalized values should be between −1 and +1.
- Select channel and repetition frequency.
- Select Upload to volatile memory.
- Configure level and output deliberately.
Python: generate and upload a sine cycle
import math
points = [
math.sin(2 * math.pi * index / 128)
for index in range(128)
]
dg.channel(1).upload_arbitrary(
points,
frequency=1_000,
)
Python: load CSV values
import csv
points = []
with open("waveform.csv", newline="") as stream:
for row in csv.reader(stream):
points.extend(float(value) for value in row)
if not points:
raise ValueError("Waveform is empty")
if any(not -1.0 <= value <= 1.0 for value in points):
raise ValueError("Samples must be normalized")
dg.channel(2).upload_arbitrary(points, 500)
Uploads use volatile channel memory and can be lost on reset or power cycle. Large sample sets generate large SCPI log entries.
9A. Internal RSF saved states
GUI workflow
- Connect the generator and open Saved States.
- Select Refresh internal files. The GUI queries all ten internal USER slots and lists populated `.RSF` files.
- Select the required `USERn - filename.RSF` entry.
- Select Recall selected settings, review the warning, and explicitly confirm.
- Verify both channel outputs and all relevant settings on the physical front panel.
This feature accesses the generator's internal non-volatile state storage. It does not upload an RSF from the PC and does not browse an external USB drive. A recalled state can include channel waveforms, frequencies, amplitudes, offsets, phases, modulation, sweep, burst, counter, utility, and system settings. The front panel is authoritative because the GUI does not represent every possible recalled parameter.
Python workflow
from cds_rigol_dg1022z import DG1022Z
with DG1022Z.ethernet("192.168.1.100") as dg:
states = dg.internal_state_files()
for state in states:
print(f"USER{state.slot}: {state.filename}")
selected = next(s for s in states if s.filename == "Setup.RSF")
dg.recall_internal_state(selected.slot)
internal_state_files() sends :MEMory:STATe:CATalog? and omits empty slots. recall_internal_state(slot) validates slots 1 through 10 and sends *RCL USERn.
10. Frequency counter
GUI: connect only to the rated counter input, select Measure / Turn On, read the five measurements, then select the red Turn Counter Off.
dg.counter_enabled(True)
try:
readings = dg.counter_measurements()
print("Frequency:", readings["frequency"], "Hz")
print("Period:", readings["period"], "s")
print("Positive width:", readings["positive_width"], "s")
print("Negative width:", readings["negative_width"], "s")
print("Duty cycle:", readings["duty_cycle"], "%")
finally:
dg.counter_enabled(False)
11. System operations
| GUI | Python | Effect |
|---|---|---|
| Reset | dg.reset() | Sends *RST; settings and outputs may change. |
| Clear status | dg.clear_status() | Sends *CLS. |
| Sync phases | dg.synchronize_phases() | Synchronizes channel phases. |
| All outputs off | dg.outputs_off() | Explicitly disables CH1 and CH2. |
SCPI *TRG | dg.trigger() | Issues a bus trigger. |
SCPI *WAI | dg.wait() | Waits for pending operations. |
12. Raw SCPI console
The GUI drop-down contains common commands and remains editable. Queries end in ?. The console prints the command and any returned response.
# Query
identity = dg.query("*IDN?")
frequency = float(dg.query(":SOUR1:FREQ?"))
# Write
dg.write(":OUTP1 OFF")
# Inspect one error or drain the queue
print(dg.error())
for item in dg.errors(limit=32):
print(item)
Command-line interface
cds_rigol_dg1022z --ethernet 192.168.1.100 --command "*IDN?"
cds_rigol_dg1022z --discover-usb
cds_rigol_dg1022z --discover-ethernet
cds_rigol_dg1022z --usb DG1ZA123 --command ":SYST:ERR?"
13. Device-specific session logs
Logs are stored under %USERPROFILE%\PB_LAB\DG1022Z_Control\logs. Every GUI unit tab has an isolated session log containing its discovery action, connection, SCPI writes, queries, responses, failures, and cleanup. A separate application log records startup and general GUI lifecycle.
- Select the desired unit tab.
- Choose File → Show Log.
- Leave the viewer open to follow new records. Switching unit tabs switches the viewer to that tab’s file.
Logs may contain IP addresses, serial numbers, output parameters, and waveform samples. Redact sensitive data before sharing.
14. Errors, recovery, and shutdown
Recovery checklist
- Do not assume outputs are off.
- Inspect the physical generator and load.
- Use All outputs off if communication still works.
- Open the selected session log.
- Disconnect only the affected tab.
- Verify cable, driver, IP, and device reservation.
- Reconnect, query
*IDN?, then drain:SYST:ERR?.
Defensive Python pattern
from cds_rigol_dg1022z import DG1022Z, RigolError
dg = DG1022Z.ethernet("192.168.1.100")
try:
dg.open()
print(dg.identify())
# Perform work.
except RigolError as exc:
print(f"Instrument operation failed: {exc}")
finally:
try:
dg.outputs_off()
except Exception:
# Inspect the physical outputs if communication is lost.
pass
dg.close()
15. Complete automation recipes
Two-channel setup with guaranteed cleanup
from cds_rigol_dg1022z import DG1022Z
with DG1022Z.ethernet("192.168.1.100") as dg:
print(dg.identify())
try:
ch1 = dg.channel(1)
ch2 = dg.channel(2)
ch1.configure_sine(1_000, 2.0, 0.0, 0.0)
ch1.set_load(50)
ch2.configure_square(10_000, 1.0, 0.0, 90)
ch2.set_load("INF")
ch1.output_enabled = True
ch2.output_enabled = True
input("Press Enter to stop outputs...")
finally:
dg.outputs_off()
Characterize a sweep, then restore a steady waveform
with DG1022Z.usb("DG1ZA123") as dg:
ch = dg.channel(1)
try:
ch.configure_sine(1_000, 0.5)
ch.configure_sweep(100, 1_000_000, 5, "LOG")
ch.output_enabled = True
input("Press Enter after capture...")
finally:
ch.output_enabled = False
ch.disable_sweep()
ch.configure_sine(1_000, 0.5)
16. Python API quick reference
| Object | Available operations |
|---|---|
DG1022Z | ethernet, usb, visa, open, close, identify, channel, write, query, reset, clear_status, wait, trigger, error, errors, synchronize_phases, counter_enabled, counter_measurements, internal_state_files, recall_internal_state, outputs_off |
Channel | configure, configure_sine, configure_square, configure_ramp, configure_pulse, configure_noise, set_phase, set_load, set_polarity, configure_am, configure_fm, configure_pm, disable_modulation, configure_sweep, disable_sweep, configure_burst, trigger_burst, disable_burst, upload_arbitrary, plus frequency, amplitude, offset, and output_enabled properties. |
| Discovery | discover_ethernet() probes local SCPI networks. discover_usb_connections() combines VISA and direct USB entries; discover_visa_usb() and discover_usb() expose backend-specific discovery. |
17. Bundled official references
- Rigol DG1000Z User Guide — operation, ratings, and remote setup.
- Rigol DG1000Z Programming Guide — complete SCPI authority.
- Rigol DG1000Z Data Sheet — specifications and ordering information.
- PB LAB text operator guide — compact offline reference.