LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Am I using good programming practice?

Solved!
Go to solution

Hi there.

 

If I can trouble you for a minute, can you please take a look at the attached VI?

This is a method I've used for a couple of years when programming various LabVIEW applications.  In short, I'm using a stacked sequence structure to handle an Init phase, a Main phase, and an Exit phase.

But a colleague has argumented that this could cause weird behavior, when having multiple while loops inside the Main window, e.g. when using a queued event structure with a producer loop and multiple consumer loops.

Is this the case?  If so, if I'm in fact using bad programming practice, what is the correct way of programming a Labview stand-alone application?  Where should I place the controls on the front panel?  I think it's a bit disorienting not having the controls in one place, but instead having them spread out allover the code.

 

Thanks for any input! 🙂

 

BR,

Øystein Johnsen.

0 Kudos
Message 1 of 10
(2,846 Views)

Hi Johnsen,

 

the common advice is to replace stacked sequences by state machines. They provide more flexibility with a minimum of additional overhead…

 


I think it's a bit disorienting not having the controls in one place, but instead having them spread out allover the code.


I think it's helpful to have controls/indicators where they are needed to be: in the DATAFLOW…

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 2 of 10
(2,840 Views)
Solution
Accepted by ojohnsen79

I cant open the code due to sitting on 2011 currently, but in general: Using a stacked sequence only for init and exit shouldn't cause much problems assuming it wraps all, but it is unneccesary. It hides code.

If you have a producer/consumer pattern as main function, why not simply queue an Init-command in the start and implement an Exit-command where you clean up as you exit?

 

As to the control they're usually placed in their event case or in the consumer where they're updated.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
Message 3 of 10
(2,833 Views)

GerdW and Yamaeda:

Thank you for your responses!

Yes, I am using a queued state machine (called it queued event structure by mistake).

 

I see your point about queuing an Init state in the start of the program.  I'm using a global functional variable for keeping track of the action queue, which automatically creates the queue when first called.  I guess I could queue an Init state at that point.

 

But what do you then do with all the controls on the front panel?  Do you place them inside the Init state handler in the consumer loop, or do you just spread them out allover the code?

 

0 Kudos
Message 4 of 10
(2,821 Views)

As GerdW said its always adviced to replace the Sequence structure operation with case structure. In your case its fine to have Sequence structure in the way you have used.

 

Avoid using Local variable instead use the Value proerty node Eventhough there is not much difference between both, a property node helps to have a proper data flow. 

Always keep the Controls inside the event structure (The reason is given in this thread).

If you are not going to use the Timeout event you can remove it so that you can save unnecessary execution.

-----

The best solution is the one you find it by yourself
0 Kudos
Message 5 of 10
(2,816 Views)

@ojohnsen79 wrote:

But what do you then do with all the controls on the front panel?  Do you place them inside the Init state handler in the consumer loop, or do you just spread them out allover the code?

 



I place them where they're used as to reduce the need for Locals. Controls are typically placed in their respective event and indicators in the event or consume state where they're updated. I guess you can call that spreading them out, though i'd argue it's as logical as grouping them all in a "declaration" state.

 

I disagree with Anand about the property nodes though, since they're about 100x slower than a local variable. If you for some reason need to update an indicator in several consumer states (or implement a range-check/feedback to a control) i'd use a Local since the state should be small and dataflow should be forced by the other functions (as a DAQ read).

 

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
Message 6 of 10
(2,797 Views)

@Yamaeda wrote:

I disagree with Anand about the property nodes though, since they're about 100x slower than a local variable. If you for some reason need to update an indicator in several consumer states (or implement a range-check/feedback to a control) i'd use a Local since the state should be small and dataflow should be forced by the other functions (as a DAQ read).

 

/Y


I too agree with respect to speed. I suggested Property node for the initialization where speed doesn't play a big role, and I personally prefer property node for this.

-----

The best solution is the one you find it by yourself
Message 7 of 10
(2,784 Views)

I think we've found a "best practice" plan for me to follow then. 🙂

Thank you very much for your help!

0 Kudos
Message 8 of 10
(2,776 Views)

P@Anand wrote:

Avoid using Local variable instead use the Value proerty node Eventhough there is not much difference between both, a property node helps to have a proper data flow.


That is HORRIBLE advice!  (You just hit on one of my pet peeves).

 

The local variable and the property node both have the race condition issue.  Niether really follow data flow, unless you actually use the error cluster on the property node.  But the property node is WAAAAAAAAAAAAAAAAAAAAAAAAAAAAY slower.  Based on my last benchmarks, we are talking in the 2000X range slower.  The reason being that each time you read or write from a property node, you are forcing a thread swap since we have to get/set the value through the UI thread.  This also forces a front panel redraw.  The moral of the story is to use a wire or shift register to pass your data around whenever you can.  If you have to get data from the front panel, try to use the terminal.


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 9 of 10
(2,760 Views)

I'll make myself clear, I am not advicing to write to the Property node/Local variable for value update (Never). My point is only for initialization and personally I never update value using Property Node/Local variable, I just use my indicator terminal. Even if I have to pass data from different loops/VIs I use Queue or FGV, Please don't take my advice in a wrong way ( 😞 I really didn't mean in continous update)

-----

The best solution is the one you find it by yourself
0 Kudos
Message 10 of 10
(2,755 Views)