LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Subpanel indicators don't update if they are not visible

Solved!
Go to solution

Hi all,

 

I am experiencing some weird behavior in one of my applications and I was wondering if anyone here had any idea why.  Here is the problem:

 

I have a vi that gets loaded into a subpanel.  The indicators of that vi don't display the data I wired to them unless I am watching the indicators when they update.  In other words: If the vi is not loaded into the subpanel, the indicators are not visible and they do not update when new data is wired to them.  When I insert that vi into the subpanel, the indicators display the wrong values until the next time they are updated.

 

I have attached some simple code that demonstrates this behavior.  It is saved as LabVIEW 2015, but I originally wrote the code in 2022 Q3.

The attached code will start a vi using call by reference.  After 6 seconds the vi will be inserted into the subpanel, and you will see that all values are default until the next time they are updated.

 

Is this normal?  It feels like a bug.  I have tried a lot of things to resolve this, including all applicable solutions of this knowledge article:

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z000000kISeSAM&l=en-US

I have also tried settings the indicators, "Synchronous Display" property, and I have tried to force updates using the, "Defer panel updates" property.  The only thing that has worked is writing values to the indicators constantly in order to get them to update after I start looking at them.

0 Kudos
Message 1 of 9
(607 Views)

Not sure what's the reason behind it, but it works if you use Run VI Method instead.

 

ZYOng_1-1765935746727.png

 

-------------------------------------------------------
Applications Engineer | TME Systems
https://tmesystems.net/
-------------------------------------------------------
https://github.com/ZhiYang-Ong
0 Kudos
Message 2 of 9
(574 Views)

Hi,

 

I don't know what is your purpose with this program, but if you make a few changes, it will work fine.

 

First, in your program, you won't see the values the array takes because it only displays them when the VI execution ends, so you would never see them in your program.
Second, the “i” indicator starts at 4 because in your main VI you wait 6.1 seconds before displaying the VI, and the secondary VI runs 4 loops before you diplay it during that 6.1 waiting time.

 

Here are some changes you can make.

 

Best regards.

using LV 2017 on Win11
0 Kudos
Message 3 of 9
(543 Views)

I've used sub-Panels in several LabVIEW Projects.  In all cases, the VI that was loaded into the sub-Panel was only called while in the sub-Panel.  You are calling it before it is placed in the sub-Panel -- I'm not sure why that messes up communication, but I also don't know why you need to do that.  The contents of my sub-Panels are often State Machines being run by the "calling program", so after doing the Insert VI to embed the (not-yet-running) routine you want in the sub-Panel, I send the "Initialize" command to the VI in the sub-Panel (which would be your "6-second" routine) and follow up with whatever else I need to send. 

 

Why can't the sub-Panel routine do the 6-seconds by itself?  The idea is to keep all of the code running in the sub-Panel running only in the sub-Panel.  At least, this technique has worked well for me ...

 

Bob Schor

0 Kudos
Message 4 of 9
(496 Views)
Solution
Accepted by topic author yourfavoriteproperty

My guess, it basically has to do with the fact that the front panel isn't initially loaded into memory. The compiled code is trying to be smart about making copies of data. If the front panel doesn't need to be loaded, each control/indicator only needs one copy of data. If the front panel does need to be loaded, each control/indicator needs two copies, one for the the actual data and one for the displayed FP object. Since you aren't loading the FP into memory until later, that second copy is only getting made when you do, and the initial value of that second copy is the default value of each control/indicator.

 

As for why Run VI works, I'm not sure. But, in your called VI, doing anything that loads the front panel into memory without actually opening it will work to make the indicators show with the expected values initially. For example:

Spoiler
FireFistRedhawk_0-1765987050822.png

 

Redhawk
Test Engineer at Moog Inc.

Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.

Message 5 of 9
(476 Views)

I'd say it's expected behaviour. Why update a front panel that isn't shown? That's just unnecessary work.

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

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 6 of 9
(385 Views)

I believe that the "Run VI" node works because any VI that runs needs a source for data from the inputs on its connection pane.  A subVI gets them from the block diagram that calls it, as well as VIs that are called via the "Call by reference" node.  The "Run VI" call has no such block diagram source, so it likely loads the diagram to get the values from that.  Just a guess though.

 

At any rate, this behavior is not really a "bug", just an unintended consequence of optimization.

 

Perhaps you could try a workaround instead.  Insert the VI in a subpanel immediately instead of waiting 6 seconds, but use a different method to make the sub-panel not visible to the user until you're ready.  Example options:

  • Use a tab control with two tabs.  Hide the tab names, and edit the colors to make it all completely transparent so you can't tell it's a tab control visually.  Have the sub-panel on one tab and nothing on the other.  When you would normally insert the sub-panel after 6 seconds, programmatically change tabs instead.
  • Have a non-visible sub-panel somewhere else in your code.  Insert it there immediately, then remove it from there and insert it into the other panel after the 6 second delay.
  • Insert your sub-panel immediately, but have it set up so the front panel is scrolled way over to the side.  When the 6 seconds are up, programmatically scroll back to the area with the controls visible on it.

There's probably even more options than those 3...

0 Kudos
Message 7 of 9
(327 Views)

I'd guess that if you want to force it to update control even though it's not visible you can use Value property nodes in the hidden VI, this'd be one of the few times when it's ok to use those. 🙂

 

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

Qestit Systems
Certified-LabVIEW-Developer
Message 8 of 9
(291 Views)

Wow, thanks for all the insights.  I didn't think this would get so much response.

 

Regarding the use case you all asked about, I made my own dynamic-tab-control using a list-box as the tabs, and a sub panel that inserts the appropriate 'Actor core.vi' when a tab is selected as the contents of the tab.

 

Since I am using the Actor framework, and more specifically I am loading an 'Actor core.vi' override into the sub panel as the UI, I cannot change how the VI is run because that is dictated by the framework.  I could separate the actor core from the UI, but that just seems like more work, and I would be worried I would just run into the same problem again regardless.

 

As for why the indicators get updated while they are not visible to the user, that is another quirk of the Actor framework.  As I understand it, the framework promotes, "pushing" data from the source instead of, "pulling" it from the destination.  That means that UI elements get updated when the data is generated, and not necessarily when the user is looking at it.  Each tab displays different interesting things about a process, and the user dictates what tab is currently visible.  Each tab is constantly updating as data is being generated, and when the user switches tabs, I want the indicators to display the data that I wired to them.  The array in my example is representative of me trying to set the headers in a table when the actor first initializes.  It is the kind of thing that only happens once at program start, and not when the user is looking at it.

 

I accepted FireFist-Redhawk's solution because it made the most sense to me and it also worked in my example code, but I also tested Yamaeda's solution of setting the indicator value via a property node.  I initially didn't like the idea of property nodes because I thought I would have to make a property node for each indicator and that would be tedious; however, when I tested the idea on my example, I tried it on only the 'Array' indicator, and noticed that the 'i' indicator also started updating normally, even though I hadn't made a property node for it.  Very interesting...

 

I will need to do some more testing to make sure this solution works on my actual code and not just my example, but this all looks very promising.  Cheers and happy new years everybody.

0 Kudos
Message 9 of 9
(250 Views)