Experiment control and others
Overview
FPGA controllers and auxiliary devices are an essential part of experiment automation: from nanosecond real-time timing to relay switching, Quatm provides a unified control interface. ADwin, NI-FPGA, Red Pitaya and several other brands are currently supported.
ADwin
Overview
ADwin is a family of real-time controllers from Jaeger Computergesteuerte Messtechnik, based on an FPGA/DSP architecture, that executes real-time tasks independently of the PC operating system.
ADwin Gold II / Pro II
| Communication | PCI / USB |
| Processor | DSP + FPGA |
| Timing precision | nanosecond level |
| Analog input | 16-bit |
| Digital I/O | TTL (5V) |
| Memory | 32 MB DRAM |
ADwinHow it works
PC (Quatm) ADwin (real-time)
┌──────────┐ PCI/USB ┌──────────────┐
│ experiment│ ←──────────→ │ ADbasic proc │
│ .py │ Par/Data │ ns timing+acq│
└──────────┘ └──────────────┘
Quatm experiment scripts read and write parameters and data arrays through the ADwin driver, interacting with the ADbasic process running on the ADwin. The timing-critical parts execute on the ADwin hardware, while the Python side handles parameter setting and result readout.
Initialization
from quatm.drivers.fpga import ADwin
# Connect to ADwin (PCI bus)
adw = ADwin(device_number=1)
# Load and start the ADbasic process
adw.load_process("experiment_sequence.TB1")
adw.start_process()
# Set experiment parameters
adw.set_par(1, 100_000) # Par_1 = 100 µs cooling time
adw.set_par(2, 50) # Par_2 = 50 cycles
adw.set_par(3, 10_000) # Par_3 = 10 ms detection time
# Start one experiment sequence (triggered by an event in ADbasic)
adw.trigger()
# Read acquired data
photons = adw.get_data(1, data_length=1000) # Read photon counts from Data_1
Key methods
| Method | Description |
|---|---|
load_process(binary_path) | Load an ADbasic-compiled binary process |
start_process() | Start the loaded process |
stop_process() | Stop the running process |
set_par(index, value) | Write an integer parameter (1–80) |
set_fpar(index, value) | Write a floating-point parameter (1–80) |
get_par(index) | Read an integer parameter |
get_data(index, data_length) | Read a data array (1–200) |
set_data(index, values) | Write a data array |
trigger() | Send a software trigger event |
Typical ADbasic process structure
' ADbasic code snippet — experiment timing
Init:
Par_1 = 100000 ' Cooling time (µs)
Par_2 = 50 ' Number of cycles
Event:
For i = 1 To Par_2
P2_DAC(1, 5000) ' Set AOM power
P2_DAC(2, 800) ' Set magnetic field
' ... wait, acquire, switch ...
Next i
Device configuration
"fpga": {
"type": "local",
"module": "quatm.drivers.fpga",
"class": "ADwin",
"arguments": {"device_number": 1},
}
Development and debugging
During development, experiment logic can be tested with theFPGADummy simulator (no hardware required). The simulator exposes the same API but performs no actual hardware operations, which makes it suitable for developing and validating experiment scripts on an office computer.Exception:
quatm.drivers.fpga.adwin.AdWinDriverError(message)class quatm.drivers.fpga.adwin.AdWinDriverError(Exception): pass
quatm.drivers.fpga.client module
Class:
quatm.drivers.fpga.client.AdWinClient(experiment, simulating=None)class quatm.drivers.fpga.client.AdWinClient(object): def filter_cmdlist(self, combinetime=1e-08): pass def push(self, time, command, value, combinetime=1e-09): pass def start_realtime(self, processortime=0, repetitions=1): pass def stop(self): pass
quatm.drivers.fpga.units module
NI-FPGA LabVIEW FPGA modular instruments
PXIe-78xxR / PCIe-78xxR series NI-FPGA
| Communication | NI-FPGA Interface Python API |
| FPGA | Xilinx Kintex/Virtex |
| Digital I/O | up to 1 Gb/s |
| Analog I/O | up to 3.2 GS/s |
| Programming | LabVIEW FPGA + Python runtime control |
nifpga Python API. Suited to custom digital signal processing requiring very high throughput and deterministic timing.ni_fpgafrom quatm.drivers.NI.ni_fpga import NIFPGA
fpga = NIFPGA(resource_name="RIO0", bitfile="custom_logic.lvbitx")
fpga.run()
fpga.write_control("pulse_width", 100) # ns
fpga.write_control("trigger_delay", 50)
fpga.read_indicator("photon_count")
Comparison with ADwin
| Feature | ADwin | NI-FPGA |
|---|---|---|
| Programming language | ADbasic (BASIC-like) | LabVIEW FPGA (graphical) |
| Python control | Parameter/data array read-write | Control/indicator read-write |
| Suitable for | Nanosecond timing, photon counting | High-speed DSP, custom protocols |
| Hardware ecosystem | Standalone controller | Integrated in the NI PXI platform |
Conrad relay board
Relay Board Conrad
| Communication | serial (19200 baud) |
| Channels | 8 relays per board |
| Support | daisy-chain expansion |
RelayBoardfrom quatm.drivers.Conrad.base import RelayBoard
rb = RelayBoard(conn="/dev/ttyUSB0", start_addr=0)
rb.set_relay(relay=0, state=True)
rb.set_relay(relay=3, state=False)
rb.write_byte(0b10101010)
Development and debugging
During development, experiment logic can be tested with theFPGADummy simulator, without connecting real hardware.