05-14-2023 01:39 AM
This NI official page mentions 【For example, when using the DAQmx Read VI with the autostart property set to True, the DAQmx Read VI will start the acquisition task and stop the task once the last sample is acquired. If you use the DAQmx Read VI in a loop, the measurement or generation starts and stops in each iteration of the loop due. To avoid this you can explicitly tell it to start and stop with the DAQmx Start Task VI and the DAQmx Stop Task VI. 】I have some questions about this issue, but I haven't found the answer in the official documentation. I hope someone in the forum can answer😀
If DAQmx Start Task VI and DAQmx Stop Task VI are not explicitly called, will the DAQmx Read VI of the continuous acquisition task also start and stop in each loop iteration? (This seems to be what the official page means.) If the limited sample mode is explicitly set with DAQmx Timing VI, is the actual number of samples per channel determined by the samples per channel of DAQmx Timing VI or the number of samples per channel of DAQmx Read VI?
3.【Explicitly starting the task prior to the loop and stopping the task after the execution of the loop significantly improves performance. 】Here it should be saying: explicitly calling DAQmx Stop Task VI after the loop (in which DAQmx Read VI will be called) can significantly improve performance. But this call happens after the call to DAQmx Read VI, so how does it in turn affect the behavior of DAQmx Read VI? (Does it happen at compile time?)
4.If I only explicitly call DAQmx Start Task VI before the loop and do not explicitly call DAQmx Stop Task VI after the loop (instead, I end the task with DAQmx Clear Task VI or something like that), will the 【Stop the task after the last sample is acquired]】in 【when using the DAQmx Read VI with the autostart property set to True, the DAQmx Read VI will start the acquisition task and stop the task once the last sample is acquired. 】still happen automatically? If so, does the explicit call to DAQmx Start Task VI before the loop still serve to improve performance?
5.Is there a difference in the behavior of DAQmx Start Task VI for continuous and finite sampling? My understanding is that calling DAQmx Start Task VI in continuous sampling will start the acquisition regardless of whether DAQmx Read VI is called or not, while in finite acquisition, calling DAQmx Start Task VI will cause the program to transform into the running state, but not really start the acquisition until DAQmx Read VI is called. Is this understanding correct?
There are a bit too many questions and I hope someone in the forum can answer some of them. Many thanks.
Solved! Go to Solution.
05-14-2023 04:26 AM - edited 05-14-2023 04:27 AM
Well if you don’t call Start, the Read will start it implicitly if the according property is true.
For continuous infinite acquisition there is no automatic stop and you need to Stop or Clear the task to end the acquisition even if it was started implicitly.
On the other hand a finite acquisition will always stop as soon as the number of scans that was set has been acquired, and an extra explicit Stop after that won’t really do anything (maybe it returns a warning about that).
05-14-2023 07:53 AM
Answering by number:
1. The hardware will stop the task after the last sample is collected, even if you don't read the data for a while. Note that if you configure for Continuous Sampling there's no known "last sample." In that case, the task *won't* stop automatically.
2a. As mentioned above, a Continuous Sampling task *can* be auto-started by the first call to DAQmx Read, but it will *not* be auto-stopped after executing the read. The next read recognizes that the task is already running and can skip past the overhead of getting the task started.
2b. For Finite Sampling, the actual # samples per channel to be captured is determined in the call to DAQmx Timing. This governs the total # of samples the hardware and driver will attempt to deliver to the task buffer after the task starts, all of it happening in the background without further app-level coding.
The call to DAQmx Read determines how many samples per channel to retrieve out of the task buffer into application-accessible memory. You're always allowed to read fewer samples than the total # to be captured, subsequent reads pick up from wherever you left off.
BTW, I agree that some of these definitions and behavior are confusing -- consider adding kudos to my related thread on the Data Acq Idea Exchange.
3. Here's the main idea. There's noticeable overhead involved when starting or stopping a task. So a good efficiency goal is to do each thing exactly once. That implies that they should be placed outside any loop. It's really the act of Starting before the loop that makes the Reads faster. You're right, the Stop has no influence on the Read, it's just that if you only Start once, you also need to only Stop once.
DAQmx has a thing known as the Task State Model and the task has internal knowledge of what state it's in. If you call Read before ever calling Start, the task has to work through various states before it can get to the Running state -- this is the overhead I referenced earlier. Further, if you also never called DAQmx Timing so that you're in on-demand sampling mode, *every* call to DAQmx Read is capturing your "last sample" (because it's also your first and only sample). Thus, right after the capture happens, DAQmx will internally transition back to the state it was in prior to your call to DAQmx Read.
4. If you explicitly Start before the loop then yes, performance of the Reads inside the loop will still be improved, even if you don't explicitly call Stop after the loop. If necessary, the call to Clear will stop the task as part of its cleanup duties.
5. No, not correct. Assuming no triggering condition has been configured, samples start being captured immediately after the call to DAQmx Start regardless of Finite, Continuous, or on-demand sampling mode.
-Kevin P
05-14-2023 10:53 AM - edited 05-14-2023 10:56 AM
05-15-2023 09:08 PM
I'm an old-timer and here's my advice:
Instead of exploring all the nuances of default behavior under various conditions, you'd be better off putting yourself fully in charge of your tasks by programming things more explicitly.
To me, the idea of configuring a Finite Sampling task, then iterating many times to read a subset of those finite samples, and also relying on an automatic task restart after reading all that the task was configured to collect -- I'd call it a "code smell". Maybe it works under specific conditions, but it just doesn't seem like a good foundation to build on.
What is it you really want your app to do? There's probably a better (i.e., clearer) way.
-Kevin P
05-16-2023 07:37 AM
Agree with what you said, I'm just asking this question out of pure curiosity🤔
05-16-2023 11:41 PM
The best way to reduce overhead when starting (or re-starting) a task is to first use DAQmx Control Task to "commit" the task before you start it. This advances the task state as far as possible without putting it into the run state, so when you *do* call DAQmx Start, you'll have minimal overhead. Here's a starting point for how it'd look:
Committing the task allows DAQmx Start to execute faster (because it has less to do). And then when you call DAQmx Stop, the task only reverts back to the committed state, so the next Start on the next iteration will *also* execute faster with minimal overhead. And so on.
This can be a useful pattern when you have a Finite Sampling task with a Start Trigger and a device that doesn't support hardware-level retriggering. It minimizes the gap time from the end of one finite capture until the task gets re-started, ready for the next trigger.
-Kevin P