LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing data between three levels of subVi's

In a project I'm wokring on i'm passing data between the main VI and subVi's using conrol references.   I ran into a little problem today when I modified a little delay timer that I use in many of my subVis into it's own subVi.  Now I want to pass the information from the new timer subVi all the way back to the main VI.  I am using the timer subVi in about a dozen other subVI, but in each case the timer subVI is a third level VI; main VI, subVi, timer subVI.  

 

When I tried to do it in the same was as I normally do when I use control references I was confused.  Normally I create a reference on the main VI block diagram and drag and drop it on the front panel of the subVi and create the property node for the Refnum on the subVi.  But going to a third level subVI am I dropping the reference from the main VI onto the third level subVI, or am i'm is dragging and dropping the Refnum from the second level VI to the third level VI?  What has me more confused is I would like to use this same third level subVi in many second level subVi's and along the way passing the third level data to all higher level VI's.  What is the best way to pass data between three levels of VI's?

 

Thank you for the help.

Danny
0 Kudos
Message 1 of 9
(3,534 Views)

I'm not sure why you are woking so hard (by passing References to controls).  Does your "little VI" retain information, or does it simply take its input and produce some output?  If the latter, why not simply pass the data in to a control, and out to an indicator?

 

There are some instances when you might need to pass a reference, particularly if the item-in-question is large or complex.  Suppose you have a Graph on the top level and want to update it in a sub-VI.  You can create a reference to the Graph in Main and pass that to SubVI, which can use property nodes to get and set values.  If you want to make a SubSubVI to do some of the work, simply pass the Reference that you have in SubVI as the "Reference argument" to SubSubVI -- it will directly reference the Graph in Main.

 

BS

0 Kudos
Message 2 of 9
(3,526 Views)

If all you are doing is updating values on the front panel. stop using references.  Use User Events to send the updated values to your main VI's Event Structure.  Your code will run A LOT faster and will be more modular.

 

In general, it is a sign of bad code when you pass references around willy nilly just to update a top level VI.  That tells me you did not modularize your code enough.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 3 of 9
(3,510 Views)

Bob,  Thank you for your suggestion.  I guess i'm working so hard because I don't know a better way. It would be great to pass the data out to an indicator and a contorl.  I made a simple subVi and a main VI and when I try to pass it out through the front panel it doesn't update until the subVi finishes.  What is right way to update the main from the sub without using references?

 

Thanks again for the education.  It's very helpful.

 

 

Danny
Download All
0 Kudos
Message 4 of 9
(3,475 Views)

@dannyjhu wrote:

What is right way to update the main from the sub without using references?


USER EVENTS!!!


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 5 of 9
(3,464 Views)

When I tell students about LabVIEW, one of the things that I emphasize is that LabVIEW, unlike programming languages with which they may be familiar, places a great deal of emphasis on the concept of Time, not only by having Time functions, but by the nature of Data Flow and how it influences the Order of Execution.

 

Consider your Test Main.  You have not wired the Error Line through your Delay Timer sub-VI (why not?), but because the sub-VI is contained within the inner Case Statement, it will execute as though it is connected, that is, it will execute serially with the execution of your Main.  For each loop through the Main, you will do exactly one call and "loop" through the sub-VI.  Your Main code cannot progress until the inner loop finishes.

 

What you (probably) really want to do is to have these two loops run in parallel, both at the same time, independently, with neither calling the other.  One way understand how to do this is to think about what it is you want to do.

 

Your Main has two Controls for itself (Go and Stop), a Control to pass input data to your Timer, a Control to "interrupt" and stop your Timer, and an Indicator to receive information from your Timer.  The program has several goals, with different Time imperitives.  When you push Go or Stop, you want an "instant response", but you don't particularly want to waste processing time if the controls are not pressed.  When you do push Go, you want the Timer to start running and to pass back to you its output, which you can display as it is changing.  Finally, you want to be able to "interrupt" the Timer to get it to stop.

 

LabVIEW has something called the Event Structure that is ideal for handling Front Panel Events, such as the changing of Controls or Indicators.  It can also be used (a more Advanced Topic) to create more flexible User Events (see Crossrulz's Replies).

 

Think, again, about Time, and what you want to happen at each critical Time point.  I see at least four -- Push Go (start the Timer), push End (stop just the Timer), push Stop (stop just the Main -- in your example, this won't happen unless the Timer is not running, but you might want to re-think this), the Timer stops (because it times out or gets an End "command"), and Timer updates its clock (which we want to display as it happens).

 

Using an Event Structure, you can (a) eliminate the 10 millisecond timer in your Main (since it will be running on an "As Demanded" basis) and (b) handle the Events that pertain to the Main routine.  You can also use the Event Structure in your Timer, using the TimeOut Event to run your clock.  You will need to learn about the Value (signalling) property of Controls, which allows you to trigger an Event when you change the value of a Control (hmm -- I'm wondering how easy it will be for Main to "push the button" of the Timer sub-VI and have it register as an Event -- I think I see a logical way to do this, but it "violates one of the Rules for Event Structures").

 

This is clearly something for you to explore and see if/how it helps you to solve your problem.  Along the way, you'll learn about some significant features of LabVIEW that will help you incorporate Time into your routines.

 

I'll leave you with a final thought -- re-read the third paragraph, and see if this might apply to your problem (this involves the Light Bulb that went off in my head when I was writing about "violating the Rules").

 

Bob Schor

Message 6 of 9
(3,431 Views)

@dannyjhu wrote:

What is right way to update the main from the sub without using references?

 


Just after I posted my lengthy reply, I realized that my ending comments brought to mind something I wrote in a Blue Book during a final exam (in Physics?) in college -- "Answer Analysis reveals that the Question is Wrong".

Message 7 of 9
(3,426 Views)

So with that last Reply, I figured I might as well make sure I knew what I was talking about.  Well, I didn't quite -- I did show that "Answer Analysis Reveals that the Question is Wrong", but my solution did not "violate the Rules of Event Structures".  It is really quite simple, uses the Event Structure, and exploits its properties.

 

One thing that you'll find when you use Boolean Controls with Event Structures -- you almost always want to make their Mechanical Action "Latch When Released" (the default setting for the Stop Button), especially if you put the Control inside the Event case that fires when its value changes.  What this does is to turn off the Control (thus resetting it, ready for another Push) when you respond to its being pushed.

 

Try to do this yourself, learning about Event Structures.  If you are still stuck (or someone doesn't do this for you, which will rob you of the fun of figuring it out for yourself, a process that also make the knowledge "stick" with you), I'll post my solution in a few days.

 

Bob Schor

0 Kudos
Message 8 of 9
(3,415 Views)

Bob,

 

Thank you for all your information.  I was thinking more about using an event structure,  and for sure there are places in my main VI code that it makes sense to move in that direction.  The problem that I posted though I don't think an event structure is the best choice.  My project is controling an instrument in our lab.  My main VI, which would benifit from an event structure, allows the operator to choose one of many processes.  Once the process is selected the main front panel updates with progress bars and other feedback.  Each process has it's own subVI that is called from the main, and runs to its completion without further user actions.  In the case of a problem the user needs the ability to stop or halt the subVI process.    

 

The instrument i'm controlling has little in the way of feedback or hanshaking.  Many of the process steps are run in a sequential fashion and require a delay timer to allow for a step to complete before starting the next. It would be great if I could pole the instrument and ask if it was ready for the next step but the instrument doesn't have the ability to do so.  

 

To make my code more modular I tried to break down many of the steps into subVIs.  One of these subVi was a version of the timer I posted.  I have the delay timer subVI as part of a state machine (second level)subVI.  Each state of the state machine is used for a specific sequential steps using subVI's, i.e. open valves, send RS-232 command, turn on fan, delay for 1 minute then next state for next series of tasks.  This state machine subVI's would probably work better if I migrated to a producer-consumer structure but I don't have much experience with it.  Long term I can move in that direction but short term I need to keep the instrument running.  Everything currently works with the exception of being able to abort the timer and get the countdown to display on the front panel of the main VI.  Your quote of "Answer Analysis reveals that the Question is Wrong" probably is probably correct.  What I really need is probably a better delay timer.

 

Thanks again for your advice.

 

 

 

Danny
0 Kudos
Message 9 of 9
(3,390 Views)