LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Wait time within a While Loop

I was always under the impression that Wait Timers (e.g. Wait and Wait Ms Multiple) always executed last within a while loop. As I'm reading up on timing of real-time loops I'm finding that NI suggested using a stacked sequence structure to force timing to run last. Has my assumption of wait timer execution been wrong all this time or do PC and RT systems differ in how loops handle timing?

 

Thanks,

Craig

0 Kudos
Message 1 of 7
(12,018 Views)

That has always been my assumption as well. Nothing else would make sense. Why put in a 100msec wait if it's going to run in parallel with a process that takes 100msec to run? Maybe I'm missing something? And if it were that important to use (stacked?! Smiley Surprised) sequences to insure proper timing maybe the timing primitives should have been given error in and out clusters 3 or 4 versions ago.

PaulG.

LabVIEW versions 5.0 - 2023

“All programmers are optimists”
― Frederick P. Brooks Jr.
0 Kudos
Message 2 of 7
(12,010 Views)

They execute in parallell. If you want to avoid placing the wait in a sequence frame you can use the express version.

 

The benefit is ofc to set a loop time without bothering about the execution time, if some visa communication takes 20 or 250ms but you want to send one packet a second it's nifty to just set wait(1000) instead of getting the time of start and calculating needed wait ...

 

It's _usually_ the last to finish execution though. 😉

 

/Y 

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 3 of 7
(12,004 Views)

Perhaps I misunderstood what I was reading. Perhaps NI is suggesting that a sequence structure be used to initalize the timing of a loop when using the Wait Ms Multiple. (which to me makes sense in order to guarantee the loop time of the first interation) however why the Wait MS Multiple is placed in a sequence structure within the while is still a bit confusing. Maybe I'll have to think on Yamaedas reply a little longer.

ss.png

0 Kudos
Message 4 of 7
(11,993 Views)

Yamaeda is fully right. A LabVIEW timing node is just like any other LabVIEW node. If there is no data dependency LabVIEW is free to schedule it anytime it wants, which in case of other asynchronous operations such as VISA or network IO is actually nearly parallel with them. If all the other nodes are synchonous then I guess LabVIEW might prefer to execute the timing node as last, but that is not something that you should rely upon. If there is any reason to want to have a specific order of execution you have to make sure to force LabVIEW to do that by using some dataflow dependency (and a sequence structure can help with that). The sequence structure is by no means necessary however, as I have my own timing nodes with an error in and error out cluster for this purpose. Additional advantage of this is that they will not wait if an error is passed in.

 

And if they have any reason to be there, they will indeed be the last to finish, as Yamadea also correctly states. Smiley LOL

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 7
(11,982 Views)

This is really something, which is not very intuitive for most users and even NI sources do contain erroneous information about this. I was under the wrong impression myself for quite some time 😞

 

So, i will tell you how those functions work and what the trick of "initialization" is.

1. They do work in parallel to your loop code, just as Yamaeda correctly stated.

2. They are based on the millisecond timer value. This value starts with 0 somewhere in the past, afaik somwhere within the boot process of the OS.

3. a) Wait (ms): When LabVIEW calls a VI for example, if millisecond timer value is 112 ms and milliseconds to wait is 10 ms, the VI finishes when millisecond timer value equals 122 ms. (From the help)

3. b) Wait Until Next Multiple (ms): When LabVIEW calls a VI for example, if millisecond multiple is 10 ms and millisecond timer value is 112 ms, the VI waits 8 more milliseconds until the millisecond timer value is 120 ms, a multiple of 10. (from the help).

 

The timer value can have any value within U32. If you keep the PC on for more than 49.7 days, the timer value will roll over and start with 0 again. This could lead to a single timing intervall being off by a bit or even completly mess up the following timing (never tested this, don't know if there are tests).

 

I think, that 3.a) is quite clear. But i want to elaborate on 3.b) a bit more:

If the timer value is x, and you configured the Wait Until Next Multiple to 100ms, the first call will wait 100- (x mod 100) ms. So if x = 240, the first wait is 100 - (240 mod 100) = 100 - 40 = 60ms. After this, the Wait Until Next Multiple is "initialized" so it should wait for exactly 100ms for each following iteration (if implemented in parallel). Given non-determinism, it will jitter a little, but it is really close to 100.

 

If placing either of the function into a sequence, like craige's screenshot shows, the wait is not parallel anymore. So Wait (ms) will "add a 'static' delay" whereas Wait Until Next Multiple(ms) will "reduce its waiting time as long as the whole iteration is still less than the time to wait. If the whole execution of the iteration succeeds the time to wait, one iteration will be 'dropped'".

 

I will create an example for this and post it here if i have the time.

 

hope this helps,

Norbert

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
Message 6 of 7
(11,973 Views)

So, ok, coming back on this.

Attached you find a small example to show my remarks in the previous post.

 

How to use it:

The main focus is in the first iterations once "Wait now!" is pressed. So it is usually not of interest to run the "waiting" for more than 5-10 iterations.

In order to see an "understandable" behavior, i suggest to wait at least 100ms. I configured "Time To Wait" to be at least 10 (coercing).

 

The second focus is "Time Value".

For "Wait (ms)", the "Time Value" will have any number, but increase each iteration by the amount of "Time To Wait".

For "Wait Until Next Multiple (ms)", "Time Value" will be initialized to a value, which is a integer multiple of the "Time To Wait" and will increase each iteration to the next multiple.

 

My example does not contain parallel code, so it does not show the parallelism of the waiting functions!

Nevertheless, understanding the shown behavior is the key. Because if the code running in parallel to the waiting requires less execution time than the wait function will wait, the behavior will be exactly as shown.

If the parallel code requires more execution time than the waiting, "Wait (ms)" is already finished and therefore the loop will immediatly continue with the next iteration (high CPU load!).

If the parallel code requires more execution time than the waiting, "Wait Until Nexty Multiple (ms)" will wait that long that the "Time Value" is again in line to an integer multiple of the "Time To Wait" (so this one keeps on running in parallel until waiting time is calculated and over). Hence, "Wait Until Next Multiple" will still introduce a waiting time (reduced CPU load), but you will "miss complete iteration slots".

 

As you can see, using a single "Wait Until Next Multiple" outside the loop for initialization can make sense if the first iteration should also have a "close to normal" execution time.

 

Please note that the Timed Loop does something similar once started. As it does it during the iterations, the first 1-3 iteration(s) are called "warmup iterations". Most often, the first single iteration is sufficient for this though....

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
Message 7 of 7
(11,954 Views)