LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Help improve my style and quality of LabVIEW coding

Hello,

 

I am thinking of doing the CLD certification for LabVIEW and have started preparing by reading some literature (code style guidelines, etc.) and also trying to implement the newfound knowledge into my coding habits. I have also read that local variables are bad, and that the best practice is to avoid them.

 

However, I am having difficulty implementing all of the material I read about LabVIEW coding into my VIs - which are almost always coded in the same manner as the one I attached. Basically all of the LabVIEW applications I make at my company require reading DAQ inputs, processing the acquired data and doing some control algorithms, which send control signals to DAQ outputs, and writing all of the data to a file.

 

I have attached a sample VI (with dummy DAQ subVIs). If you have the time - any ideas, comments, consideration or improvements on all areas of the VI are greatly appreciated and welcomed. I think this will be the best way for me to learn new LV tips and tricks.

 

Thank you!

0 Kudos
Message 1 of 13
(3,376 Views)

G-Pero,

It is great to hear that you are considering CLD Certification. You must get an overall idea of LabVIEW and its design patterns as a first step. Have you studied the various design patterns avaliable in LabVIEW? 

The forums can be a great place to learn about new concepts in LabVIEW. 

 

Just egging you to find more ways to learn. My 2 cents.


Good luck

Prashanth N
National Instruments
0 Kudos
Message 2 of 13
(3,366 Views)

I had a look at your code. From the first glance, I can point out that you should use a project so that your hierarchy is visible to anyone using your code. On the poisitive side, you have kept your subVIs and typedefs in sub-folders, which is a good thing.

 

Can you please save your code in LV 8.5? Always try sharing VIs in oldest version possible. That way, more people will be able to view it.

 

Regards,

 

Prashanth N
National Instruments
0 Kudos
Message 3 of 13
(3,365 Views)

Local variables (as well as globals) are not inherently bad; they are however easily misused, which has lead many people to admonish against their use.  However there are legitimate uses for them.

Message 4 of 13
(3,346 Views)

@G-Pero wrote:

...

I have attached a sample VI (with dummy DAQ subVIs). If you have the time - any ideas, comments, consideration or improvements on all areas of the VI are greatly appreciated and welcomed. I think this will be the best way for me to learn new LV tips and tricks.

 


Its not a biggest Block Diagram which I have ever seen, but try to fit it to 1600x1200 as first excercise.

Did you get CLAD certification already?

 

Andrey.

 

0 Kudos
Message 5 of 13
(3,343 Views)

OK I've seen worse. (actually not too bad but...)

  • Use wire labels especially when you have wires that don't fit on 1 screen
  • You show a lack of understanding how timed loops differ from while loops  (event structure in TLoop with DT=0, Elapsed Timer in Timed Loop.   Someday you'll say WTH was I thinking spawing unique execution systems for thoseSmiley Wink
  • You could have saved a lot of locals and data duplication by enqueueing data from the DAQ loop to the Write File Loop instead of using a notifier
  • Sometimes an Array of Clusters can be a good idea  clusters of clusters of same data type can often be harder to maintain- want to add a new element- maybe test a single point? just init the array of clusters (like from a file perhaps?)  Saves a lot of confusion
  • Saving timestamps to file as strings is a pet peeve of mine.  Now how do you graph vs time?  Check out My Idea 
  • There is no reason to avoid creating sub-vis and making the Main BD fit on one screen.  I fact it can help to show the code high level structure.
  • Straighten them wires!

Most of your issues would be solved by re-thinking your data structures- A good place to concentrate on to improve.

 

Keep Slinging- you'll get there


"Should be" isn't "Is" -Jay
Message 6 of 13
(3,329 Views)

@paul_a_cardinale wrote:

Local variables (as well as globals) are not inherently bad; they are however easily misused, which has lead many people to admonish against their use.  However there are legitimate uses for them.


I'll preface this by saying I have not looked at the code yet however I wanted to comment on this with respect to the CLD exam. While there are cases where local variables are an acceptable choice they are generally not accepted in the CLD exam. Part of successfully passing the CLD exam to to understand what NI is looking for. Global and local variables defintely are not something they look for in a CLD exam.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 7 of 13
(3,326 Views)

OK, I did take a look at the code now. HEre are some additional points to consider.

  • Document, document, document. None of your controls or indicators are documented. Also, document your code more to help someone looking at it to actually understand it better.
  • Definitely avoid the use of all of the local variables. Thing of a design pattern that separates the processing tasks from the UI. If you have one task handling the UI you really don't need to use local variables.
  • Avoid unnecessary bends in your wires.
  • Definitely get your block diagram to fit on a smaller screen. These days it shouldn't be larger than 1600x1200 or close to that.
  • Modularize your code. Use more subVIs
  • You have a classic off by one error in your code. All of your loops use the stop button to exit. However you always check the value at the beginning of the loop iteration therefore you will execute the loop one more time than necessary.
  • Avoid unnecessary frame structures. You have a frame structure in the second loop that does nothing for you. Everything down stream of it will execute in the correct order because of the data dependencies. The frame structure serves no purpose here.
  • Try to avoid deeply nested case structures. Once I start to see that happening in my code I rethink my logic. At a minimum I would build an array of the various Boolean values and convert them into a number and use that to chose the appropriate case to execute rather than nesting three or more case structures.


Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 8 of 13
(3,314 Views)

@Jeff Bohrer wrote:

OK I've seen worse. (actually not too bad but...)

  1. Use wire labels especially when you have wires that don't fit on 1 screen
  2. You show a lack of understanding how timed loops differ from while loops  (event structure in TLoop with DT=0, Elapsed Timer in Timed Loop.   Someday you'll say WTH was I thinking spawing unique execution systems for thoseSmiley Wink
  3. You could have saved a lot of locals and data duplication by enqueueing data from the DAQ loop to the Write File Loop instead of using a notifier
  4. Sometimes an Array of Clusters can be a good idea  clusters of clusters of same data type can often be harder to maintain- want to add a new element- maybe test a single point? just init the array of clusters (like from a file perhaps?)  Saves a lot of confusion
  5. Saving timestamps to file as strings is a pet peeve of mine.  Now how do you graph vs time?  Check out My Idea 
  6. There is no reason to avoid creating sub-vis and making the Main BD fit on one screen.  I fact it can help to show the code high level structure.
  7. Straighten them wires!

Most of your issues would be solved by re-thinking your data structures- A good place to concentrate on to improve.

 

Keep Slinging- you'll get there


  1. Ok, will do.
  2. Can you explain what the difference is? Or point me to some good literature on this topic? 
  3. How exactly can you do that? I tried sending data via notifier, but I could not send different data types.
  4. I do not quite understand what you mean.
  5. Also, I do not understand what the problem here is. The graph shows data vs time.
  6. Will try.

@Mark Yedinak wrote:

OK, I did take a look at the code now. HEre are some additional points to consider.

  1. Document, document, document. None of your controls or indicators are documented. Also, document your code more to help someone looking at it to actually understand it better.
  2. Definitely avoid the use of all of the local variables. Thing of a design pattern that separates the processing tasks from the UI. If you have one task handling the UI you really don't need to use local variables.
  3. Avoid unnecessary bends in your wires.
  4. Definitely get your block diagram to fit on a smaller screen. These days it shouldn't be larger than 1600x1200 or close to that.
  5. Modularize your code. Use more subVIs
  6. You have a classic off by one error in your code. All of your loops use the stop button to exit. However you always check the value at the beginning of the loop iteration therefore you will execute the loop one more time than necessary.
  7. Avoid unnecessary frame structures. You have a frame structure in the second loop that does nothing for you. Everything down stream of it will execute in the correct order because of the data dependencies. The frame structure serves no purpose here.
  8. Try to avoid deeply nested case structures. Once I start to see that happening in my code I rethink my logic. At a minimum I would build an array of the various Boolean values and convert them into a number and use that to chose the appropriate case to execute rather than nesting three or more case structures.

  1. Will do.
  2. How can I accomplish all the tasks in my application without the use of local variables? I admit, this is the main reason I opened this thread ... because I have tried to imagine a design architecture that would work without local variable, but was unsuccessful. Can someone please explain in detail how to do this on this specific application.
  3. Will try to.
  4. I will try, but I make my block diagram to the width of my screen, but vertically I do not limit its size - so I can easily scroll up and down to move around.
  5. I try to create as many subVI as possible, but only on code that is reusable on other projects. Is also better to have a lot of single use subVIs with every project? Doesn't this add unnecessary overhead and slows the application?
  6. What would be the correct way to stop the application?
  7. Ok.
  8. Ok. I only do your proposed solution on nested case with a depth of at least 4. 3 nested structures were still acceptable for me, but I will listed to your proposal and try to improve on this.

 

Thank you all for taking the time to look at the code and writing your comments.

 

 

I already have the CLAD certification, but this was only a test. I think I will be able to try the CLD exam sometime next year, but I have to learn and implement different coding style in my everyday application (at work). With your help I am sure I will be able to accomplish this - reading literature is one thing, but actual projects are another.

0 Kudos
Message 9 of 13
(3,284 Views)

2 Can you explain what the difference is? Or point me to some good literature on this topic?

Some good posts on LabVIEW's VI Properties> Prefered execution system are colleted and linked from post 3 in this thread.  Timed loops force the creation of a new single thread execution system independant of any other execution system This can cause some subtle performance hits when you have multiple Timed loops.  By all means use them- but use them when required and default to un-timed structures for better performance.

 

3 How exactly can you do that? I tried sending data via notifier, but I could not send different data types.

Check out Queues- a queue can take any data type and hold multiple elements.  Much more scaleable than a notifier.

 

Cluster of clusters

Youu have three Clusters of clusters of the same data type. Convert them to Array of Cluster- Watch all your case structures to select the "active" cluster become Index arrays!  (and what happens when you want to add or remove a "setting"  You need to change the clusters.  With arrays of clusters again, you get a much more scaleable solution- add a ini file to hold the desired values for each experiment and your solution just requires a new file to change parameters at run time no need to edit the data in the VI and re-compile to run a new test.

 

Saving timestamps to file as strings is a pet peeve of mine.  Now how do you graph vs time?

The data in your file is now a string-how do you view any parameter vs time from the file? ( you can't) You graph vs time in the VI then throw out time (which is important) in the data file because you convert it to a string- Better to save it in the native format of the application you will use to inspect the data.  Usually that's Excel, Lotus, or Access- Time to XL converts TimeStamp to the correct epoch and scale for any of these applications and you maintain the ability to graph vs time from the stored data.

 

 


"Should be" isn't "Is" -Jay
Message 10 of 13
(3,267 Views)