vDAQ® API

Tasks

Like ScanImage, the vDAQ can be scripted to output digital or analog buffers. ScanImage’s waveform generator is sufficient for most use cases. However, one may write their own task using a user function or script for custom purposes.

Preliminary vDAQ Notes

DAQ tasks supported with task MATLAB API:

  • Analog Output tasks (2MHz max sample rate)

  • Analog Input tasks (1MHz max sample rate, on the analog inputs on the breakout, not the high speed inputs on the vDAQ)

  • Digital Output tasks (20MHz max sample rate)

DAQ tasks not supported with task MATLAB API:

  • Digital Input tasks

  • High Speed Analog Input tasks (using the high speed channels on the vDAQ card)

Get the vDAQ resource to create tasks

To get a handle for the vDAQ, use the Resource Store and filter by vDAQ:

1 resourceStore = dabs.resources.ResourceStore(); % object that holds all system resources
2 vDAQ = resourceStore.filterByName('vDAQ0');     % filter just the vDAQ for the tasks

Create Analog Output Waveforms for a vDAQ Task

The vDAQ supports analog output (AO), digital output (DO), and analog input (AI) tasks. In this example, an AO task outputs a 10Vpp 1kHz sine & cosine wave.

 1 amplitude_V = 5;    % 10/2 Vpp = 5V
 2 frequency_Hz = 1e3; % 1 kHz sine/cosine frequency
 3
 4 taskSampleRate_Hz = 1e6;                   % 1 MHz sample rate
 5 taskSamplePeriod_s = 1/taskSampleRate_Hz;  % 1 us sample period
 6 taskDuration_s = 5 ./ frequency_Hz;        % 5 periods (5 ms)
 7
 8 time_s = (0:taskSamplePeriod_s:taskDuration_s);       % time vector
 9 sin_V = amplitude_V * sin(2*pi*frequency_Hz*time_s);  % voltage sine waveform
10 cos_V = amplitude_V * cos(2*pi*frequency_Hz*time_s);  % voltage cosine waveform
11
12 % create the analog output task
13 ao_task = dabs.vidrio.ddi.AoTask(vDAQ.hDevice,'Sinusoids');
14 ao_task.addChannel(0, 'Sine Wave');       % Add AO0 as Sine Wave output
15 ao_task.addChannel(1, 'Cosine Wave');     % Add AO1 as Cosine Wave output
16 ao_task.writeOutputBuffer([sin_V(:) cos_V(:)]);
17 ao_task.sampleRate = taskSampleRate_Hz;
18 ao_task.sampleMode = 'finite';
19 ao_task.samplesPerTrigger = numel(time_s);
20 ao_task.allowRetrigger = true;
21 ao_task.startTrigger = 'D0.0';            % trigger on rising edge of digital port D0.0 (controlled by a task below)
22 % ao_task.startTrigger = 'si0_sliceClk';  % (another example) trigger on rising edge of ScanImage's frame clock

Create an Analog Input Task

AI tasks may be used to monitor feedback, acquire data, etc.

 1 % (for testing, loop back AO0 to AI0 and AO1 to AI1 with BNC cables)
 2 ai_task = dabs.vidrio.ddi.AiTask(vDAQ.hDevice,'Example Acquire Data');
 3 ai_task.addChannel(0, 'AI0 input data');
 4 ai_task.addChannel(1, 'AI1 input data');
 5
 6 % sync ai_task with ao_task so they will start simultaneously and sample at the same rate
 7 ai_task.syncTo(ao_task);
 8
 9 % set the callback function to be called every time a number of samples are acquired
10 % (see exampleAICallbackFunction.m, which just plots the data received)
11 ai_task.sampleCallback = @(varargin)exampleAICallbackFunction(ai_task,varargin{:});
12 ai_task.sampleCallbackN = ai_task.samplesPerTrigger;  % callback every time a full trigger is recorded

Create a Digital Output Task

A DO task may be useful for things like triggering another task. Here is an example of a signal delaying ScanImage’s frame clock by 5 ms with a 1 ms pulse width.

 1delayTime_s = 5e-3;  % 5ms
 2pulseWidth_s = 1e-3; % 1ms
 3
 4% calculate time length in terms of samples (round to nearest sample)
 5delayTime_samples  = round(delayTime_s * taskSampleRate_Hz);
 6pulseWidth_samples = round(pulseWidth_s * taskSampleRate_Hz);
 7
 8% create the delayed frame-clock waveform
 9delayedFrameClockWaveform = [...
10   zeros(delayTime_samples,1); ...  % remain off for the delay time
11   ones(pulseWidth_samples,1); ...  % remain on for the pulse width
12   0; ...                           % turn back off after the pulse width elapses
13];
14
15% create the digital output task and write the delayed waveform to it
16do_task = dabs.vidrio.ddi.DoTask(vDAQ.hDevice,'Digital Sync');
17do_task.addChannel('D0.0', 'Delayed Frame Clock');
18do_task.writeOutputBuffer(delayedFrameClockWaveform);
19do_task.sampleRate = taskSampleRate_Hz;
20do_task.sampleMode = 'finite';
21do_task.samplesPerTrigger = numel(delayedFrameClockWaveform);
22do_task.allowRetrigger = true;
23do_task.startTrigger = 'si0_sliceClk';  % trigger on rising edge of ScanImage's frame clock

Task Management

Starting Tasks

1% start ao_task first. it will wait for the trigger on D0.0
2ao_task.start();  % automatically starts ai_task since it is synchronized
3
4% then start the do_task which will wait for the frame clock trigger
5do_task.start();
6
7% after ScanImage starts scanning, the frame clock will trigger the do_task,
8% which will then trigger the ao_task and ai_task

Abort and Clean Up Tasks

1ao_task.abort();
2do_task.abort();
3delete(ao_task);
4delete(ai_task);
5delete(do_task);