02-11-2014 11:49 AM
Hi,
I am building a control system where I get data from hardware and other software at irregular intervals. I would like to show the user how old the data is that is currently shown in an indicator. My idea was to use the background color of an indicator to show the age, white meaning the value is very recent, and an increasing red color would mean that the value hasn't been updated in a while. My idea was to create a custom indicator that would monitor the age of its own value and adjust its own background color. So the main program would set the value and forget about the indicator.
I have made an example VI (attached) of the kind of behaviour I'd like to see.
Do you think this is at all possible?
Best regards,
Victor
02-11-2014 11:59 AM
Hello Victor,
My recommendation is to take a look at XControls:
Tutorial: Creating New Front Panel Objects with LabVIEW XControls
http://www.ni.com/white-paper/3198/en/
I like to think of XControls as a subVI for your front panel- they allow you to define the behavior of a control from the ground up. They do require more work up front to get them doing what you want and impose some limitations (most "normal" properties/methods won't be directly accessable without setting them up for the XControl), but If you're planning on using more than a few of these color-coded indicators you'll probably want to consider them as they'll make reuse and scaling your application much, much easier.
Regards,
02-12-2014 05:04 AM
It certainly is possible. As mentioned, one option is XControls, but you should be aware that XControls aren't built to run things in parallel. You can't simply add a timeout to the event structure of a facade VI and use that. Instead, you will need to use some kind of daemon to handle it for you. You could launch it from the XControl and give it the reference of the internal control you want to modify and then send an update to it when there's a value change event. The actor framework is useful for creating such daemons, although you can also do it using other means. You could also use a single daemon which will keep an array of reference and simply manage all the XControls.
Another option is to generalize the whole thing. Instead of writing to the indicators directly, mark the indicators somehow (the label is practical) and use a more generic engine to update their values (basically iterate over all the controls and get their label, then use that info to know how to update them). This can be very useful if you have a lot of indicators and a tag engine. If you do that, then you simply add the color code into that update engine.
02-12-2014 05:23 AM
Why not using time which will be updated when indicator updated. Rename time indicator as last updated on.
02-12-2014 07:15 AM
@Ranjeet_Singh wrote:
Why not using time which will be updated when indicator updated. Rename time indicator as last updated on.
My first thought. Why go through all the effort creating an xcontrol? Tell the user exactly how old the data point is. You can take a time measure when you get the data then subtract that value from the current time.
02-12-2014 07:46 AM
Hi all,
Thanks for your suggestions.
Ideally, I would incorporate this logic in the indicator [of a custom version of an indicator] itself, but so far I haven't heard anything to make me believe that that is possible.
02-12-2014 08:10 AM
@VictorClaessen wrote:
Ideally, I would incorporate this logic in the indicator [of a custom version of an indicator] itself, but so far I haven't heard anything to make me believe that that is possible.
What's wrong with the way you're doing it now? Looks pretty straightforward to me. Just make a subVI out of it and then you can even use it in a for loop to modify all your similar indicators at once.
Cameron
02-12-2014 08:23 AM
Hi Cameron, thanks for thinking along.
I'm not really sure what you mean with "the way you're doing it now". If I make a subVI out of this indicator.vi as it is [in the first post], and place that in parent.vi then
But perhaps I'm not completely following you?
02-12-2014 08:51 AM
Not your exact VI as you posted, but using that method. The snippet below is called an Action Engine, it runs through the while loop exactly once. (Don't ask me about that "DigNum Refnum", the property node was supposed to be hooked up to the indicator.) Just wire the appropriate controls and indicators onto your subVI's connector pane.
You could also bundle your indicator and the last update time indicator as a cluster for output, and unbundle them as your first step in the subVI, then you wouldn't have to remember to pass two things to and from the subVI every time.
Cameron
02-12-2014 09:15 AM
Sounds good, but you've lost me. So what you are showing now is the subVI. (The bundling remark I get.)
The best I've come up with so far is that you want me to to call this subVI, from the main loop of the parentVI, for all the indicators I have on the front panel of the parent? [by passing them as a reference?] But then the parentVI will have to check wether the value has been updated? Why not do that in the subVI?
BTW Would it be possible to attach your VI to this post? I'm using 2011 so I can't import your snippet as is.