09-30-2009 01:08 PM
Mark,
You need kudos for the last post, because that is the true spirit of this forum!
09-30-2009 01:20 PM
Guys thanks for all the help, both for the 'quick fixes' and the pointers on how to do it right. As I suspected I'm looking at it the wrong way. This app is reasonably well advanced, so if the quick fix works (local variables) that's how it will be sorted. At least I know to explore the state machine stuff next time. Mark, you're on the money when you say that I'm turning it into a sequential thing.
Presumably I can create a local variable associated with a control from the control's context menu? Will it matter if the control is inside a frame which has not yet been accessed when I click the start button?
I'll try all this tomorrow.
Thanks again,
Joe
09-30-2009 02:16 PM
Friends, should we really leave a beginner with that outburst of emotions about locals and sequences alone?
Ok, I try to explain the wohle thing. Every good LV programmer goes into a kind of frenzy mode whenever he/she encounters locals, globals or sequences. All of these are severe violations of the dataflow. Think of them as the infamous GOTO statement.
The big problem is, that people coming from a text based programming background, try to literally translate their code into LV. In the breakpoint forum, there is a thread that collects bad results ('why local variables are bad').
I go for all 3 and give a brief do/don't:
* globals:
do:
- writen in the init of a app and only read elsewhere (lookup table).
- duct-tape: iof there is a demo tomorrow, you can't redo architectural flows.
don't:
- They gave me the biggest race condition ever on a shiped product. Same mess as the duct-tape.
* locals:
do:
- initialize controls
- save val's for next init step (if doning something more important with the terminals)
don't:
- use them to pass data, we have wires.
- use them instead of a terminal (x10 performance).
- replace them with property nodes 'Value', even less performance
'*Sequences (replace them by state machines ASAP):
do:
- Only a fixed step will ever be required, mainly 'Init, Run, Stop'
- Place around timing functions (better use openG that does sequnting via the error wire)
- Duct-tape against race conditions (encapsulating locals, globals or timing functions)
- obscure issues when interfacing external code and pointers
don't:
- never use the stacked SQ, better the flat one
- use more than one frame, make the error flow determine the execution order. Unless you only have Init, Run, Stop'
- use them, a state machine is the same effort but more gain
Felix
09-30-2009 02:21 PM
09-30-2009 02:41 PM
Will it matter if the control is inside a frame
You'll find that terminology is important - a CONTROL cannot be inside a FRAME.
A CONTROL is on your front panel, the TERMINAL for that control is on the diagram, possibly within the FRAME of a sequence structure on the diagram.
If you're using a local variable, then it doesn't matter where on the diagram the terminal is, it's where the local variable is.
Wherever you detect the START button being clicked - if you set a LOCAL variable to 0 (or anything else) at that same point, then the associated indicator (or control - you can have local variables for controls as well) gets set to the value you fed to the local, and its display will update.
It's similar to a terminal, but there are differences:
Some folks are dogmatic about local variables ("they're always bad", "they lead to race problems", "spawn of Satan", or such), I'm not one of them.
If you understand dataflow programming in general, then you should have no problems. You have to understand that they are NOT the same thing as a wire: if you wire from A straight to B, then it's guaranteed that B executes AFTER A. But if you put A into a local variable (or terminal), and read from a terminal (or local variable), then there is no guarantee which occurs first, the read or the write. That's bad.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
09-30-2009 03:36 PM
Hold a moment please.
We want to navigate a new user of LV to do it good. But we should not overdo it. If this is just the start of a project, please go over to state machines, even if they might be unnecessary in the future. If you write new code, do it straight away.
But: if you need to show results, ship a product, get it running... get it running and don't look back on the spaghetti.
I am not promoting good code at all.
Write good code (as discussed here) if you need to work with it. If the product is just going out, all duct-tape is fine as long as no one sees it. Global and locals might fire back (race conditions), but the money is already paid. Sequences are save.
In short: I like good code. I'm payed for working code.
Felix
09-30-2009 03:57 PM
F. Schubert wrote:Hold a moment please.
We want to navigate a new user of LV to do it good. But we should not overdo it. If this is just the start of a project, please go over to state machines, even if they might be unnecessary in the future. If you write new code, do it straight away.
But: if you need to show results, ship a product, get it running... get it running and don't look back on the spaghetti.
I am not promoting good code at all.
Write good code (as discussed here) if you need to work with it. If the product is just going out, all duct-tape is fine as long as no one sees it. Global and locals might fire back (race conditions), but the money is already paid. Sequences are save.
In short: I like good code. I'm payed for working code.
Felix
To a very limited extent I agree with you. However, if I am selling a product I would like to ensure that my customer gets a quality product, not simply ones that works. Also, what is the product going to be used for? If this will be controlling an X-Ray machine I know that I would not be pleased knowing the potential for race conditions existed inside the code. The cost of an error in such a system is very high.
09-30-2009 04:24 PM
Mark,
something dangerous (like X-rays, lasers) should not be controlled by software alone. They definitfly need some hordware interlock system.
But customers allways come with a new feature request. But won't change the agreed timeline.
They can say it in one sentence.
I would ask for a week implement it. (Don't think anyone agrees on that).
IT TAKES ME A MONTH...
And back to the primary question: ship or reuse?
Felix
09-30-2009 04:36 PM - edited 09-30-2009 04:39 PM
F. Schubert wrote:Hold a moment please.
We want to navigate a new user of LV to do it good. But we should not overdo it. If this is just the start of a project, please go over to state machines, even if they might be unnecessary in the future. If you write new code, do it straight away.
But: if you need to show results, ship a product, get it running... get it running and don't look back on the spaghetti.
I am not promoting good code at all.
Write good code (as discussed here) if you need to work with it. If the product is just going out, all duct-tape is fine as long as no one sees it. Global and locals might fire back (race conditions), but the money is already paid. Sequences are save.
In short: I like good code. I'm payed for working code.
Felix
Don't agree with the general philosophy. Do your best to write the best code you know how to write the first time around, or you'll pay for it when you have to support it! If you have to write spaghetti code - and everyone does at times - do so with great trepidation because it WILL come back to haunt you. Try not to write quick n dirty code if at all possible.
Example:
A team of five people have been working for two YEARS trying to untangle spaghetti code in one test application that was abandonware. Still haven't succeded in fixing half the bugs.
That being said, sometimes you get done writing the code, then you learn a way to do the same thing much easier/better, but it would take a major rewrite... oh well, that's what version 1.1 is for! 😄
Bill