LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Timed loop in main loop

Hi,

I have a main loop that acts as a TCP server that collects data from 5 stations. I'm trying to add a timed loop within the main loop that will count the number of seconds a station is in a particular state. Ive tried using a timed loop structure and a delayed while loop but both starve my main loop and don't allow it to execute. What I need is for it to timeout and let the rest of the VI execute but after reading through the help files and searching online I cannot figure out how to make it do that. The timed loop structure has a timeout but apparently the timeout is how long before it executes its self... not the rest of the VI. If anyone knows how I can accomplish this and fix my VI I would greatly appreciate the help. 

 

    Thank You,

meanmon13

 

ps: I have attached an image of my vi using the timed while and the timed loop structure 

pps: I'm using LabView 8.5.1

 

Download All
0 Kudos
Message 1 of 7
(4,007 Views)

meanmon13,

 

It is somewhat unclear from the pictures you posted what exactly this is supposed to do.  In both the outer while loop and the inner while loop, neither of the conditional stops seems to be doing anything.  In the outer loop, the VI is set to run forever, while in the inner untimed while is also and the inner timed is not even tied to anything.  If you want the inner loop to time out after some period of no response, you need something like this:

 

19513i19147D7541F96FC0

 

But, as I pointed out, there are other issues with the code you posted also.  Have you considered using the STM library for your communication?  In some of the examples that they provide, you will find architectures that are more robust for TCP communication than what you have up in the pics.  This API developed by NI engineers is quite powerful.

 

Cheers, Matt

0 Kudos
Message 2 of 7
(3,993 Views)

Thank you for your quick reply mtat76,

 

What I want the inner loop to do is to "wake up" every second and iterate through each station and check its state. If the state is "charging" then it increments a counter (number of seconds the station has been in the "charging" state). I've written a sub-vi that checks the state and increments the counter but I can't seem to get the inner loop to only run every second and call the sub-vi.  I want the inner loop to "sleep" so that the out loop can run. Oh, and I never want the outer loop to stop... its a server and should run "forever" or until the user closes the vi. 

 

I'm not sure what it is the loop in your picture does. I think it would run until a timeout occurs which is not what i want... i want it to "not" run until a "timeout" (1 second) occurs and then only run what is in it once and then wait again.

 

~meanmon13

 

PS: I didn't know about the STM library and will check it out. Thank you for the tip

0 Kudos
Message 3 of 7
(3,981 Views)

meanmon13,

 

A couple of things: first, no loop will run "forever".  Regardless of the purpose of the loop, there is ultimately some event which should trigger the loop to stop.  The way that you have the outer loop currently setup, the user is forced to hit the "Abort" button in the VI.  This is bad - things will not shut down properly, something might not be released and ultimately you may get behavior that you don't expect.  If the user is to be in charge, at the very least you need to provide some functionality that will allow the VI to shutdown gracefully.  As it stands, you never actually close the connection simply because when the abort button is hit, all execution will stop immediately.  Since you have decided to use events, I would suggest using the "Panel Close?" filter event for the VI (you can decide whether the VI is actually closed or remains open but not running). 

 

Second, you will never put the inner loop to "sleep" in the sense that you wish.  What you need to do is to poll the stations and if some elapsed period of time is exceeded then you stop the inner loop proceed with the execution of the outer loop and then start over in the next iteration.  The inner loop would then be executed with each outer loop execution for some period of time not to exceed some maximum elapsed time during which the stations states are polled.  A more elegant solution might be to run the two loops in parallel, but without actually handling your code I don't know how to suggest going about this.

 

One final thing - avoid the use of local variables and property nodes when possible (and in your code, this is entirely possible); rather use shift registers to contain the data that you need.  Local variables and property nodes have extra overhead associated with memory, obscure the data flow and can be executed in an unexpected order (especially in your case since the inner while loop execution order is not tied to any wires).

 

Just some thoughts.

 

Cheers, Matt

0 Kudos
Message 4 of 7
(3,971 Views)

I would like to use parallel loops but when I've used them in earlier revisions of this VI only 1 of the loops ran and the other did not. I do not know how to make both of them run at the same time. I think that would be the best solution but I lack the knowledge of how to get a VI to run two threads. I've thought about trying to use the inner loop to trigger a real-time interrupt that could be picked up by the event structure but I don't know how to make it do that. 😕

 

As for your suggested polling method I not sure how I'd get the result I want out of it. If I were to "poll" for 1 millisecond and then stop the inner loop. How would I know how much time had passed sense the last time I incremented the charge counter? 

 

~meanmon13

 

P.S.: As for not using the local variables I am only reading values so mutual exclusion is not an issue and this VI is the only running application on the computer so the memory overhead is fine. 

0 Kudos
Message 5 of 7
(3,963 Views)

meanmon13,

 

I think I am at a loss at this point.  You can not do what you are asking in the manner in which currently have your VI constructed.  The reason that the parallel loops did not operate as you wanted was because you had some dependencies between the loops (i.e. one loop had to complete execution before the other could proceed).  Below shows an example of two sets of loops doing potentially the same thing with different results:

 

19541i2FB96C406EBC3DF1

 

I don't know the inner workings of you application so I can not answer your question regarding polling.  Consider posting some VIs of how you might do something (maybe a simplified version of the application that you have posted) and I might be able to provide some more specific suggestions.  Also, you might want to review some of the more fundamental concepts associated with LV - how memory is used, the concept of data flow, as well as some basic architectures (producer-consumer, state machine, etc etc).  There is a lot of material on this site both in the discussions and in the knowledge base that will help you grasp these concepts.  And on that note, concerning local variables - they don't just affect memory; it is good programming practice to avoid using them where possible as they tend to obscure the programmatic flow thus creating a VI that is more difficult to maintain over the long term.

 

Cheers, Matt

0 Kudos
Message 6 of 7
(3,948 Views)

I'm looking at your Timed Loop 2 JPG.  You have all of your code in one main loop.  Everything has to execute and finish before the main loop can go to the next iteration.  If you have a Timeout event in the event structure, either the timeout period must be reached, or some other event must be triggered before that block will be finished executing.  The timed loop must finish executing.  The No Error case structure must finish executing.  Only after all three have completed can the outer loop go to the next iteration.  But your Timed Loop has nothing connected to the stop sign, so it will run forever, and the main loop will never go to the next iteration.

 

In your other JPG, you have a while loop in the lower left corner set to run forever.  Again, the outer loop will never go to the next iteration because that While Loop never finishes.  All code inside the main loop must end before the next iteration can start.

 

If you want a particular section to run once every second, put that code in a Timed Loop set to a period of 1000mS.  Put the Timed Loop outside of your main loop so that it can run continuously every second, independent of your main loop.  If you need to pass data to some other part of your code, use a queue. 

 

Don't set the loops to run forever.  The only way to stop it is to use the abort button.  Doesn't matter if it is a server and supposed to run continuously, day and night.  At one point or another, it has to be stopped for maintenance or whatever.  Use a Stop button and a local variable of the stop button to stop the main loop and the Timed Loop.  This will ensure that the code finishes properly and is not stopped in the middle of a process with references still open.  Since the stop button has a local, you will have to set the action to Switch when Released instead of a Latch type.  You will also have to set the Stop button back to False at the end of the code so that it starts off as False the next time the code is started. 

 

Be sure to put a small delay, Wait(ms), in your main loop so that you don't chew up 100% CPU time.  even a value of 0 will work.  Without a delay, the loop will hog the CPU, which may cause performance problems elsewhere.

 

- tbob

Inventor of the WORM Global
0 Kudos
Message 7 of 7
(3,934 Views)