LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Deterministic loop is delayed when continuously rewriting AO's buffer

Solved!
Go to solution

some interest links:

 

Configuring the Data Transfer Request Condition Property in NI-DAQmx

http://digital.ni.com/public.nsf/allkb/45A7AC6B59E026B386256F90006DAA49

 

Data Transfer Request Condition for Continuous Analog Output using NI-DAQmx

http://digital.ni.com/public.nsf/allkb/45A7AC6B59E026B386256F90006DAA49

 

 

Message 11 of 14
(798 Views)

Dankeschön, Bernhard (I guess you are german 🙂 ?

 

Those links were very explanatory. I am still somewhat lost, but we're getting closer to solving this.

 

Your suggested parameters work! In the simplified VI as well as in the original VI. Unfortunately, the first iterations output the same signal once or several times. Additionally, if I call the DAQmx Stop Task VI and restart the task after a while, the first piece of signal that comes out belongs to the old update.

 

I can avoid this by using the following configuration: no regeneration, DMA, condition = onboard memory empty. The available space still gets consumed, but only very slowly, so it's OK. BUT: If I use this configuration in my original code, then things get weird, and I get errors -200290, -200018 and -200016 depending partly on the sampling frequency chosen, and partly on things that I haven't been able to track down.

 

Actually, to be more precise: In the original code, the AO is generated in a first round without problems. Then, a pause follows, and the AO is generated again. This time there is more computation going on in parallel, but I don't feel that it is so much that the computer couldn't handle it - in fact, the timed loop doesn't get delayed anymore.

 

My confusion arises from the fact that:

 

- Regeneration works fine (though I haven't checked the latency yet) in the case where more computation is going on. However, it produces bad first iterations, regardless of the computational load.

 

- No regeneration fails in the case with more computation, but the first iterations (when it works) are as desired.

 

 

So the computer can solve the two pieces of what I need separately. Is there a way of getting the best of the two options?

0 Kudos
Message 12 of 14
(784 Views)

Sorry, that was wrong! I had a mistake in the original VI and I wasn't monitoring all missed periods. I would like to upload that VI, but it is a true monster mammoth...


So, the things look like this: In the original VI, I start the task once (phase I), stop it after some seconds, and restart it again, this time with more computation going on in parallel (phase II). It is nevertheless not so much computation we're talking about.

 

All configurations work fine with phase I.

 

In phase II, the only configuration not delaying the timed loop or throwing an error is Bernhard's (DMA, reg, memory half full or less). The problem: Since the onboard FIFO is more than half full, the VI outputs always a piece of old data when restarted. I also haven't measured the latency, but I expect some.

 

I tried to set the transfer condition to "onboard memory empty" to avoid having old data played at the beginning. The timed loop then gets delayed in the first iteration or couple of iterations, the VI throws a warning 200015 and then works fine until the end.

 

If I disable regeneration, no matter what the transfer condition is, the timed loop is delayed, an error -200290 is thrown, and nothing is output anymore.

 

 

So, this makes some more sense now. In the line same of what The_Seeker commented, it seems that the write VI produces a peak just at the beginning of phase II and behaves fine from then on. Setting the condition to half full or less takes care of this peak, but leaves the buffer half full with old data. Mmmh....

 

0 Kudos
Message 13 of 14
(762 Views)
Solution
Accepted by topic author sls__

Solved!

This one was subtle.

 

The first iteration calls the Write VI after a time t (black line). It loads a full period of data into the board's buffer. The board will be busy until time t after the start of the next iteration (red line).

 

Problem.pngNow, since the next iterations contain a little bit more computation, they will need t' > t until they can call the Write VI. By then, the board's buffer is already empty and the AO has crashed.

 

To solve the issue, one has to make sure that t is as large as possible. This way, the following iterations will have plenty of time to load their data into the baord.

 

I came with this solution:

 

Sol.png

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


No regeneration and transfer condition = memory empty. Fast and with controlled* latency, just the way I wanted it 🙂 But it doesn't look too elegant, it blocks execution and it may be problematic if the contents of the middle frame change substantially. Is there any other way to tell the timed loop to run the Start Task VI just before the end of the iteration?

 

Thanks to Bernhard and Seeker for their helpful comments!

 

 

*as good as it gets, I guess!

Message 14 of 14
(735 Views)