Signal sources and RF
Drivers for frequency synthesizers and RF instruments: Valon 5009, DDS AD9959, Agilent, Rigol.
Overview
Quatm supports a broad range of RF instruments, from general-purpose function generators to vector network analyzers, covering frequency synthesis, arbitrary waveforms and S-parameter measurement.
Valon 5009 dual-channel microwave frequency synthesizer
Overview
The Valon 5009 is a dual-channel frequency synthesizer (23.5 MHz – 6 GHz) controlled over a serial port. Quatm wraps it in valon, which sets the frequency and power of the two outputs independently.
Valon 5009 Dual RF Synthesizer
| Communication | serial (RS232) |
| Frequency range | 23.5 MHz – 6 GHz |
| Channels | 2 |
| Output power | -30 ~ +10 dBm |
| Frequency resolution | 0.1 Hz |
Widely used in ion trap experiments to drive microwave transitions (such as the Ba⁺ 9.9 GHz hyperfine transition) or as an AOM drive source.
Driver module:
valon
Initialization
from quatm.drivers.valon.valon_quatm import valon
# Connect to Valon (default /dev/ttyUSB0)
valon = valon(port="/dev/ttyUSB0")
# Set channel 1 frequency to 500 MHz
valon.set_frequency(freq=500e6, source=1)
# Set channel 2 frequency to 9.925 GHz (external frequency multiplier required)
valon.set_frequency(freq=9.925e9, source=2)
# Send raw command
valon.sendRaw("LOCK 1 ON\r\n")
Key methods
| Method | Description |
|---|
set_frequency(freq, source) | Set the output frequency of channel 1 or 2 (Hz) |
sendCommand(source, command, value) | Send a formatted SCPI command |
sendRaw(cmd) | Send a raw string command |
Serial communication
Underneath, the Valon driver communicates through VSerialPort (a serial.Serial subclass). Typical parameters:
# serial parameters (driver defaults)
port = "/dev/ttyUSB0"
baudrate = 115200
timeout = 0.1
Use the Valon 5009 to drive the 9.925 GHz hyperfine transition and measure Rabi oscillations by scanning the frequency.
Key parameters
| Start frequency | 9.924 GHz |
| Stop frequency | 9.926 GHz |
| Step | 10 kHz |
| Repetitions per point | 100 |
# experiment snippet: frequency scan
import numpy as np
frequencies = np.arange(9.924e9, 9.926e9, 10e3)
for f in frequencies:
valon.set_frequency(freq=f, source=2)
# ... run the probe sequence ...
Reference: See ion trap experiments → quantum state detection
Frequency accuracy
The internal reference stability of the Valon 5009 is limited. For high-precision spectroscopy or quantum control experiments we recommend:
- an external 10 MHz rubidium clock reference
- or real-time monitoring of the output frequency with a HighFinesse wavemeter / spectrum analyzer
class quatm.drivers.valon.valon_prog.Valon_Standalone(name='Valon')
Bases: object
Standalone driver for the Valon frequency generator. Commands can be sent via the Commandhub and are processed in parallel to the experiment, thereby the experiment is not delayed by the Valon.
function quatm.drivers.valon.valon_prog.run()
DDS AD9959 four-channel direct digital synthesis
Overview
The AD9959 driver wraps the AD9959 evaluation board and controls four independent DDS channels over the SPI bus, providing precise frequency, amplitude and phase control.
AD9959 evaluation board 4-channel DDS
| Communication | SPI |
| Channels | 4 |
| Frequency resolution | 32-bit (0.12 Hz @ 500 MHz clock) |
| Phase resolution | 14-bit |
| Amplitude control | 10-bit DAC |
Widely used in cold atom/ion experiments for AOM driving, sideband generation and coherent manipulation.
Driver module:
AD9959
Initialization
from quatm.drivers.dds import AD9959
dds = AD9959()
# Configure channel 0 — cooling-light AOM
dds.set_frequency(0, 80e6) # 80 MHz
dds.set_amplitude(0, 0.5) # 50% amplitude
dds.set_phase(0, 0) # 0° phase
# configure channel 1 — repump AOM (+0.1 MHz offset)
dds.set_frequency(1, 80.1e6)
dds.set_amplitude(1, 0.3)
Key methods
| Method | Description |
|---|
set_frequency(ch, freq_hz) | Set the channel frequency (Hz) |
set_amplitude(ch, amp) | Set the channel amplitude (0–1 fraction) |
set_phase(ch, phase_deg) | Set the channel phase (°) |
update_all() | Update all channels at once |
Synchronized update
The AD9959 supports a synchronized update mode: first call the set_* methods for the four channels individually (buffered), then call update_all() to write everything to the hardware at once. This guarantees phase consistency between channels, which is essential for experiments such as sideband cooling that rely on precise phase relations.Device configuration
"aom_dds": {
"type": "local",
"module": "drivers.DDS",
"class": "AD9959",
}
Typical applications
| Application | Configuration |
|---|
| AOM drive | Single channel, fixed frequency |
| Raman transitions | Two channels, difference-frequency locking |
| Trap drive | Multi-channel phase control |
| Sideband cooling | Frequency modulation |
Alternative driver
An alternative AD9959 board driver with a serial (AT command) interface is also available:
from quatm.drivers.dds.alibaba import AD9959Board
Rigol DG1020Z two-channel function generator
DG1020Z
DG1020Z Rigol function generator
| Communication | VISA (USB/LAN) |
| Channels | 2 |
| Frequency range | 1 µHz – 25 MHz |
| Amplitude | 1 mVpp – 10 Vpp |
| Sampling rate | 200 MSa/s |
Used to generate AOM/EOM drive signals, modulation waveforms and custom arbitrary waveforms.
Driver module:
RigolDG1020Z
from quatm.drivers.AWG.specific import RigolDG1020Z
fg = RigolDG1020Z(addr="USB0::...")
fg.set_frequency(80e6)
fg.set_amplitude(1.0) # 1.0 Vpp
fg.enable_output(channel=1, enable=True)
fg.set_function(channel=1, function="SIN")
Other Rigol devices
DP1116A programmable DC power supply
DP1116A Rigol DC power supply
| Communication | VISA |
| Output | 16V/10A or 32V/5A |
| Channels | 1 |
| Resolution | 1 mV / 1 mA |
Used for coil current control, laser diode driving and circuit board supply.
Driver module:
DP1116A
from quatm.drivers.rigol.power_supply import DP1116A
ps = DP1116A(addr="USB0::0x1AB1::0x0E11::DP1A123456789::INSTR")
ps.set_voltage(12.0) # 12V
dc.set_current(0.5) # 500 mA current limit
ps.enable_output(True)
Oscilloscopes
Rigol DS series oscilloscopes are compatible with the Tektronix SCPI command set and are controlled through the ITektronixScope driver:
from quatm.drivers.tektronix.base import ITektronixScope
scope = ITektronixScope(addr="USB0::0x1AB1::0x04CE::DS123456789::INSTR", nchannels=4)
scope.set_timebase(scale=1e-6) # 1 µs/div
scope.set_vertical(channel=1, scale=0.5) # 0.5 V/div
waveform = scope.acquire(channel=1)
33500B / 33220A / 33250A Agilent/Keysight
| Communication | VISA (USB/LAN/GPIB) |
| Channels | 1–2 |
| Frequency | up to 120 MHz (33500B) |
| Resolution | 14-bit |
| Sampling rate | 250 MSa/s |
| Waveforms | sine/square/ramp/pulse/noise/ARB |
A laboratory standard signal source for AOM driving, modulation signals and reference clock generation.
Driver module:
Agilent33500 / Agilent33220A
from quatm.drivers.awg.specific import Agilent33500
awg = Agilent33500(addr="USB0::0x0957::0x2C07::MY52801234::INSTR")
# Configure an 80 MHz sine wave
awg.set_function(channel=1, function="SIN")
awg.set_frequency(80e6)
awg.set_amplitude(1.0) # 1 Vpp
awg.enable_output(channel=1, enable=True)
# Burst mode — generate N cycles, then stop automatically
awg.enable_burst(channel=1, ncycles=100)
Supported models
| Driver class | Applicable models |
|---|
Agilent33500 | 33500B, 33510B, 33520B, 33522B |
Agilent33220A | 33220A, 33250A |
RigolDG1000 | DG1022, DG1032 |
RigolDG1020Z | DG1022Z, DG1032Z |
Instek AFG2000 / AFG2225 dual channel
AFG-2225 / AFG-2100 Instek
| Communication | VISA |
| Channels | 1 (AFG2000) / 2 (AFG2225) |
| Frequency | up to 25 MHz |
| Sampling rate | 200 MSa/s |
A cost-effective two-channel arbitrary waveform generator.
Driver module:
InstekAFG2225 / InstekAFG2000
from quatm.drivers.awg.specific import InstekAFG2225
awg = InstekAFG2225(addr="USB0::...")
awg.set_frequency(10e6)
awg.set_amplitude(2.0)
awg.enable_output(channel=1, enable=True)
awg.enable_output(channel=2, enable=True)
AFG1022 / AFG1062 Tektronix
| Communication | VISA |
| Channels | 2 |
| Frequency | up to 60 MHz (AFG1062) |
| Sampling rate | 300 MSa/s |
| Arbitrary waveform | 64 MB memory |
A high-performance two-channel AWG with support for large custom waveforms.
Driver module:
TektronixAFG1000
from quatm.drivers.awg.specific import TektronixAFG1000
awg = TektronixAFG1000(addr="USB0::...")
awg.set_function(channel=1, function="ARB")
# Load a custom waveform...
Tektronix DPO/MSO series oscilloscopes
DPO2000 / MSO4000 series Tektronix oscilloscope
| Communication | VISA |
| Bandwidth | 100 MHz – 1 GHz |
| Channels | 2–4 |
| Sampling rate | up to 5 GS/s |
Automates waveform acquisition and parameter measurement over SCPI. Frequently used for experiment debugging and pulse sequence verification.
Driver module:
ITektronixScope
from quatm.drivers.tektronix.base import ITektronixScope
scope = ITektronixScope(
addr="USB0::0x0699::0x0401::C012345::INSTR",
nchannels=4
)
# Configure trigger
scope.set_trigger(source=1, level=0.5, slope="POS")
scope.set_timebase(scale=1e-6) # 1 µs/div
scope.set_vertical(channel=1, scale=0.1) # 0.1 V/div
# Acquire waveform
waveform = scope.acquire(channel=1)
Agilent E5071C vector network analyzer
E5071C Agilent VNA
| Communication | VISA |
| Frequency | 9 kHz – 20 GHz |
| Ports | 2–4 |
| Functions | S-parameters, impedance, Smith chart |
Used for RF component characterization: S-parameter measurement of filters, amplifiers, antennas and transmission lines.
Driver module:
AgilentE5071C
from quatm.drivers.Agilent.vna import AgilentE5071C
vna = AgilentE5071C(addr="TCPIP::192.168.1.100::INSTR")
vna.set_frequency_range(start=1e6, stop=1e9, points=1001)
vna.set_if_bandwidth(100) # 100 Hz IFBW
vna.set_averaging(count=10)
# Read S21 parameters
freq, s21 = vna.read_S_parameters(parameter="S21")
PicoVNA portable vector network analyzer
PicoVNA Pico Technology
| Communication | TCP/SCPI (port 5025) |
| Frequency | 300 kHz – 8.5 GHz |
| Ports | 2 |
| Dynamic range | 100 dB
|
A compact USB-controlled VNA, well suited to desktop RF debugging in the laboratory.
Driver module:
PicoVNA
from quatm.drivers.PicoTech.vna_scpi import PicoVNA
vna = PicoVNA(addr="localhost") # or IP address
vna.set_frequency_range(start=10e6, stop=500e6)
s_params = vna.read_S_parameters(parameter="S21")
Generic SCPI device configuration
"function_gen": {
"type": "local",
"module": "drivers.awg.specific",
"class": "Agilent33500",
"arguments": {"addr": "USB0::..."},
}