-
Notifications
You must be signed in to change notification settings - Fork 4
Getting Started
Pulsecontrol is a script bundle with the aim to standardise the operation of Arbitrary Waveform Generators (AWGs) in a MATLAB® context. Pulses for AWGs can be created using a flexible syntax. They are stored in a global database (plsdata). Groups of pulses from plsdata can be transfered to an AWG for execution in sequence.
An AWG is represented in the data structure awgdata. Changes to pulses loaded to an AWG are documented, by autosaving the current AWG state.
An AWG runs so called waveforms. Waveforms consist of a number of values stepped through with a certain clock rate.
The values can range from -1 to 1 and are mapped according to the maximum peak-to-peak amplitude on the device to a voltage:
voltage | normalized value
--------------------------------------------
offset - amplitude(p-p)/2 | -1
offset + amplitude(p-p)/2 | +1
Exceding values are clipped.
Besides the analog part of the data, a waveform inclueds two digital marker parts, which can be set for every clock individually to 'on' or 'off' on additional output channels. This is useful for triggering other instruments based on the index position within the waveform. More Information on the 14-bit integer encoding used for transmission and storage of pulses on the AWG can be found in awgload.
Waveforms are produced by a more general data type in Pulsecontrol called a pulse.
In Pulsecontrol a pulse can be created in several ways defined by the following formats:
- 'wf' is the most basic format. The pulse is described via data values for every clock of the AWG. This is the format transmitted to the instrument and corresponds to a waveform.
- 'tab' defines pulses in a tabular manner. Data values are defined at distinct times of the pulse. The intermediate values are ramped.
- 'elem' defines pulses out of several pulse elements. A pulse element describes distinct shapes controlled by parameters, e.g. 'wait' will stay at at a specific voltage for a given time. The format of a pulse is determinded by the string pinf.format where pinf is a data structure defining the pulse.
Pulses of the format 'elem' and 'tab' are converted into 'wf' when transmitted to the AWG.
To use Pulsecontrol the AWG must be connected and opened for communication via the Instrument Control Toolbox™. Two global data structures plsdata and awgdata must be present in the MATLAB® workspace. awgdata contains the instrument object, a representation of uploaded pulses and other important poroperties. plsdata contains pulsedefenitions and defines paths where to store groups of pulses, and backup awgdata. The next section describes the creation and upload of a pulse plus the necessery setup.
The example data structures plsdata and awgdata can be created by executing the scripts awgsetup.m
%% create awg structure from scratch
clear global awgdata;
global awgdata;
% number of instrument channels
nChan = 4;
awgdata.chans = 1:nChan; % determines order of channels, not used
awgdata.scale = ones(1,nChan); % pre-scale waveform valus before upload.
% Used with offset to relate arbitrary
% pulse scale to, e.g. mV
awgdata.pulsegroups = []; % pulsegroups synchroniced with the AWG
awgdata.zeropls = []; % available placeholder zero-pulse lengths
awgdata.triglen = 1200; % length of optional trigger pulse preceding a group
awgdata.clk = 1.2e9; % number of samples per second of instrument
awgdata.seqpulses = []; % !!! functinoality not clear
awgdata.waveforms = {''}; % waveforms present on instrument
awgdata.offset = zeros(1,nChan); % pre-offset waveform valus before upload
awgdata.zerochan = ones(1,nChan); % !!! functinoality not clear
awgdata.bits = 14; % bit-resolution of instrument.
% in case of AWG7000 12bit may be useable, check
awgdata.slave = []; % !!! elaborate
awgdata.current = 'awg5k'; % name of the current instrument
awgdata.awg=[]; % handle to the openend instrument object
awgdata.alternates = awgdata; % alternative configurations of awgdata
% save current awg
awgsavedata;
% clean up
clear nChan;
and plssetup.m Copy them to your own location, for modification purposes.
%% create pulse database from scratch for iq mixer calibration
clear global plsdata;
global plsdata;
% name of database
dbName = 'iqmx';
% get the path to this script
[scriptPath, ~, ~] = fileparts(mfilename('fullpath'));
% save pathes in database
plsdata.datafile = [scriptPath '/awg_pulses/plsdata_' dbName '.mat'];
plsdata.grpdir = [scriptPath '/awg_pulses/pulsegroups_' dbName '/'];
% create pulse structure
% plsdata.pulses = struct('data', {}, 'format', {}, ...
% 'xval',{}, 'taurc',{}, 'name',{},'trafofn',{},'pardef',{});
plsdata.pulses = struct('name', {}, 'data', {}, ...
'xval',{}, 'taurc',{}, 'pardef',{},'trafofn',{},'format',{});
% set timebase to microseconds
plsdata.tbase = 1000;
% create folders
mkdir 'awg_pulses';
mkdir(plsdata.grpdir);
% save database
plssync('save');
% clean up
clear dbName scriptPath;
They define necessary properties in the structures and create a folder structure to store pulses and AWG states for Pulsecontrol. Now a pulse can be defined.
clear pinf;
pinf.name = 'pulse1';
pinf.data.pulsetab = [0 1; 0.1 0.3; 0.2 0.4];
The above code creates a pulse of the format 'tab' with the name 'pulse1'. The format is specified automatically depending on the content of pinf.data. In this case a pulsetab array creates a 'tab' pulse. The first row in the array defines the time. While the subsequent two rows define values at this times. Since start and end value are not equal, the intermediate values are linear interpolated. The length of the rows is arbitrary.
The atomar unit of time is 1ns. A scaling factor plsdata.tbase is used when evaluating time in Pulsecontrol. The default value is 1000. Thus pinf is a pulse of 1ns* plsdata.tbase *1 = 1us, which reaches 1 starting from 0 in 1200 steps for a clock speed of 1.2GHz of the connected AWG. The used speed can be found in awgdata.clk.
time | first chan. | second chan.
---------------------------------
0 | 0.1 | 0.3
1 | 0.2 | 0.4
Since the values have an arbitrary unit and the resulting voltage is dependent on the actual settings of the AWG peak-to-peak voltage, it is commune to normalize the values to the unit 'mV' using awgdata.scale and when requiered awgdata.offset.
The created pulse can be plotted using the function plsplot().
plsplot(pinf);
pinf is then added into the plsdata.pulses database at the index plsnum.
plsnum = 1;
plsreg(pinf, plsnum);
Next a pulse group needs to be defined. Only groups can be uploaded to the AWG. In this case the group consist of only one pulse.
clear pg;
pg.name='pulse1_loop';
pg.ctrl = 'notrig'; % no trigger signal
pg.pulses = plsnum; % index of pulse1
pg.nrep = Inf;
pg.chan = [1 2];
Pulse 'pulse1' is selected by the index plsnum of the database. For several pulses an 1xm index array can be specified in pg.pulses, then the pulses are concatenated together.
pg.nrep can be used to specify the number of repetitions of the group. pg.chan defines which physical channels are used to output the pulse. More advanced options are possible. Further information can be found in the User Guide.
The function plsdefgrp() is used to save the group as a mat-file to disk inside plsdata.grpdir with the name 'gr_pulse1_loop'.
plsdefgrp(pg);
All supported features of a group can be found in the comment of plsdefgrp.
Finally the group is added to end of the sequence of the connected AWG with:
awgadd('pulse1_loop')