LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Wise use of Local Variable

Solved!
Go to solution

@gkartik wrote:

"So, the calculation and the 8 reads can happen in any order!  Imagine, 4 reads of stale data, a write to the indicator and 4 reads of new data!  as an example!  without dataflow the values read are unknowable."

I don't know how local variables work. But from what you are saying, the data transfer from the indicator to all other local variables don't happen simultaneously. So it can cause problems and wiring can eliminate them. Am I correct? Can you some simple example to demonstrate your idea.


The intent of the local variable is to provide the current value of the control/indicator being read. Because your code does not have dataflow dependency it will attempt to run in parallel. The order in which parallel code runs is unpredictable. The local variable will not read the control/indicator until the local variable is ready to be read. In the meantime it could be possible for the value of the control/indicator to have changed. 

 

Attached is a quickly written vi where I added waits to control the order of execution to show what can happen. In my example Numeric 2 and Numeric 3 both read from local variables from Numeric 1, but Numeric 2 reads the data, then Numeric 1 writes new data, then Numeric 3 reads the data. Thus Numeric 2 and Numeric 3 have different values.

 

 

0 Kudos
Message 21 of 30
(2,396 Views)

Wires enforce ordering, because they have a direction. Things that receive data from a wire (e.g. indicators, or input terminals of other nodes) cannot run until data becomes available on that wire from the source (each wire can have only one source, but multiple destinations).

 

When you use a Local Variable, essentially you're allowing multiple sources for the "same" data. But you don't specify when they should be read (indeed, without ugly use of Flat Sequence Structures or similar, it's quite difficult to enforce ordering for a Local Variable). As a result, their values might be read at any time within their 'sequence block' (possibly not a real term - I mean the frame around them, e.g. For loop, While loop, Case Structure, etc), and if you have multiple copies, (especially containing reads and writes) they might not be the same.

 

I put together an example, but it didn't initially show the behaviour I'd expect. Once I added some parallelism, it very quickly fell apart (but possibly that's not representative of your situation). None-the-less, it does illustrate something 🙂

 

parallelRaceCondition.png


GCentral
Message 22 of 30
(2,391 Views)

@gkartik wrote:

Could you please suggest me some resources from where I could learn good programming styles. Because it is difficult to make a good readable VI without good programming practices.


When I got started in LabVIEW, I bought Peter Blume's "The LabVIEW Style Book" (and I've been bugging Peter to write a second edition for about a half-dozen years).  I read it cover to cover at least three times my first year, and have read it several more times.  I adopted and adapted many of his points, and try to "hint" to colleagues to adapt "better style", focusing on neat wiring, "one-screen" block diagrams, encapsulating detail in sub-VIs, making icons (even if only 3-4 lines of "text-in-a-box"), and always writing a minimum VI Description.

 

Bob Schor

0 Kudos
Message 23 of 30
(2,382 Views)

Quick, albeit ugly looking, method based on @Kyle97330 excellent suggestion.

 

Lots more can be done, 2012 vi attached.

 

mcduff

snip.png

Message 24 of 30
(2,376 Views)

@gkartik wrote:

Could you please suggest me some resources from where I could learn good programming styles. Because it is difficult to make a good readable VI without good programming practices.


LabVIEW ships with many examples and design templates that you should inspect closely. There are also plenty of online examples and even books as suggested by others.

 

Nothing beats hands-on experience and constant exercise. Write code, step back and think about better alternatives. Make mistakes, recognize the mistakes, correct the mistakes and learn from them (and never make the same mistake twice!), make new mistakes, etc. Repeat!

 

Analogy: You cannot become a faster runner by only reading books about running. You primarily need to run as much as possible! Still, a book about running physiology (nutrition, posture, pacing, etc.) can help you get more efficient faster while avoiding injuries.

 

 

Message 25 of 30
(2,369 Views)

Thinking more about the Giant Block Diagram and Plethora of Local Variables, I agree with McDuff's depiction of @Kyle97330's suggestion.  I'd go a few steps more:

  • I'd build a Cluster to hold the Front Panel Controls that I will be needing (a Cluster Wire is much less intrusive and can be passed to an "Unbundle by Name" to get out just what you need).
  • I'd make a TypeDef of the Cluster and make an Icon for it for use when you Bundle by Name (you need to put the Cluster on the input of the Bundle by Name, and instead of a huge Cluster diagram, you can right-click it and it will "shrink" to an Icon, at least in the last 4-6 versions of LabVIEW).
  • Build an Event Loop with Value Change cases for every Control where you add the new value into the Cluster.  Put a Shift Register in this Loop and initialize it with code that initializes your Control Cluster.  This will be the only place that you'll need the Controls, themselves, in the Block Diagram.
  • Have an Event Case for every Control to update its value in the Cluster.  [Magic is going to happen a few steps later ...]
  • Create a Stop Control (not in the Cluster) that you will use to stop the entire Program.  Create a Value Change Event for this Stop control and wire its NewVal output to the Stop of the Event Loop.  Keep the Stop Control, itself, outside the Event's While Loop.
  • In a separate While Loop, put the Program that needs to use these Controls.  Wire the Stop Control to this While Loop's Stop indicator.
  • All we now have to do is get the latest value of the Cluster into this While Loop.  We could use a Notifier, but if you are running LabVIEW 2016 or later, I recommend that you use a Tag Channel Wire.  I'll show you how ...
    • Inside the Event Loop, right-click the Cluster Wire coming out of the Bundle by Name and choose "Channel Writer".  Choose a Tag Channel.  Bring your cursor near its output to get the Wiring Tool, click, and drag the Channel Wire (it will look like a pipe) to the outer edge of the Event's While Loop.
    • On the outside of the While Loop, create a "wire" (looking like a pipe) and create a path to the separate While Loop (where your code will be), crossing into the While Loop (see below).  Note that the "pipe" lies on top of the While Loops, indicating it is "jumping over the top" and allowing the data to flow "unimpeded" (that's why the formal name is "Asynchronous Channel Wire").
    • On the stub inside the (lower) While Loop, right-click and Create Channel Reader.  Right-click the Reader's output and you'll have the Control Cluster that you just updated in the Event Loop.
    • One more step -- you don't (yet) have the initial value of the Cluster in the While Loop, just the value(s) after you make changes.  So click on the Cluster wire as it goes into the Event Loop, create another Tag Channel, and join its output with the Pipe running from the Event Loop to the While Loop.  Be sure you use a proper Pipe Flange.
    • I put the 1-second Wait in the lower Loop to mimic "lots of processing", and also to avoid overheating the CPU ...  This is Just an Example, after all.
  • What if you are using LabVIEW 2012, where there were no Channel Wires?  Well, Tags are analogous to Notifiers (which, I must confess, I "didn't get" for the longest time -- Tags, to me, are so much simpler ...).

Here is the code (as a LabVIEW 2016 Snippet -- I also attached the VI and TypeDef).

No Local VariablesNo Local Variables

I probably shouldn't mention this (as it is my first time presenting at NIWeek, and I'm slightly nervous), but I'll be discussing "Using and Abusing Channel Wires" on Monday, May 20 at 4:30 pm.  It will be a tad more complicated than the above ...

 

Bob Schor

 

P.S. -- of course I forgot to attach my VI and Control, but was saved by the Edit Your Reponse button ...

 

Download All
Message 26 of 30
(2,360 Views)

@Bob_Schor wrote:

 

I probably shouldn't mention this (as it is my first time presenting at NIWeek, and I'm slightly nervous), but I'll be discussing "Using and Abusing Channel Wires" on Monday, May 20 at 4:30 pm.  It will be a tad more complicated than the above ...


As long as you show your code, I think you will be fine, and give an excellent talk.

 

mcduff

0 Kudos
Message 27 of 30
(2,356 Views)

Drat!  I think I used the correct Snippet, but attached a flawed VI.  Here's the correct one, with my apologies.

 

Bob Schor

0 Kudos
Message 28 of 30
(2,345 Views)

@mcduff wrote:

As long as you show your code, I think you will be fine, and give an excellent talk.

Well, they provide a PowerPoint Template which means "pictures of code", but I will have Laptop with VIs as well (and have a few "Show Code Now" slides ...).

 

Bob Schor

0 Kudos
Message 29 of 30
(2,344 Views)

@billko wrote:

@JÞB wrote:

@billko wrote:

Unfortunately, the forum does "pre-processing" of pictures before displaying them, so your snippet won't work.  You'll have to upload the snippet as a file.  I'm already afraid of what I'm seeing though.  You know that LabVIEW doesn't really flow left to right; it just appears that way because you connect the nodes together from left to right - usually.  That being said, the "floating code" that you have in there can execute at any time it feels, and if you have locals attached to it, you may or may not be operating with stale data.


Bill,  you can download the png from the picture manager then the snippet works fine


Perhaps we should update the sticky at the top of the forum?


Bill, read the thread! That info is in there 😄


"Should be" isn't "Is" -Jay
0 Kudos
Message 30 of 30
(2,301 Views)