Code covered by the BSD License  

Highlights from
Pre-trigger Data Capture and Custom Triggering

image thumbnail

Pre-trigger Data Capture and Custom Triggering

by

 

12 Jul 2013 (Updated )

An example of pre-trigger data capture and custom triggering using the session-based interface.

sw_pretrigger_session
function s = sw_pretrigger_session
%SW_PRETRIGGER_SESSION software trigger and pre-trigger capture
% This file demonstrates how to configure a software trigger (rising edge).
% It is editable for other trigger conditions. In addition, this file also
% demonstrates how to capture pre-trigger data.
%
% Written by Isaac Noh
% Copyright 2013 The MathWorks, Inc.


%% EDIT CONFIGURATION FOR YOUR HW==========================================
% Setup the hardware channels
s = daq.createSession('ni');
s.addAnalogInputChannel('cDAQ1Mod2','ai6','Voltage'); 
s.addDigitalChannel('cDAQ1Mod4','port0/line0','InputOnly'); 
%==========================================================================

%% EDIT THESE PARAMETERS FOR YOUR CUSTOM ACQUISITION========================
% Setup the acquisition parameters 
mySampleRate = 2000;
captureLength = 1; % capture example for 1 seconds after trigger, must be multiple of myBufferRefillPeriod
myBufferRefillPeriod = 0.1; % in seconds
myNumPretriggerBuffers = 2; % this code assumes at least 2 buffers
myNumChannels = 2;
%==========================================================================

%% DO NOT EDIT ============================================================
% Apply the settings to the hardware
s.Rate = mySampleRate;
s.IsContinuous = 1;

% The samples are stored in a circular buffer, which is a
% computationally efficient way of storing the samples
myBufferSize = ceil(myBufferRefillPeriod * mySampleRate);
myNumBuffers = myNumPretriggerBuffers + (captureLength/myBufferRefillPeriod) + 1; % plus 1 to account for mid refill trigger
myCurrentBuffer = 1;

% The set of buffers
myCircularBuffers = zeros(myBufferSize, myNumChannels, myNumBuffers);
myCircularTimeBuffer = zeros(myBufferSize, 1, myNumBuffers);

% Set the NotifyWhenDataAvailableExceeds property to set the frequency for
% refilling the buffer.
s.NotifyWhenDataAvailableExceeds = myBufferSize; % runs every 200 samples (= myBufferSize)
lh = s.addlistener('DataAvailable',@refillBuffers); % function to call

myDataBeingLogged = false;
trigInd = 0;
s.startBackground();
% =========================================================================


%% Listener function
    function refillBuffers(src,event) %#ok
        
        % Get the current data
        ai0data = event.Data(:,1);
        ai0time = event.TimeStamps;
        dio1data = event.Data(:,2);
        
        
         
        %% THIS CAN BE REPLACED WITH ANOTHER TRIGGER MECHANISM=============
        % Check if the trigger condition is met
        trig = event.Data(:,2) > 0.5; % triggers when digital signal is high
        %==================================================================
                
        %% Find the first data point that fits the trigger condition
        if any(trig) && (myDataBeingLogged == false)
            trigInd = find(trig, 1, 'first');
            myDataBeingLogged = true;
        end
        
        
        
        %% Refill the buffer and throw out data beyond pretrigger time (FIFO)
        newData = [ai0data dio1data];
        myCircularBuffers = cat(3, myCircularBuffers(:,:,2:end), newData);
        myCircularTimeBuffer = cat(3, myCircularTimeBuffer(:,:,2:end), ai0time);
        
        % Actions for when the trigger condition is met
        if myDataBeingLogged == true
            if myCurrentBuffer == (captureLength/myBufferRefillPeriod) + 1 % +1 to account for the padded buffer (line 27)
                % Reorganize data once trigger condition met
                myCircularBuffers = permute(myCircularBuffers, [1 3 2]); % rearrange 3D matrix for proper reshape
                myCircularBuffers = reshape(myCircularBuffers, myNumBuffers*myBufferSize, myNumChannels);
                myCircularTimeBuffer = reshape(myCircularTimeBuffer, myNumBuffers*myBufferSize, 1);
                
                % Clean up HW resources
                s.stop();
                s.release();
                delete(lh);
                
                % Extract the pretrigger length and the capture length from
                % the buffer.
                numBufferSamples = myNumPretriggerBuffers*myBufferSize; 
                fullCapTrigInd = numBufferSamples + trigInd;
                trigTime = myCircularTimeBuffer(fullCapTrigInd);
                numCapSamples = captureLength * mySampleRate;
                reqCapture = myCircularBuffers((fullCapTrigInd-numBufferSamples):(fullCapTrigInd+numCapSamples),:);
                reqCaptureTime = myCircularTimeBuffer((fullCapTrigInd-numBufferSamples):(fullCapTrigInd+numCapSamples),:) - trigTime;
                
                %% EDIT FOR CUSTOM ACTION==================================
                % Add to or replace this section to save data
                subplot(2,1,1);
                plot(reqCaptureTime, reqCapture(:,1));
                subplot(2,1,2);
                plot(reqCaptureTime, reqCapture(:,2));
                %==========================================================
            end
            myCurrentBuffer = myCurrentBuffer + 1;
        end
    end % refillBuffers

end % my_sw_pretrigger_session

Contact us