09-10-2008 11:09 AM
I've been working the hardware end of the project and am now just getting back to this issue. All of you SM lovers out there should be happy to know that I converted all of my sequences to state machines per your recommendations above.
Since my terse "sample" vi caused confusion, let me just explain how I did the coding and ask for suggestions on how to remedy the problem. The code consists of a top-level state machine with states [Pre-powered Init, Post-powered Init, Normal Operation, Shutdown]. Inside each of these states there is typically another state machine that performs the details. For example, inside of Pre-powered Init, I set up my database connections, set the front panel to the default state, prompt the user for login information, etc. Inside of Post-powered Init, I initialize my power supplies, spectrometers, Compact Field Point, sision system, etc. I really only care about UI events in the pre-powered state (where I can adjust my configuration parameters or turn the station on) and in the Normal Operation state (where I use the front panel controls to make all the testing take place or turn the station off). Somehow, I have to decouple this mess so I only have one event handler. Since I was uninitated in the zen of event handling, I made the common mistake of place handlers where I thought I needed them, one in each of those two states.
My current ponderings include whether to turn this thing inside out so that the event handler is the outer-most structure or to set it up as a second structure that runs in parallel with my existing state machine. Any ideas how to refactor this into something elegant?
09-10-2008 12:04 PM
From your description, there should only be one state machine. It appears that your pre & post powered init only contain other states. Simply bring those inner states to the same state machine as "Normal Operation" & "Shutdown". All within one state machine. And delete pre & post powered init since they are no longer needed.
Now, as far as Operation states.... if you have Front Panel controls that you want to trigger events, then you should add another loop (typically at the top) which handles the Operator (Front Panel controls) events. Within that loop you should place an Event Structure.
You can find a template of what I describe by selecting: File > New... > From Template + Frameworks + Design Patters >
Producer/Consumer Design Pattern (Events)
09-11-2008 11:42 AM
09-11-2008 12:49 PM
Can you also post in LV8.2?
R
09-11-2008 12:58 PM
Yes. Thanks.
09-11-2008 01:19 PM
Oh boy....
Where to start... 😮
Wow.. you like to complicate things.. 😉
First: Never place an Event Structure within an Event Structure.... (unless you R-E-A-L-L-L-L-L-Y know what you're doing)
Why use references to create an event? Why not handle the value change event directly from the button.
I'll modify your code to illustrate.
R
09-11-2008 01:46 PM
"Wow.. you like to complicate things.. "
This is a complex problem. I hope I am not trying to make it harder than it needs to be.
"First: Never place an Event Structure within an Event Structure.... (unless you R-E-A-L-L-L-L-L-Y know what you're doing)"
I didn't. There are two event structures inside of a state machine. They are not nested.
"Why use references to create an event?"
I'm not. I'm using references to register the events.
"Why not handle the value change event directly from the button."
Can do except that limits you to static event handling which then indeed causes a practical limitation on the number of event handlers you can have (limit = 1) as stated in other posts. With dynamic registration, I can turn the events handled by the structure on and off as shown in the example.
09-11-2008 02:01 PM - edited 09-11-2008 02:02 PM
This will probably show up in Ray's code, but what I would suggest is to have a separate loop that handles events. Use a queue to determine your next state in the state machine, and the event structure can then enqueue states based on user interaction without making the entire state machine wait for an event to occur.
Plus, your queue gives you a fantastic way to synchronize your quitting. Just have your stop event release the queue (and force destroy) and your dequeue in the state machine will error and return your default case.
09-11-2008 02:20 PM
JLV--
Thanks for your post. I am wondering about the queue, though. It seems redundant to me since each event structure owns a queue that LV uses to store events. When an event occurs, LV places a copy of the event into each queue registered for that event. The queue is there implicitly. Try running the example I gave you with execution highlighting turned on and click [s1..s4] like crazy and you will see that the clicks have all been buffered up since it continues to exectute until all events have been handled.
Regarding my state machine, I think that is irrelavant as it pertains to event structures and event handling. The point is that my existing code (not the example but my application) already has the distributed event handlers and they run in different states. The example shows that having more than one event structure is perfectly acceptable as long as the events are dynamically registered as shown. If I were to have two ESs both acting on s4: Mouse Down, they would race and lock up the front panel. If I have two ESs both acting on <s4>: Mouse Down but not concurrently registered, there is no interference and the designer is free to utilize as many ESs as needed to process the events. It seems that dynamic registration is the key to the multiple ESs.
kc64
09-11-2008 02:33 PM