Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Retriggerable AI hanging and missing triggers on restart

Re: software vs. hardware timing

Hani's method should be a much more CPU-efficient method for getting your data as the loop execution timing will be driven by the hardware.  When he directly calls DAQmx Read while wiring in the desired # samples, DAQmx Read won't return until detecting that the desired # of samples becomes available (or there's a timeout).  While waiting, it will yield the CPU and there are even some DAQmx property nodes that let you fine tune this waiting.  (This kind of behavior is one key benefit of the DAQmx driver compared to the legacy driver.  Note that the Windows task manager may still report 100% CPU, but you'll be able to multitask because DAQmx will yield as necessary.)

Your method would gobble up CPU as it polls for # samples available as fast as the loop can run.  In this sense, your method depends on application-level software timing to gather the data.  You're right though that you should eventually get the same data either way.  In a troubleshooting situation involving a kind of un-responsiveness though, it'd be good to avoid hogging CPU or memory resources wherever possible.

If I remember your app right, one further enhancement of Hani's method might be to request (triggers per step)*(samples per trigger) from DAQmx Read and get rid of the loop.  After reading the complete chunk of data all at once, you can then break it down into chunks of ~1000 samples per trigger or whatever is the exact # of finite pulses you generate per trigger.

I find your "weird observation" intriguing.  Often when a behavior tracks to some magic # like a power of 2, there really *is* some underlying and consistent explanation.  I was about to speculate about the board's hardware FIFO, but just looked it up and saw that it's in the Mega-sample range.  Still, I'd keep prodding about to explore whether the magic # behavior happens around the specific value of 1024, or whether it happens for other multiples of 16, or powers of 2, or whatever.

-Kevin P.

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW?

(Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).



0 Kudos
Message 11 of 26
(1,595 Views)

Thanks for the clear explanation Kevin.  I made a little test program to try using from 1 to 1024 samples per trigger.  For each value I would run the loop 1,000 times (i.e. 1 trigger per step, 1,000 steps).  I set the timeout value in the DAQmx read so when the pulse train stops triggering I would get an error.  I recorded how many loops were acquired before an error for each number of samples per trigger as well as the amount of time taken to acquire the data vs. the expected time.  See the attached pictures and the vis I used.  It looks like I generally get no errors (at least for 1,000 steps) for values up to around 384 steps per trigger.  After this point every multiple of 16 works.  Other values usually fail.  I have noticed that putting a slight delay after the DAQmx read seems to help.  For example putting a conditional probe on the error from DAQmx read greatly improved the number of times I successfully acquired 1,000 steps.  After I saw this I fooled around with putting a dummy loop in to cause a delay and that also seemed to help.  I don't think I want to put an actual sleep call there since my trigger rate is 100 Hz and in my previous experience with Windows it seemed like the minimum sleep time is usually 10 ms.  So that's the first problem.

The other thing I noticed was that for values of samples per trigger that were not multiples of 16 it took about twice as long as it should have to get the data.  I had noticed earlier that if I didn't specify the number of samples to read in the DAQmx read it returned data in multiples of 16.  If I had 2 samples per trigger, the DAQmx read (with no sample number specified) returned only after 8 triggers (giving me 16 data points).  The disconcerting thing now is that I if actually specify 2 samples to the DAQmx read it still takes 8 triggers to return but only gives me 2 data points, apparently discarding the other 14!  From my timing measurements specifying 2 samples per trigger took 8 times as long, 3 samples took 6 times as long, 4 samples took 4 times as long, etc.  Above 16 samples per trigger, only multiples of 16 took the expected amount of time, everything else took twice as long.  It seems the DAQmx read only returns when has the number of data points specified, then rounded up to the next multiple of 16.  I've watched the pulse train on a scope and confirmed that it's not that its missing triggers.  That's the 2nd problem.

To me the 2nd problem, while undocumented and annoying, isn't a big deal; I prefer powers of 2 since I later perform an FFT on it.  The first problem with the pulse trains stopping triggering is a problem that I would like to fix.  Also, I can't really use your suggestion of reading in multiple triggers in one block.  I'm trying to fit the data from each trigger in real time and the time it takes to fit is only slightly less than my trigger rate.  NI people, is there someone that is an expert in the pulse train generation that can comment?  Can I talk to someone (I don't have a service contract) since this really seems to me to be a bug in a board and/or software that I've just purchased? 



Message Edited by Phamton on 11-09-2007 05:50 PM
Download All
0 Kudos
Message 12 of 26
(1,582 Views)
0 Kudos
Message 13 of 26
(1,579 Views)

 After this point every multiple of 16 works.  Other values usually fail.  I have noticed that putting a slight delay after the DAQmx read seems to help.

I don't have LV near my network PC and can't examine the code now.  The fact that a slight delay after the read helps should prove to be a very helpful clue though.

The second problem sounds to me like a board-specific behavior.  I've read other threads where certain boards would not return single 16-bit samples.  They waited to pack two of them into a 32-bit wide data chunk before transferring to system memory.  I don't know your board in detail, but your description sounds like your board only wants to transfer data in 16-sample multiples.  When you want 2 samples per trigger, it waits for 8 triggers to accumulate the 16 samples -- thus 8x factor.  When you ask for 3 it waits for 6 triggers to accumulate >= 16 samples,  ask for 4 or 5 each and wait for 4 triggers, etc.

There's a chance that there are DAQmx properties allowing you to change this behavior, but I don't know for sure.  I'm also only speculating in my diagnosis above.  Can anyone from NI comment?

The problem of the counters only retriggering properly for a while, then failing to respond, then "coming back to life" is not one I recall reading about previously on the forums.  I don't really know if that'll be good news or bad news to you, but it seems to be a fairly unique problem rather than a general, commonly-experienced bug.

-Kevin P.

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW?

(Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).



0 Kudos
Message 14 of 26
(1,560 Views)

Hello Phamton,

I will be looking into why multiples of sixteen for your samples per trigger produces the appropriate number of steps. 

I have also been looking through your initial posts and I see that you had originally modified the example Multi-Function-Ctr Retrigg Pulse Train Generation for AI Sample Clock.vi. I noticed that you will be changing external parameters after a predetermined number of triggers occur.  I assume that these changes will be made after the tasks are stopped and before they are restarted.  Will this functionality be added to the code at a later date?  I ask because it is not necessary to stop and restart the DAQmx tasks if there is no change to any of the properties of the counter or AI task. 

Regards,
Browning G
FlexRIO R&D
0 Kudos
Message 15 of 26
(1,518 Views)
Hi Browning,
  Thanks for looking into this.  I hope you can reproduce the bugs I've seen.  The code I've attached is really just a stripped down version of a much larger program (actually a set of programs).  In the actual programs I do have other VIs that change parameters between stopping and restarting the task.  There are a few reasons I think I would like to do this.  First, I would like to miss as few triggers as possible.  Second, if I leave the task running, I don't see an obvious way to deterministically figure out what data is valid (i.e. taken after the parameter changes have taken effect).  I could easily see cases happening where the first read after setting the parameters returns data prior to the changes.  Third, there are cases where a user might want to pause the acquisition.  If the task keeps running the buffer could easily overflow.  I can see non-ideal workarounds for many of these problems (for example, throwing out the first data from the first read after changing parameters) but it would be nice to just have something that works every time.      Thanks,

Paul
0 Kudos
Message 16 of 26
(1,512 Views)
Hi Paul,
 
I think I can shed some light on the 16 sample issue that you are seeing.  I see from your original post that you are using a PCI-6132, one of our devices which has a very large on-board FIFO.  The FIFO on devices such as this tend to move data in 32 byte chunks.  Essentially, data from your ADCs is staged in a 32 byte FIFO before being transferred into the devices main FIFO.  Once the data makes it to the main FIFO, it can then be transferred to the buffer on your host PC.  If you are only reading on one channel, this 32 byte chunk equates to 16 samples.
 
If you were performing 'normal' finite acquisitions, the driver would be aware of when the device was done clocking in samples, and flush any 'stranded' samples out of the 32 byte staging FIFO.  However, when using counters to perform retriggered acquisitions AI is set up to be continuous.  Because of this, the device does not know when it has finished a record, and there is no way for us to flush the data.  It will remain stranded until more data is clocked in.  If it is critical that you get data from one trigger without delay, then I recommend you try to constrain your record size to multiples of 32 bytes.
 
I hope that makes some sense.
Dan
Message 17 of 26
(1,498 Views)
Thanks a lot, Dan.  That makes perfect sense.  So one problem is solved, now I just need to figure out why the counters sometimes stop triggering.
0 Kudos
Message 18 of 26
(1,491 Views)

Hello Paul,

In order to correct the counter glitch you are seeing, it is necessary to reproduce the issue.  I see that you mentioned a scope in a previous post and if it is possible, could you scope the pulse train and trigger signal and trigger the scope off of the trigger signal?  Screenshots of this would be most helpful.  Along this line, please make sure that the trigger signal you are using matches TTL specifications and is properly terminated on the DAQ card.   

Also, could you read the trigger signal and the pulse train in using the analog input channels of your card?  This is possible by performing a continuous analog input task independent of the pulse train generation task.  You can continue to stop and restart the counter task, but the AI task should be continuous so that no triggers are missed.  Please include the code you use to perform this test as well as screenshots so I can also verify it on my end. 

Regards,
Browning G
FlexRIO R&D
0 Kudos
Message 19 of 26
(1,466 Views)

Hi Browning,

  I've attached the files requested.  Had problems finding a scope I could save a capture on so I ended up doing it the old-fashioned way.  One picture is zoomed in showing the trigger and a few of the sample clock pulses.  The other shows the length of the whole pulse train.  Note these are taken when the pulse train actually triggers.  When it doesn't I see the trigger and nothing on the pulse train channel (usually zero volts, occasionally 5 volts).  This is how I've been able to tell that only the counter train stops working.  For these pictures I had a sample clock rate of 2.5 MHz, 511 samples.  The trigger is 1 us wide at 100 Hz.  My connections to the board are made through a BNC-2110 box.

Download All
0 Kudos
Message 20 of 26
(1,437 Views)