Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Effect of DAQmxTaskStop

Hi,

I am using a PXI-6733 board to generate waveforms based on advance pulses from a FPGA control system that is the master controller in our experiment. In some cases, the FPGA will abort a run and stop generating pulses: When this happens, we need to have something else advance the DACs to their final state. Our current approach is to read out the buffer position, stop the dacs, reload with the remainder of the waveforms, change the timing to internal clocks, and then restart. My question is whether there is a simpler approach?
Reading the documentation on the state model carefully, I've found the following parts:


1) Transitioning the State Backwards

When a task is implicitly transitioned backwards, it returns to the state of the task prior to the last operation that resulted in a forward state transition

2) Operations That Require State Transitions

You implicitly transition the task to a new state when you perform an operation that requires that the task be in a specific state and it is not. If this occurs, the task is implicitly transitioned to the required state. Some operations that require state transitions include the following:

[snip]

Calling the Write function/VI commits the task. If the value of the Auto-Start parameter is True, the task also is started. For more information regarding the auto-start behavior of write operations, refer to When Should You Use the Start Function/VI?

The way I read this, I should be able to use task->Control(DAQmxTaskStop) to return to the commited state from running, provided I started the task manually. If I try this, I get the following exception:

You only can get the specified property while the task is reserved, committed or while the task is running. Reserve, commit or start the task prior to getting the property.
Property: CNiDAQmxStream::TotalSamplesGeneratedPerChannel
Task Name: MyTask
Status Code: -200983

Which seems to indicate that the task is not in the commited state. What am I missing here?
Also, is there a simpler way of doing this? (E.g., is it possible to change the sample clock source from external to internal while running?)

Thanks,
Janus




.

0 Kudos
Message 1 of 6
(3,681 Views)
You always find out right after you post 🙂

I was calling l_task->Control(DAQmxTaskVerify) after writing the waveforms: This way I was calling start from the "Verified" state -- so that's where stop returned me. After removing the DAQmxTaskVerify everything works nicely.

Janus

0 Kudos
Message 2 of 6
(3,676 Views)
Janus,

You could certainly manually control the task state, changing some parameters and starting it again. And you are accurate in your understanding of the task state model. Are you sure the task is actually running (it isn't a finite task that has completed by the time you run the Control method)? Could you perhaps post your code?

As for another way of doing this, I can think of one that I would prefer. I would set up a digital input change detection task to detect rising edges from 1.) your FGPA and 2.) a counter output (this would require a physical loopback wire from CO to DI). I would then use the "Change Detection Event" internal signal as the sample clock for your analog generatoon. Whenever you detect that your FPGA is no longer providing clock pulses, you could set your counter up to either 1.) generate a continuous pulse train (uses only 1 counter) if you have a finite analog output task, letting the board stop the generation after the appropriate number of samples, or 2.) generate a finite pulse train of a certain number of pulses (uses 2 counters) if you have a continuous analog output task and you wish to stop at an exact point in your waveform. This would require no modification of any analog tasks and buffers. Would this be an option? Please let me know and I can post more details.

Hope this helps,
Ryan Verret
Product Marketing Engineer
Signal Generators
National Instruments
0 Kudos
Message 3 of 6
(3,645 Views)
Ahh... I did not sroll down at all. Didn't see your code or  your second post. Regardless, my second paragraph still may be an option.

Hope this helps,
Ryan Verret
Product Marketing Engineer
Signal Generators
National Instruments
0 Kudos
Message 4 of 6
(3,643 Views)
Ryan,

Thank you for your reply: The second method you outline sounds very promising.

Your scenario 2 describes precisely what we need: We are generating the same waveform repeatedly, based on advance pulses from the FPGA. The waveform is only allowed to stop at the endpoint values (intermediate configurations are not stable).
The FPGA only aborts if forced to do so from our main controller software, so we can take necessary actions with respect to the DACs in this case if necessary.

I should perhaps also mention that the reason I am fiddling with this (working) code is that we need to extend it to multiple DAC-cards (requiring multiple tasks). This seems to be going quite smoothly by automagical advance pulse routing through our PXI backplane, but any modified way of finishing waveforms should of course be compatible with this operation.

Am I correct that the "change detection event" is a software event based on sampling the DI? If so, the method might not be applicable: First of all, we cannot accept "software in the loop" due to jitter (that's why we have the FPGA), secondly, we are pushing the envelope of the DACs, and are aiming for at least 700ksamples/s, so it might be hard for at sampled edge-detector to keep up at all?
A dedicated hardware gate would do the trick, of course, but compared to that, our current "reprogram with the remainder of the waveform" approach still wins.

Janus
0 Kudos
Message 5 of 6
(3,632 Views)
Janus,

The "Change Detection Event" is actually a hardware signal, but there is also a corresponding software interrupt that can be generated. Page 6-8 (97) of the M Series User Manual shows a block diagram of the change detection circuitry. There are examples of how to do this, but basically, you would use the m_task->Timing.ConfigureChangeDetection() function for a continuous acquisition, start the task, and never acquire any data. If you decide to go that route and encounter any difficulties, I'd be more than happy to help.

Regards,
Ryan Verret
Product Marketing Engineer
Signal Generators
National Instruments
0 Kudos
Message 6 of 6
(3,621 Views)