LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Identify if the subvi is called for the first time by a second top-level VI

Solved!
Go to solution

Like this.

 

Top level VI A

 

Middle level VI B

 

Lower level VI C

 

See.  The top level VI will determine the first call?  and report it down to the lower level subVI's.  Actually very simple.

 

If this isn't what you want, then you definitely need to explain it better.

Download All
0 Kudos
Message 11 of 21
(848 Views)

Here is an example where I wanted to see how that can be implemented. Thank you for being patient with me.

 

-Run the A_top level VI

-Press the measurement button control

-The code goes to B

- I can call C D E at any time (at any iteration of the while loop)

- Here I populated C that counts every time it called first after B starts

- Once you press exit in B the VI is again directed to A

- The next time we move from A to B and in B if C is called, i wanted the frist call count to be updated by 1

0 Kudos
Message 12 of 21
(833 Views)
  • You seem to have renamed the subVIs so the toplevel can no longer find them. Can you attach a working demo, preferably all in one zip file?
  • Please don't maximize the front panels and diagrams to the screen. That's very annoying, especially when debugging multiple VIs.
  • None of your "init to defaults" (and sequence structures) are needed if all booleans were latch action (and they should be!).
  • All your while loops are greedy when doing nothing but spin as fast as the computer allows.
  • Did you understand Ravens suggestion?
0 Kudos
Message 13 of 21
(818 Views)

@Rex_saint wrote:

Here is an example where I wanted to see how that can be implemented. Thank you for being patient with me.

 

-Run the A_top level VI

-Press the measurement button control

-The code goes to B

- I can call C D E at any time (at any iteration of the while loop)

- Here I populated C that counts every time it called first after B starts

- Once you press exit in B the VI is again directed to A

- The next time we move from A to B and in B if C is called, i wanted the frist call count to be updated by 1


I'm sorry to say my patience is wearing thin because what you posted looks like you didn't do at all what I said.

Why do you still insist on first call primitive in the C level VI?

Why didn't you set up the connector panels with a control that let you pass a boolean from the top down to the lower subVI's.

 

Even this mention of "counting" how many times a subVI has been called is a new requirement you haven't mentioned before now.

 

I'm loathe to recommend globals, but if you are trying to keep track how many times a particular subVI has been called, whether it has been called before, perhaps you should create an action engine/functional global variable that subVI"s can report into when they've been called, and that will allow any VI from anywhere/anytime to check on the status.

 

It is a pretty simple principle and I can't figure out why you don't seem to grasp it.

 

Let the higher level VI's tell the subVI's whether this is their first run or not.

0 Kudos
Message 14 of 21
(804 Views)

@altenbach wrote:
  • You seem to have renamed the subVIs so the toplevel can no longer find them. Can you attach a working demo, preferably all in one zip file?
  • Please don't maximize the front panels and diagrams to the screen. That's very annoying, especially when debugging multiple VIs.
  • None of your "init to defaults" (and sequence structures) are needed if all booleans were latch action (and they should be!).
  • All your while loops are greedy when doing nothing but spin as fast as the computer allows.
  • Did you understand Ravens suggestion?

My bad. I renamed them back and removed the maximized option for the front panels. And this is not my original code (which has a lot of subvis), this is one just a skeleton demonstration. I understand what Ravens has suggested.

 

Ravens asked me to connect a first call input terminal to the lower level subvi and pass when that first call happens from the VI that is calling it.

Therefore I posted a demo code narrating what I wanted, seeking for an answer on how to implement Ravens suggestion on this model of code.

 

In this code attached now, I have kept an input terminal to subvi C, through which i pass a true whenever B calls C for the first time as suggested by Ravens.

 

But I am really confused on how does B notifies C that it is C's first call.

 

It would be really helpful if the code I attached is modified to do that. And the' first call count' control in B subvi is just to verify if the code is working fine (by which i meant if the count updates every time this chain of events happen "A calls B---> B calls C first time---> First call count updates"). 

0 Kudos
Message 15 of 21
(782 Views)

@RavensFan wrote:

@Rex_saint wrote:

Here is an example where I wanted to see how that can be implemented. Thank you for being patient with me.

 

-Run the A_top level VI

-Press the measurement button control

-The code goes to B

- I can call C D E at any time (at any iteration of the while loop)

- Here I populated C that counts every time it called first after B starts

- Once you press exit in B the VI is again directed to A

- The next time we move from A to B and in B if C is called, i wanted the frist call count to be updated by 1


I'm sorry to say my patience is wearing thin because what you posted looks like you didn't do at all what I said.

Why do you still insist on first call primitive in the C level VI?

Why didn't you set up the connector panels with a control that let you pass a boolean from the top down to the lower subVI's.

 

Even this mention of "counting" how many times a subVI has been called is a new requirement you haven't mentioned before now.

 

I'm loathe to recommend globals, but if you are trying to keep track how many times a particular subVI has been called, whether it has been called before, perhaps you should create an action engine/functional global variable that subVI"s can report into when they've been called, and that will allow any VI from anywhere/anytime to check on the status.

 

It is a pretty simple principle and I can't figure out why you don't seem to grasp it.

 

Let the higher level VI's tell the subVI's whether this is their first run or not.


Sorry for that, I was not insisting on keeping the first call primitive inside the C. I kept it their to ask for the functional modification based on your suggestion. In the new zip file i uploaded I have in part implemented what you asked for and replied to what my confusion was in regard to your suggestion.

0 Kudos
Message 16 of 21
(778 Views)
Solution
Accepted by Rex_saint

Sorry to drag us back a page, but did you look at what I posted (probably the last post on the first page, based on the default 10 posts per page).

I'm not sure given the posts that followed if it does what you want or not, but if not perhaps you can clarify.

 

In the code you uploaded now, C does indeed have an input to indicate the special behaviour (first time call in B) and presumably using that (via e.g. the case structures in C) is not a problem. Doing the same for D and E (or other hypothetical subVIs) is also not a problem.

 

As to how B notifies C, this is via the block diagram of B.

In your example, it appears that B has an interactive front panel, and that its execution flow is not known at edit time - is this correct?

 

If so, I'd suggest doing something like the following (in B):

set.png

 

Obviously this doesn't handle other cases (but you could move the Format to String and Set Variant Attribute outside of the Case Structure if you need to handle all cases).

Also, it's not obvious what your full application will do, but this should be a usable technique (with a Variant on an shift register in B, using attributes with a dummy value to check if the value is overwritten).

 

Edit: 2019 snippet to demonstrate perhaps more clearly:

Example_VI.png


GCentral
Message 17 of 21
(772 Views)

I think this is exactly what I needed. I will implement this and check. 

I will get back if I have a query, else will notify this as accepted solution. 

 

Thank you all for being patient and helping me over this. I know I should have been a pain while communicating what I needed. 

0 Kudos
Message 18 of 21
(761 Views)

Hi, 

 

Thanks for the idea that worked great and triggered one more idea, which I have implemented. This time instead of passing the 'first call?' control value, I am passing its reference. I have set the default value of that control as true. Now when B is calling C for the first time, I am setting the value of 'first call?' to be false inside C. And when B freshly loads I am re-initializing the value of first call? to default (=true)  via invoke node.

 

Block diagram of B

B_block diagram.JPG

 Block diagram of C

C block diagram.JPG

 

0 Kudos
Message 19 of 21
(747 Views)

Hi Rex,

 

I'm glad my solution worked for you.

 

With regards to the approach using a reference to a boolean, I'll only point out that you'd need one boolean for each of C, D, E, ... and that this is harder to use separately - if you want to run/test C (or D, or E) without running B, you can't easily do it if you require a reference input (because you can't have a meaningful boolean control reference default). It's much easier to test if you simply pass the value via control.

 

LabVIEW is a dataflow language - as much as possible we tend to try and avoid using non-dataflow methods like references (although sometimes they are useful/critical). As you've found, a reference can be used to update a value that isn't in the same VI, but if you can use a simpler "by-value" method instead that will probably lead to less confusion and fewer possible bugs in the future.

 

That being said, it's good that you've found alternative solutions too. Just be aware that relying on default values can make programming more tricky, and having required reference inputs makes (sub)VIs harder to use alone (or test).


GCentral
0 Kudos
Message 20 of 21
(730 Views)