Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Delay on Do Not Allow Regeneration mode

Hello,

 

My application is to control at the same time the position of one linear motor and the flow from a proportional valve. In order to do this, I will have while loops to evaluate the sensors signals (position and flow) and based on the errors (control), some corrections will be proposed and "new waveform" will be generated and applied, so I need to use the “Do Not Allow Regeneration” mode.

 

Well, to do preliminary tests I used the NI example (https://forums.ni.com/t5/Example-Code/Update-Multiple-Analog-Output-DAQmx-Channels-On-The-Fly/ta-p/3...) and I did few modifications to adapt. I also connected my analog outputs with the analog inputs to observe the delays when a new value is adjusted on-the-fly (ao0-> ai0; ao1->ai1).

 

When I am using a waveform with sampling rate of 200 S/s and 200 samples (waveform duration is 1 second) and a DAQ buffer with 200 samples, the delay between an on-the-fly adjust (offset, amplitude or PSOL) and the signal measured by the analog input is almost 8 seconds. I am testing with these numbers because so far, they are appropriate for my application.

 

I know that the buffer size and sampling rate determine the delay. But if my buffer size is 200 samples and the sampling rate is 200 S/s, should the delay be 2 seconds (because the write function is 2 buffer sizes ahead of the generation)?

 

My control loop runs every 1 second, but my output takes almost 8 seconds to be update, it is easy to understand that it is not going to work. On the other hand, change my control loop to 8 seconds will be a huge downgrade.

 

Please, someone would have any insights about what I am doing wrong? There is any way to work around this delay? Any suggestion, criticism or opinion will be very welcome.

 

About my hardware: I am using USB-6003, LabVIEW 2019, my PC is a Core i7 8th gen (when application is running CPU goes up to 40%).

 

Thank you!

Andrea

0 Kudos
Message 1 of 24
(2,636 Views)

8 seconds to update definitely does not seem right as the buffer is only set to be 200 samples with a 200 S/second clock. If the program is not giving the AO channel new data to write, then the AO channel should have received an output underflow error. How is this 8 seconds measured? Do you observe the 8 seconds delay every single time when the values are updated? The 8 seconds implies that the inner for loop ran with the old waveform values and writing the same values 8 times.

 

In the VI you uploaded, the inner loop is taking values from 2 controls and 1 local variable from another control to update the waveform being output. There will definitely be delay from when the control is being updated in the UI until the waveform written to the driver is actually updated. For instance, since the loop runs every seconds, from the UI the user have to update the control and hit enter, the inner for loop might not update the waveform from that update value until next iteration thru the loop. Because the current iteration is already underway. And if the user needs to update all 3 controls to update to update waveform. The delay from the UI will scale linearly if these control are provided by human input. Is there human input expected in this process? It sounds like a slow control application from your description but the VI tells a different stories with the event structure. Are these added for testing? But even if they are updated all the same time by another program, there still might be a 1 second delay because the current iteration is on-going when the value are being updated.

 

Also the example and your VI are both calling start in the for loop, so the first iteration will take a long time because there is setup time for the driver to start the task.

 

The data transfer condition is set to onboard memory empty and the buffer is set to exactly 200 samples. That is no ideal for continuous update. That means no new data can be written into the software buffer until the previous data has been transferred to the device. But the device is also set to not requesting new data until onboard fifo is actually empty. That would add extra delay to the data transfers. You would want to set your software buffer size to be bigger so it can store up more data and data transfer should be onboard memory less then full to allow less latent data transfer.

 

The CPU is running 40% because the while loop with the event structure has no wait in it so until the AO is triggered by the event structure. That while loop will run as fast as the computer allows. I suspect after the AO is running, that the program will no longer take 40% of CPU as the while loop is force to slow down.

 

In the inner loop, a for loop is used to generate an array of identical element. This can be done more efficiently using the initialize array primitive in LabVIEW.

Message 2 of 24
(2,590 Views)

Hello Jerry, thanks for your comments. Following are my answers.

 

Answer first paragraph: I'm measuring the 8 seconds watching the change on the analog input. I hit only one button (PSOL, amplitude or offset) changing its value and start a stopwatch, when I first watch the change in the analog input, I stop the stopwatch. The analog output keeps the old value until the new one starts. If I change very times the same button, some intermediary values are ignored but the output will show some of them, the best way to see this is using the vi.

 

Answer second paragraph: As I mentioned, I'll use control loops to find these three new values (PSOL, amplitude or offset). For now, these three new values (PSOL, amplitude or offset) are available every 1 second and are updated once. In these tests, I'm adjusting only one at the time.

 

Answer third paragraph: there is no error about no samples available even when I increase the sampling rate. But as you mentioned bellow, I can improve this, but I don't believe that it is causing the delay.

 

Answer fourth paragraph: I used the Onboard Memory Empty because according the NI link (https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019Mg6SAE&l=en-US) "... the new waveform will be seen quickly on the output". I tried new buffer sizes, when I used 400 samples, I had the same delay, when I used 600 samples, I had the error -200292 every 3 seconds.

 

Answer fifth paragraph: I used the example from NI which no wait time was applied in the inner while. I really don’t know how it will work if I include wait times in the inner while, I can try. I have to clarify, the CPU processor usage is not a concern, I just gave this information in case it is worth.

 

Thanks again!

Andrea

0 Kudos
Message 3 of 24
(2,580 Views)

Hi Jerry,

 

Just complementing.

 

About your concern "The CPU is running 40% because the while loop with the event structure has no wait in it so until the AO is triggered by the event structure. That while loop will run as fast as the computer allows. I suspect after the AO is running, that the program will no longer take 40% of CPU as the while loop is force to slow down".

 

Well, I have the indicator “in loop” in the front panel that shows the iteration rate of 1 second, so this while is not running as fast as the computer allows.

 

Tks,

0 Kudos
Message 4 of 24
(2,578 Views)

There's a lot of good info and advice in that last reply by Jerry_X, but I think there's a little mixup in the part about the onboard buffer and latency.  I'll get back to the specifics later, first here are some general comments and questions.

 

Control loops usually want low latency updates at regular time intervals.  Buffered output is great for timing regularity but not so great for low latency.   Unbuffered software timed output is often better for low latency but not so great for timing regularity.  So you usually have to figure out your priorities and make tradeoffs.

 

Since it seems you don't need a particularly fast update rate, I'd normally expect low latency software timing to be a better option.  However,  you also seem to have one output signal that needs to be a sine wave (?) where you control the amplitude and DC offset occasionally.  The frequency is fixed, and you seem to want to define at least 5 cycles of this sine wave for each update.  All of this strikes me as *unusual* for a control system.

   Can you explain why you're doing things this way?  What is it about your system or actuators that require it?

 

Now let's get back to the "mixup" I referenced earlier:

 


@Jerry_X wrote:

The data transfer condition is set to onboard memory empty and the buffer is set to exactly 200 samples. That is no ideal for continuous update. That means no new data can be written into the software buffer until the previous data has been transferred to the device. But the device is also set to not requesting new data until onboard fifo is actually empty. That would add extra delay to the data transfers. You would want to set your software buffer size to be bigger so it can store up more data and data transfer should be onboard memory less then full to allow less latent data transfer.

I think things are pretty much opposite to the paragraph above and that you should stay with the "onboard memory empty" setting to reduce latency, as described here.  You might *also* need to consider other nearby properties related specifically to USB.  I don't tend to use USB devices for demanding apps so I can't offer further first-hand advice.  But here's one pretty good overview I found, and here's another thread that touches on one of the properties too.

 

 

-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).
Message 5 of 24
(2,568 Views)

Sorry, I missed that the event structure has a timeout of -1 which means it is waiting indefinitely. So the while loop is blocked until someone triggered the AO.

0 Kudos
Message 6 of 24
(2,565 Views)

Thanks, Kevin, I figure out where the mistake in my thinking was. 😓 I did not think about the onboard buffer on the device. I definitely should not post anything on the forum before I had my coffee in the morning. Yeah, the link you posted is correct that transfer condition of FIFO empty will help the waveform reflect the change sooner. 

 

Looking at the spec, 6003 can store 2047 samples in its onboard buffer. The 8 seconds delay is probably from having to propagate thru buffered up 2047 samples FIFO + the intermediate buffer is provided by the USB endpoint on the device before it can output the new data being written. I am suspecting the AO inner loop is running faster than once per second initially until the onboard buffer and intermediate USB buffer is full. I am not sure how much the driver respect the data transfer condition on 6003. Due to the high latency on USB bus, the driver is biased toward buffering as much data as possible to prevent overflow on the AO device.

0 Kudos
Message 7 of 24
(2,558 Views)

We can add time delay to the while loop to force it to write less so less data is buffered up in the onboard buffer and intermediate buffers. However, I don't know if doing this in such a way will improve the data delay below a second. And it is also a little tricky such that we have to make sure we don't delay the write too much such that the device will underflow its AO. Would 1 second of delay meet the application's requirements? What is the delay requirement we are trying to meet here?

 

Continuous output streaming over USB is designed to get data over the bus as efficiently as possible in bulk packets. Changing waveform on the fly with data on demand is not the ideal usage for continuous output. Does the application requires a continuous sine wave as shown in the code?

0 Kudos
Message 8 of 24
(2,550 Views)

Hi Kevin, 

 

In my application I need timing regularity, for example, my linear motor is "always" running a multi-sinusoidal waveform (4 frequencies). The linear motor is connected to a big syringe plunge, so the multi-sinusoidal waveform applied to the motor will generate a multi-sinusoidal flow at the syringe output. Then, I measure the frequency components (FFT) of the flow signal (regularity is extremely important) and if necessary I will change the amplitude of each frequency in the multi-sinusoidal waveform. Well, I need some time to acquire enough data for the frequency domain (now is 1 second), this is not very frequent, I guess.

 

The other waveform is to keep a proportional valve with a continuous bias flow. I decided to build a waveform with constant values in order to put the two signals together to the output once. I totally understand that this could be improved.

 

Yeah, the frequencies will be fixed (always), I will just need to change the individual amplitude of these frequencies.

 

I was expecting a latency of 2*buffer size (totally fine for my application), but I'm seeing almost 8*buffer size. I probably doing something wrong, but I can't see it.

 

I'll dig in the links about USB devices limitation, this is new for me.

 

Thank you!

Andrea

0 Kudos
Message 9 of 24
(2,541 Views)

Hi Jerry,


I just answered Kevin's questions, I think that your answers are also there. But I would like to enforce: 1-) I was expecting a latency of 2*buffer size, this will be okay; 2-) Yes, my application requires a continuous multi-sinusoidal waveform running (always) and without Glitching.


Thank you so much!
Andrea

0 Kudos
Message 10 of 24
(2,536 Views)