Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Monitoring DAQmx progress during a long acquisition

My apologies if this should have been on the LabVIEW board, but I figured the DAQ pros hang out here...

 

I am writing a LabVIEW program to acquire a large number of simultaneously sampled points from an S-series board using DAQmx.  Depending on the user's configuration the acquisition can be extremely rapid or very slow.  The number of samples to acquire will be fixed, so I am using a finite sample size acquisition scheme.  In addition the acquisition may have to sit around and wait for quite some time before the hardware trigger is received.  To avoid having the user think that the process might have locked up I would like to provide a progress bar during the acquisition.

 

The architecture includes setting up the clock and trigger sources, then calling a DAQmx start task to "arm" the system.  The program immediately proceeds to a DAQmx Read with -1 on the "Samples to read" input.  This will wait (up to the timeout value) until the acquisition is complete.  This all works well and fine, but the progress is giving me problems.

 

I was hoping to place a loop above the DAQmx read that uses a DAQmx property node to report the number of samples acquired.  The closest thing I found was a DAQmx Read property node set to "Current Read Position".  This works great, except that it only fires after all of the data has been acquired and read.  I suppose that this is because it hasn't actually read anything until the read completes.  I also tried the "Total Samples Acquired", but again this is under the DAQmx Read property node, so the act of waiting for the read to complete seems to lock out DAQmx Read property nodes. Is there another property node class that I can use to keep tabs on the process?

 

Unfortunately I don't think that I can do a piecewise read where I read what has been acquired in the buffer, update the progress and then go back and read in the next set because in some instances we'll be aquiring at very high speeds on eight channels and I don't think the PCI bus can handle that kind of bandwidth.

 

Any thoughts?  Thanks in advance!!

 

Paul

0 Kudos
Message 1 of 7
(3,559 Views)

Hi Paul,

 

Almost all entrypoints to DAQmx tasks are serialized using a per-task mutex. This is why a blocking read operation seems to lock out the "Current Read Position" property.

 

Here are a couple of ways to prevent your calls to DAQmx Read from blocking:

  • Use the Every N Samples Acquired Into Buffer event like this example demonstrates: Acquire & Graph Voltage-Internal Clock-Every N & Done Event. Note that it's still possible to block if you read more data than is available.
  • Perform non-blocking reads by setting the timeout to 0. This will cause DAQmx Read to only return data that is already in the buffer, rather than wait for more data. Your program will have to determine when to read, because continuously polling is not a good idea, but there are several solutions that can work: polling the Read.AvailableSamples property (with some delay to avoid polling continuously), waiting for the Every N Samples Acquired Into Buffer event, or using software timing.

Brad

 

---
Brad Keryan
NI R&D
0 Kudos
Message 2 of 7
(3,553 Views)

Here's just a little more "user perspective" to build on Brad K's answer.  I feel like I generally know my

way around multifunction DAQ pretty well, but I was quite surprised to learn about a fairly basic DAQmx

behavior that Brad referenced in his reply.  I did not realize that queries to DAQmx Read properties would

be blocked by an earlier blocking call to DAQmx Read.

 

I've done a lot of apps with both finite and continuous acquisition in which I was also querying properties

like "TotalSampsAcquired" throughout the acquisition process.  I never encountered that blocking issue,

not even accidentally, for the following simple reason:  I've had a long-standing habit of *never*

making DAQmx calls that can block indefinitely. 

 

Brad offered one solution -- a short timeout value at or near zero.  Another approach is simply not to bother

calling the Read function until you need to.   Since you'd like to monitor progress through properties like

"TotalSampsAcquired" anyway, just go ahead and monitor until all samples have been acquired, and *then*

call DAQmx Read to retrieve them.

 

-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 3 of 7
(3,538 Views)

Kevin and Brad,

 

Thanks for the replies.  Reading the replies, I guess I could understand the role of Start Task and Read a bit better.

 

Can an acquisition be armed for hardware trigger and acquire the points by using only the Start Task?  If so, it seems that one method to do this is to configure and start the task, trigger the acquisition, monitor the acquisition with a TotalSampsAcquired property node and then when all samples have been acquired, issue a Read funtion to transfer all points out of the card's buffer and into the computer's memory.  Will that work?

 

I was under the impression (and this impression came from no where in particular) that the "Read" function was required to effectively wait for the samples to be acquired.  If the Start Task function will arm the card so that it waits for a trigger and acquire samples without blocking status reads to the card, then this is ideal.

 

Thanks again for everyone's input...

0 Kudos
Message 4 of 7
(3,536 Views)

I thought that I would go ahead and reply in case someone searches on this topic and could use the final outcome.

 

I went ahead and tried something that was suggested earlier in the thread and in doing so answered my own question.  In short, you do not need to call a "Read" function with a timeout of -1 in order to prepare the card for a triggered acquisition.  The "Start Task" function does this without blocking calls to DAQmx Read class property nodes.

 

So, the final solution that I implemented was to configure the acquisition as required, issue a "Start Task" function.  I would then enter a loop that would call the (DAQmx Read) TotalSampsAcquired property node.  This is not blocked at this point, so I get a proper response.  I then continue to check this value at a reasonable interval and update a progress bar accordingly.  Once I reach more than 98% of the points acquired, I exit the loop and fire off a "Read" function with a -1 timeout to wait for the remaining few points and then transfer them to the computer.  Once that has completed I issue a "Stop Task".

 

This seems to work just fine and did what I had originally envisioned.  Feel free to post back if someone knows of any pitfalls with this approach, but at this point I'm heading down this road.

 

Thanks to everyone who replied...

 

Paul

Message 5 of 7
(3,518 Views)

Hi Paul,

 

Sorry, I was out of the office.

 

Your conclusion that DAQmx Start Task arms the start trigger is correct.

 

Be careful using a read timeout of -1. A timeout of -1 means "wait forever if necessary", so it can still block. For example, with an external sample clock, if the clock signal stops before the last sample, then reading the last 2% will never complete, and the read will block forever. Waiting for TotalSampsAcquired to reach 100% would not block in this case. However, if you're using the onboard clock, this isn't as much of a concern.

 

Brad

---
Brad Keryan
NI R&D
0 Kudos
Message 6 of 7
(3,495 Views)

Thank you for the heads up on that.  I am using the onboard clock, but for future compatibility I should probably change the timeout to a calculation to wait over 2x the expected duration for the remaining number of points.

 

Thanks for everyone's help, the application is working well now.

 

Paul

0 Kudos
Message 7 of 7
(3,488 Views)