06-03-2010 11:02 PM
All,
As you can see in the attached image I have declared controls, indicators, booleans, etc. outside of a while loop containing an event structure...First question, is this a silly practice? If it is, what is a good practice? I like my method because I can easily see the variables without digging through layers of events. Anyway, using this practice and property nodes to initialize controls and indicators to certain values, when a vi called seems like a good way to go about things.
Anyway, as you can see, the string indicators are initialized to empty strings using the value property node. In this case, the block diagram shown is a subvi that is supposed to return the value of the string indicator "acceptedValue" when a button named "accept" is pressed to a main vi. However, as the code currently exists, it will only return an empty string. If I remove the intialization of "acceptedValue" to an empty string outside of the loop, it will indeed pass the expected string value instead of an empty string to the main vi... However, in my mind this is a problem because I want to keep the intialization to empty string to make sure some previous value of the subvi isn't accidentally returned to the main vi.
What am I doing wrong?
06-04-2010 01:24 AM
You are programming like a text programmer. Think dataflow instead.
It would really help if you could attach the actual VI instead, because it is impossible to tell from a picture what the program is doing.
First of all, shuffling data around via value property nodes is probably the most inefficent way to do things. The wire is the variable, not the controls or indicators.
If your indicators are output connectors, place them to the right of the event structure so they receive data via a wire coming from the event structure. The cancel event would output an empty string, etc. If the code is more complex, keep the values in a shift register.
All your booleans are probably set to latch action. This also means that they need to be inside their respective event case so they can properly reset once they are pressed. (A latch action boolean will reset when read by the code. If the terminal is outside, it will be read right when the program starts and then ever again.)
Your code is also very unpredictable. For example you are not ensuring that the initialization occurs before the event loop. They could execute in parallel, leading to race conditions and unpredictable results.
If you simply want to make sure that indicators are cleared when the subVI is called, there is a setting in the "execution" section of the VI properties: "Clear indicators when called". Most likely you don't need it.
06-04-2010 01:26 AM
Hi KSU,
from what I see you initialize the "Selected Result" indicator with an empty string. Later in the event your read the indicator (which has been emptied) and feed the value to a different indicator. I would expect an "empty string" result from this operation.
But:
I wouldn't use an indicator to transport values from one location to the other. Use wires instead...
06-04-2010 08:20 AM
Thanks guys, I have no formal training in Labview and it shows...have a bit of text based programming eduation.
Anyway...
"If your indicators are output connectors, place them to the right of the event structure so they receive data via a wire coming from the event structure"
Inside or outside of the while loop?
06-04-2010 08:39 AM
KSU Flyer wrote:Inside or outside of the while loop?
06-04-2010 09:04 AM
The other guys here have answered exactly (and more) than what I would have said myself.
However, do a search on "state machine" its an architecture which I use for similar use.
Changed my life
06-04-2010 10:26 AM
Thanks guys...the attached is the vi, but its a bit jacked up now as I'm trying to do away with the property node stuff as suggested.
I'd love to figure out state machines
06-04-2010 11:53 AM
You have effectively created a sort of state machine using an event structure. I have never seen such an architecture. For example, your start keyboard event causes another event, the search entry event. This is like one state (start keyboard) calling the next state (search entry). Pretty brilliant for a text based programmer with no Labview experience. However, this is Labview, and this architecture is not very desirable and not very efficient, and also not very scalable.
Please look at my attached state machine examples. One uses strings to dictate the state, the other uses a queue. The outcome of one state can dictate which state to jump to next. This is standard practice in Labview. Try adapting your code to this architecture. You will be able to eliminate a lot of property nodes.
You don't need to declare variables in Labview. Just use controls and indicators wherever you need them. Your first state should be an initialize state, where you set the initial values for your controls and indicators, such as wiring in a blank string to selectedResult and a 0 to matchesFound. Then your next state would be to an event structure that waits for some button, like startKeyboard, to be pressed. That event would then call the state where you would put your virtualKeyboard.vi inside. That state would also call the next state which would be searchEntry. You won't need the Val(Sgnl) property node anymore.
Try to code this way. With the state machine architecture, you will be able to add more states, change the flow, and such as your code requires future changes. Also it makes it more easy to read. Let us know if you have troubles.
06-04-2010 12:48 PM
Thanks tbob, brilliant or crazy...probably the second. 🙂
I think I get it, but one question...do you ever use an event structure? Seems to me that you always use a case structure with wait function in the while loop to keep from eating up clock?
Thanks again!
06-04-2010 01:02 PM
The event structure is used when you need user input, like waiting for a user to press a button or change a control value. Otherwise you do not need an event structure. In your case, I believe you are wanting to wait for the user to press a button, so one of your states (probably right after initialize) will contain an event structure. When the event fires, send the next state out to the shift register. The code will jump out of the event case to the proper case. You can always jump back into the event case when the immediate function is done and you want to wait for user input again. That is the beauty of a state machine. You tell it where to go.
The delay in the loop is strictly for preventing 100% CPU usage.