LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Heisenbug? Initialize to Default doesn't occur first, except in Debug

Solved!
Go to solution

I have a "Success!" indicator that I want to set TRUE if the external library call to the DLL was successful. I also want to set it FALSE when I run the VI, so that I'm sure that it's TRUE because the call succeeded, and not because the state is left over from the last run.

 

So I went to Create Invoke Node: Initialize to Default and placed it on the VI. When I run the VI, the indicator stays FALSE, even though the library call successfully returns values from the DLL (which also proves that the call succeeded). It's as if the Initialize happens _after_ the compare returns true, instead of before the compare runs.

 

I turned on Highlight Execution to debug it, and now it works properly. Smiley Frustrated. This is 100% repeatable. If I turn off Highlight Execution if indicator stays FALSE after a successful run; if I turn on HE, it turns to TRUE after a successful run.

 

I thought the whole point of the Invoke Node: Initialize to Default  was that it would occur first, no? Or is my understanding incorrect?

 

I think I found a workaround, which is to wire the Error Out from the Initialize to the Error In on the library call, which I think forces Init to run first. Is my interpretation correct? I can't prove this, because debugging it also avoids the problem. But this also is 100% repeatable.

 

Without that wire my indicator is always incorrectly FALSE after a run, and with that wire my indicator is always correctly TRUE after a run (unless I disconnect the hardware to force a failure, e.g. then it's correctly FALSE after a run). With that wire, if I run the VI again and again, I can see it briefly flash to FALSE before turning TRUE, e.g. the intended behavior. But why do I need this workaround, and/or why does this behavior change when HE is on? Thanks!

 

InitToDefaultHappensLate.png

0 Kudos
Message 1 of 4
(2,893 Views)
Solution
Accepted by TheWaterbug

Yes, without the error wire both independent code parts execute in parallel, and whatever finishes last wins. Typical race condition. The error wire enforces an execution order. LabVIEW 101! 😄

(Highlight execution mostly slows down the lower part of the code, ensuring that it is the last thing to finish.)

 

You don't need this "reinit" at all! Simply go to your VI execution properties and enable "clear indicator when called". Voila!

 

ClearWhenCalled.png

 

 

Also note that there is a "not equal zero" primitive. No need for diagram constants with the wrong representation. 😄

Message 2 of 4
(2,887 Views)

Thanks!

 

So much to learn . . . .

0 Kudos
Message 3 of 4
(2,857 Views)

As Altenbach said, you should always use wires, especially the error wire, as a way to force things to happen in the correct order.

 

Since you're interested in learning things, here's something that's helpful to know.  Any property or invoke node that changes something on the front panel, such as the "reset to default" you used or a "Value" property node, takes many orders of magnitude longer to run than a local variable does to change the value.  

 

On my PC, on LabVIEW 2015, I can run the "Reinit to default" somewhere around 1500 times per second on a Boolean control.  However, it slows down when I'm doing graphics things like moving windows around, and so on, sometimes down to 60-100 times per second.  It basically slows your program down to the speed of your graphics driver, because that's what it's waiting on.

 

BUT... if I switch to using a local variable to set that same Boolean control to False, I can set that somewhere around 2.4 million times per second!  It would probably be even more if I removed some of the code monitoring the timing, because the variable write is so fast it's more likely the speed is being held back by that which is measuring the speed.  Even with that, it's over 1,000 times faster.

 

That's why your program always ran out of order.  Your DLL call takes maybe a few microseconds but your invoke node takes milliseconds, so it would always finish last.

Message 4 of 4
(2,854 Views)