From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Property Node - Value (signaling) behaviour

Hello everyone,

 

I want to implement a function, which sets values of controls on the FP of a referenced VI:

So I have a MAIN.VI with a event structure. As part of one of its cases there is the SUBVI which receives the MAIN.VI's reference and attempts to set values of its controls using the property node "Value (signaling)". The behaviour looks like this:

 

1. Value signaling property node is run - the wired value is set to CONTROL X imediately and an event is queued at the event structure (in MAIN.VI)

2. CONTROL Y is set in the same way as CONTROL X in step 1

3. Once the SUBVI finishes, all the controls have the new values set and the MAIN.VI's Event structure starts handling the queued events:

4. Handling the first case (for CONTROL X) changes value of CONTROL Y as part of its normal functionality

5. Handling the second case (for CONTROL Y) performs its code but doesn't set the controls value so CONTROL Y keeps the value set by event case of CONTROL X - even though I initially performed the property writes in order CONTROL X, then CONTROL Y

 

 

what I would expect is that writing the value of a control would happen at the beginning of its corresponding Event struct case so that i can assume that before writing the value to CONTROL Y all actions connected to value change of CONTROL X have already happened. Otherwise, the current behaviour introduces some data "inconsistency": when the event struct case for CONTROL Y launches its event data node's "NewVal" value doesn't correspond to what is actually written in the control i.e. its actual value.

 

Does anybody have ideas how to workaround this behaviour? Thanks

0 Kudos
Message 1 of 7
(4,103 Views)

I don't quite follow your example, but the fact that it doesn't work properly and is so complex to explain suggests that "you shouldn't do it that way".  If the purpose of the sub-VI is to programmatically set a Front Panel Control and do it through the Control's Value-signalling property, why not (a) not pass in a Front Panel Reference, (b) do pass in (if necessary) the Front Panel Control, and (c) pass out the desired new Front Panel Control.  In the Main program's calling sequence, you (a) call the sub-VI, then (b) in the Main, wire the new value to a Value-signalling Property Node.

 

If it is more complicated then that, rethink what you are trying to do.

 

Bob Schor

0 Kudos
Message 2 of 7
(4,088 Views)

The problem remains the same - anytime and anywhere i would perform a sequence of Value signaling writings the values will be set first for all the controls (from first to the last) and only then the controls' associated events are performed (again from first to the last one).

What i want (and would believe more "natural") is setting value of the first control, then having its event case run, then setting value of the second control and having its event case run etc.. 

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

@ravyh wrote:

What i want (and would believe more "natural") is setting value of the first control, then having its event case run, then setting value of the second control and having its event case run etc.. 


What you describe is "more natural" is in violation of the central LabVIEW Paradigm of "Data-Flow" programming.  In particular, the Event Loop is running in parallel with the code that is "setting" Events.  If you want to Set an Event, wait for it to happen, then set another Event, wait, Set, Wait, you need to "serialize" these parallel processes (which kind of defeats the purpose).  If this is what you really want, you can program in such a sequence, but just don't use Event (Value-signalling) events, do it all directly in your (serial) code.

 

Bob Schor

0 Kudos
Message 4 of 7
(4,064 Views)

If you want to perform an event based on the data that caused the event, then just use the NewVal on the left terminal inside of the event case.  But the value in the terminal (or local variable or property node) will be whatever was last written to it (via a terminal, local variable, or property node).


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 5 of 7
(4,040 Views)

Exactly. Event itselves always keeps corresponding old and new values of the control value as event data no matter at what time in the future event handling code executes. There is always huge risk of race condition if there are miltiple writers to the same control becouse there are two buffer for each control behind the scene (the first which is called "Execution Buffer" - keeps actual value for the code execution and the second which is called "Operation Buffer" - keeps actual value for the UI element) and one Transfer Buffer to protect data transfers between the execution and operation buffers.

 

Operation buffer changes executes exclusively in the UI thread (i.e. serialized with all other operations which runs in UI thread). As I said before - control event also maintains it's private data snapshot so in theory it could happen that different value (then it's displayed on the UI) is passed by the control output over the wire to the running code while different value is observed in the control event for the same control at certain conditions. That's why it is not recommended to mix together all possible scenarios for control value changes to prevent from violation of the determinism.

Run attached examle which reproduces scenario you've described before but is always deterministic no matter what control value is actually displayed by the control on the UI.

Regards,
Ondřej K.

CLA, CTA, CLED
Message 6 of 7
(3,988 Views)

@okubik wrote:

If you want to perform an event based on the data that caused the event, then just use the NewVal on the left terminal inside of the event case.  But the value in the terminal (or local variable or property node) will be whatever was last written to it (via a terminal, local variable, or property node).  The Event itself always keeps corresponding old and new values of the control value as event data no matter at what time in the future event handling code executes. There is always huge risk of race condition if there are multiple writers to the same control because there are two buffers for each control behind the scenes (the first, which is called "Execution Buffer" - keeps the actual value for the code execution and the second, which is called "Operation Buffer" - keeps the actual value for the UI element) and one Transfer Buffer to protect data transfers between the execution and operation buffers.

 Operation-buffer changes execute exclusively in the UI thread (i.e. serialized with all other operations which runs in UI thread). As I said before – the control also maintains its private data snapshot, so in theory, it could happen that a different value (other than what’s displayed on the UI) is passed by the control output over the wire to the running code while a different value is observed in the control event for the same control at certain conditions. That's why it is not recommended to mix together all possible scenarios for control value changes to prevent a violation of determinism.


I found this topic because I am faced building a motion control and data acquisition system that uses, as part of it, a scientific-grade camera. The vendor of the camera provides a LabVIEW example of how to run the camera, but like the camera, it is a very complex example that makes extensive use of the Val(Sgnl) properties of many controls to implement state machines in both the main VI and several subVIs. It is not exactly straight forward to follow the data flow through such an example and this degree of use of the Val(Sgnl) feature was new to me. In trying to understand the example, I needed to figure out if there could be multiple change events queued up for any given control such that the same event structure frame would fire multiple times. Also, was it a FIFO queue?

 

It would appear that yes, there can be multiple events queued up and they are processed in the order in which they are queued up (lossless FIFO).  The data value provided at the time that an event is entered into the queue is the value that is available on the "NewVal" terminal of the event that handles the change.  On the other hand, the most recent/last data value is the value available from the control's terminal (or local variable or “Val” property node).  I built the attached example VI (LV v2014) to convince myself that this is really how it all works.

 

0 Kudos
Message 7 of 7
(2,740 Views)