09-22-2009 09:57 AM - edited 09-22-2009 10:00 AM
Hi,
I am sure this should be easy for LV user, but I still get mad with the matter.
In circle 1 Gauge_error is set to true but when it arrives in circle 2 it is set to false (which is the default value).
I can't understand why because between the circles the value is true as it should be.
I know I did something wrong with that local variable. I tried with property node : Value but the problem is still there.
Thanks for your help.
Solved! Go to Solution.
09-22-2009 10:09 AM
That is a classic race condition and is precisely why you should not be using locals. You are assuming that the second local is read after the first local is written to. Absolutely not true.
Really, really work hard to replace the locals with a wire.
09-22-2009 10:16 AM
09-22-2009 10:16 AM
Ok, thanks.
I replaced by a wire and it is working just as expected
In this case it was not really hard to replace local variable by a wire but sometimes this is not so easy.
So what should the programmer do ? Is there a "trick" to avoid this issue ?
09-22-2009 10:26 AM
09-22-2009 10:33 AM
remvu wrote:
So what should the programmer do ? Is there a "trick" to avoid this issue ?
One thing you could do is store the error cluster in a wire that runs through every case and is maintained from iteration to iteration using a shift register.
The other option is to use an Action Engine (see Ben's Action Engine Nugget). This stores the data in an uninitialized shift register in the subVI. You create different actions such as Set and Get for each of you pieces of data you want to get, or set, within that cluster. This gives you the ability to read or write to that variable from multiple points of the program independently, without all the variouis bundle/unbundle operations stepping on each other.
09-22-2009 10:36 AM
remvu wrote:So what should the programmer do ? Is there a "trick" to avoid this issue ?
Typically, you would keep your error cluster in a shift register that us updated as needed. In this case, you might want to add an indicator to keep the operator updated about error status, but often you don't even need a front panel object (control or indicator).
You are still thinking in terms of text code, where "variables" are cornerstones.
Local variables can be used to communicate where dataflow is not possible, e.g. between loops. But even in these cases there are better tools, such as queues.
It is time to familiarize yourself with dataflow. For example the (cutoff) while loop in the lower right of your code image is completely pointless, because of dataflow issues. No matter what, it will execute exactly once after the upper loop has stopped and thus can be replaced by a sequence frame, for example. It cannot start while the upper loop is running because it depends on data from it, and once the upper loop is finished, the boolean is true, stoping the loop immediately after one iteration.
Personally, I would also not call a custom cluster "error". A labview error cluster has a very specific personality (status, code, source), so re-using the label "error" could lead to confusion. Why not call it "status" for example.
09-22-2009 10:38 AM - edited 09-22-2009 10:41 AM
remvu wrote:
You mean like it is done for the error in / error out cluster ?
Yes, you could conceivably do that for all "variables" used in that case - using a shift register and the cluster of data elements. No Locals !
09-22-2009 10:58 AM
@altenback
I read carefully your message and it was really useful.
I really need a guy like you in my office to learn how to program corretly with Labview, the problem is that I am the only one here which has some Labview bases.
I think it could be a good idea if I go to a Labview training, like a basics II or Intermediate I, II ?
Regarding the loop there was that inside :
Now I put it directly in the main loop but the problem is that the duration is not updated "continuously" (before it didn't too...of course).
@Broken arrow
Thanks now I get it !!
09-22-2009 11:00 AM - edited 09-22-2009 11:07 AM
remvu wrote:Regarding the loop there was that inside :
![]()
Now I put it directly in the main loop but the problem is that the duration is not updated "continuously" (before it didn't too...of course).
Well, the duration indicator still needs to be in the loop. (btw. if you would swap the two inputs to the subtract node, you would not need to multiply by -1.) 😄
Here's what you can do: see no locals!
The code on the left is a bit more lightweight. 🙂