Triggering with a DAQ board--how do I pull data out of startBackground and tell MATLAB to take a few more samples?

Good afternoon,
I'm having some trouble updating some old NI interfacing code (for a PCI-6115) to the new session based interface in 2011b.
Here's the basic idea: I'd like to run my DAQ board like an oscilloscope, so I set it to passively scan, wait until my signal passes some threshold value, and then record a sample for X length of time (or NUMBEROFSAMPLES number of samples).
I've read through http://www.mathworks.com/products/daq/demos.html?file=/products/demos/shipping/daq/demo_compactdaq_background_acquisition.html and that's given me the basic idea of what needs to be done, but I'm still having trouble getting my code to work properly.
Here's my code %Initial routines for creating the daq session and initializing the channels (device = daq.createSession('ni'), etc.) % thresh = 2; % 2V threshhold value
device.NotifyWhenDataAvailableExceeds = NUMBEROFSAMPLES;
lh = device.addlistener('DataAvailable', @(src, event) stopwhenpassthresh(src, event, thresh));
device.IsContinuous = true;
device.startBackground;
function stopwhenpassthresh(src, event, thresh)
if any(event.Data > thresh)
disp('Triggered')
src.stop;
end
end
Some questions that I have: - How do I pull event.Data and event.TimeStamps out from the stopwhenpassthresh function into something I can process? - If it was at all possible, I'd like to be able to tell my code that when we pass the threshhold value, it should take one extra run of data (and then I can lop off the extra data afterwards). It'd also be nice if I could get a bit more control over the pre-trigger data as well.
Thank you for your help, Paul

 Accepted Answer

This may be of help! I proposed 3 different methods, chose whats best in your case: http://www.mathworks.com/matlabcentral/answers/6258-thread-subject-nidaq-continuous-and-background-acquisition

1 Comment

As best I can tell, this works! I'm using Walter's approach of a circular array (so I don't overload any memory) so I'm using a global counter as well. It's kind of a kludge (still awaiting input from Mathworks about 2012a's trigger routines) but until things go horribly wrong, I'm happy with it. Thanks!

Sign in to comment.

More Answers (1)

Use the same data sharing techniques as for graphic callbacks; see http://matlab.wikia.com/wiki/FAQ#How_can_I_share_data_between_callback_functions_in_my_GUI.3F

7 Comments

Hi Walter,
Thank you for the reply. I'm still a little hazy on how I'd use these techniques (beyond saving files, but I'm worried that might end up slowing things down). How would I call something like getappdata with every DataAvailable event (particularly if it's updating every 10 ms or so)?
Best,
Paul
Use nested functions and shared variables.
The question becomes how you notify your program that it needs to deal with the event information before you overwrite it with the next asynchronous callback ? And the answer to that appears to be: You Don't. Queue the information instead and let the processing routine deal with it when there is time. A circular queue is possibly an appropriate data structure.
Good morning,
I think I understand how to do the circular queue (have a counter loop 1 to 3 and back again, and write the output to the appropriate third of an array), though I'm unclear how I'd be able to expand the scope of anything nested to the appropriate level. Every time I've tried to get my referenced function in the addlistener routine to output something (so any changes are not restricted to the scope of that function) this have not worked properly.
A rough idea I'd have would be
Kill the function in the listener that stops the DAQ board when we pass the threshold
numscans = NUMBEROFSCANSPERDATAAVAILABLE;
thresh = DESIREDTHRESHHOLDVOLTAGE;
breakflag = 0;
onemore = 0;
counter = 0;
trialarray.t = zeros(1, 3*numscans);
trialarray.V = zeros(NUMBEROFCHANNELS, numscans*3);
lh = addlistener('DataAvailable', @(src, event) stopwhenpassthresh(src event thresh));
device.startBackground;
while breakflag == 0
realcounter = mod(counter,3);
testt = getappdata(lh, event.TimeStamp));
testV = getappdata(lh, event.Data));
if testt(1) ~= trialarray.t(realcounter*numscans+1)
% Checking to see if we already pulled this data
trialarray.t((realcounter*numscans+1):((realcounter+1)*numscans)) = testt;
trialarray.V(:,(realcounter*numscans+1):((realcounter+1)*numscans)) = testV;
counter = counter + 1;
if onemore == 1 %Letting me take one more data run
breakflag = 1;
end
if any(testV>thresh)
onemore = 1
end
end
end
Is this what you were thinking about?
Much appreciated,
Paul
And I just realized there may be a somewhat simpler version to this
Instead of using getappdata, my listener routine is
lh = device.addlistener('DataAvailable', @(src, event) testt = event.TimeStamps, testV = event.Data)
As before, I use the while loop to keep on running and compare results to new ones. Not sure if the listener will let me actually write to testt and testV, but maybe this will simplify matters?
Anonymous functions cannot contain assignments using "="
Argh. Oh well, is the routine I wrote above what you had in mind?
Sorry, I will look at it more closely when I have time.

Sign in to comment.

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!