LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Having trouble getting wait(ms) to run in parallel in my While Loop

This issue has me at my wits end. I've posted a rather large snippet of my main data acquisition loop below. Let me explain it a bit:

 

The loop is the main loop that constantly reads the most current data from a thermocouple reader, a pressure sensor and also reads another sensor's readings by reading the last line from a data file being generated by that sensor. All of this works well. The pressure sensor (PX409) seems to be slow with data acquisition, but in general, the entire loop takes around 0.6 - 0.7 seconds to run if I remove the Wait(ms) VI at the bottom of the loop.

 

The case structure at the bottom of the loop is used to log data into a data file if a certain amount of time has elapsed since the last data logging event. I have it setup this way so my UI and graphs on the front panel are updated more frequently, while data is logged into a data file at a slower rate. I know that this is probably a terrible VI in terms of wiring, etc, but I'm fairly new to LabVIEW and have been learning a lot in the past week to get to this stage.

 

So everything works perfectly, except for the 2 second delay in the while loop that I am trying to introduce. Since my loop takes 0.6-0.7 seconds to operate without any delay, I want to essentially force this loop to take 2 seconds to execute every single time. From reading up on the Wait VI, it seems like the way I have used it is the way to go as it should run in parallel during the loop execution. Since the loop only takes around 0.7 seconds to execute, the wait should force it to wait another 1.3 seconds before it starts the next loop iteration.

 

However, this doesn't seem to happen. No matter what I set the delay to, my loop takes (delay + 0.7) seconds to execute, which seems to indicate that for some reason the delay is being chained before/after my loop execution and is not running in parallel. Does anyone know why this is the case and what I could do to fix the issue?

 

I also tried a simple VI to examine how Wait works (below the larger snippet). However, in that snippet, everything works as expected. The For loop takes around 0.7seconds to execute, yet the x-y indicator only increments in steps of ~ 2 seconds.

 

I'd really appreciate if someone could point me in the right direction.

 

 

snippet.png

 

simpleSnippet.png

0 Kudos
Message 1 of 23
(6,074 Views)

http://zone.ni.com/reference/en-XX/help/371361J-01/glang/wait_ms/

 

The wait is working like it should.  If you set the wait to 1350ms you should be pretty close to what you want.  If you want it closer to the 2 seconds you can try a timed loop instead of a while loop.  Right click the boarder of the while loop and you will have the option to replace with a timed loop.  Then you can set the period (dt) with the connector on the left with 2000 to get what you want.

 

My question is why you want to only have your loop only run every 2 seconds?  There are better ways depending on what you are trying to do.

0 Kudos
Message 2 of 23
(6,062 Views)

Bryan, thanks for your response. Why I am doing this is perhaps not all that clear to me either :). I just wanted a cleaner 1second refresh rate for the front panel UI so that the time stamp in seconds is also not a weird number. However, it isn't ultra critical, but the reason I am hung up on this is more so that I can understand how timing works in LabView.

 

With regards to your comment about this being the expected behavior...I don't quite understand. If I read this correctly: http://digital.ni.com/public.nsf/allkb/12B2EA9AD5B265AD86256257004DD8E2

 

It indicates that the Wait timer runs in parallel to other code that is executing in the while loop. So if my loop takes 0.7 seconds to do all calculations, and my time delay is set to 2 seconds, the total time for the loop to run should be 2 seconds, not 2.7. So data readings between each loop iteration should in theory be spaced by approximately 2 seconds, not 2.6 seconds.

 

This seems to be the case in the smaller/simpler VI I posted above. In that VI, the Nested For Loop takes 0.7 seconds to execute when I time it without the Wait. When I introduce the wait for 2 seconds, the x-y indicator shows an accurate 2 second increment between each loop iteration. I don't see the difference at a conceptual level between the 2 VIs I posted (in terms of how I am making use of the Wait function), yet they seem to be behaving quite differently.

 

0 Kudos
Message 3 of 23
(6,044 Views)

Sorry about the bum advice.  Not sure what I was thinking at the time, but you are correct.

 

I tried to open your snippet, but there are files missing that deal with reading your TC's and a few others.  So I can't run it to try and duplicate what is going on.  The quick way to control the update rate on the UI would be to treat the indicators just like the file save, only update them every so often with a timer.  It is better not to stop your main while loop for any longer than you have to.  Nobody likes an interface that is very sluggish to respond and it can do bad things to other parts of you code that have to wait that extended amount of time.  To speed everything up you could also put the file read into a different loop and just update the value in your main loop when a new value is available.

 

But that is no longer your main question.  It might have something to do with the reading of your TC's and pressure.  How are you reading them?

0 Kudos
Message 4 of 23
(6,029 Views)

Hi Brian,

 

Yup, sorry, don't think the snippet will work as there are some sub-VIs I wrote that are being called along with some dlls for the pressure sensor and the TC reader.

 

At the moment, the TC and Pressure reader result in about a 0.3-0.5 second of CPU time...the rest is most likely due to the use of property nodes in several places. From what I can tell, they can be quite a bit slower due to their synchronous nature and this results in my main while loop taking close to 0.9 seconds (I was wrong about the 0.7 seconds estimate in my previous post). 

 

With regards to your comment about a sluggish UI, I actually have a separate parallel loop that is operating with a delay of 200ms that polls the UI for interactions with a couple of the main buttons that I expect the user to interact with. This allows the user to open file dialogs, etc, while the graphs and data on the front panel UI are still updated. So I'm not as worried about sluggishness. I do agree that if this was my one and only loop, I'd want this to run as fast as possible and then have a less frequent update of the front panel.

 

To be honest, I think I'd get much better performance using a Producer/Consumer design pattern (just read about it a couple of days back), using event handlers, etc, but that is going to require a lot of effort on my part since I am new to LabVIEW and have limited hours at work that I can devote to this problem. At the end of the day, I have a working piece of software but what I just can't figure out is why the delay timer is behaving differently in my program as compared to how I'd expect it to behave.

 

To get back to your question about how I am reading the TCs and the Pressure:

 

- The TC reader comes with a dll that I invoke using the Call Library Function Node. This is a modification of supplied LabView code that came with the instrument. The pressure reader comes with a .NET dll which I also invoke by constructing a .NET object and calling its methods using the .NET palette in LabVIEW. At the moment they are setup to be probed asynchronously within the while loop to try and reduce the overall loop runtime. Apart from that, the rest of the stuff is pretty straightforward. I'm at a loss about the timing issue though. 

 

Thanks a lot for taking the time to look at this. I really appreciate it!

0 Kudos
Message 5 of 23
(6,013 Views)

Hmm...so after digging around the forum, I came across this post by Ben Rayner: http://forums.ni.com/t5/LabVIEW/Slow-property-node-subvi/m-p/1929379#M644485

 

Locals have a special backdorr method of getting at the value in a control that bypasses the UI thread.

 

That is why it ran fast in the top-level VI.

 

When using a property node, the code will stall when it gets to the property node read while it waits for the OS to do the thread swap to the UI thread to read the value and then it will drop out of the UI thread and finish that cycle of your loop.

 

I would go for a LV2 Global to as the easiest fix since it will use the UI thread

 


Do you think this could be related to some interplay between a property node read within my main loop and the fact that somehow the loop is being forced to wait for the UI thread and somehow that interplay results in my main loop always having to wait past the delay time to finish execution?

0 Kudos
Message 6 of 23
(6,009 Views)

Did you try using Wait Until Next ms Multiple.  Replace the wait(ms) with Wait until Next ms Multiple and try.

 

-Ajay

--
Ajay MV


0 Kudos
Message 7 of 23
(6,003 Views)

I did play around with it but that does not seem appropriate for what I wanted to achieve. The regular Wait Node should be the one that is applicable for what I am trying to do and seems to work as expected for the smaller example VI I posted above.

0 Kudos
Message 8 of 23
(6,000 Views)

The free wait should really hold up the loop for 2 secs. Are you measuring the time correctly? Place all of the loop content in a frame sequence and add a frame before and after with Get(ms) to get execution time. Apart from thread competition and express vi's i cant really think of anything. (maybe harsch on the express vi's, but they've been strange before).

 

Else you'll have to make a workaround, measure the time it took to perform the loop, then add (2000-looptime) as wait. 🙂

 

/Y

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

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 9 of 23
(5,991 Views)
Thanks Yamaeda. I did double and triple check my timing calculations but they seem to be correct and match my wrist watch when I measure the total execution time over multiple iterations. I guess I'll need to rethink my program if I really want to fix this, or hack a solution together along your lines where I measure each loop execution time and then subtract that from 2000ms, and place a timer with that delay in the second frame inside the loop.
0 Kudos
Message 10 of 23
(5,977 Views)