03-25-2013 08:09 AM
Hello,
I'm developing a motion and DAQ program and I was wondering what would be a good architecture to develop it. The program requires a small user interface and will run some processes in parallel to perform motion actions, drive a sensor, acquire data and calculate/save results.
Although I'm fairly familiar with Labview basics and to some extend with more advanced concepts such as events, state machines and actor framework, I don't know how to select/develop a good architecture.
My first idea is to use an event driven UI + state machine. However, it is unclear to me if the UI should launch and communicate in some way with the statemachine or whether the statemachine should listen for certain UI events. Any ideas on this or alternatives?
There is no code yet, I just want to have a general idea of an architecture which would be suitable! Any advice is welcome!
Thanks,
Wouter
03-25-2013 09:28 AM
I would not recommend monitoring for user events in your state machine. Create a basic messaging protocol and let your state machine react to those messages.This architecture is more flexible and will allow you to re-use your processing in an automated application that does not have an UI.
03-25-2013 09:33 AM
I fully agree with Mark. You want your UI code in its own loop and send messages to your processing loops to update them. I like to go so far as to have the processing loops send user events in order to perform GUI updates.
03-25-2013 09:43 AM
Hello sir,
I made a quick example that maybe helps you on your way.
Keep in mind that there are many architectures possible and all of them have pros and cons.
You have not listed enough information to completely design a suitable architecture for your problem.
Some considerations for the example VI:
- Use Type Definitions for the State Variables Cluster and the State Selector enum
- You could use Functional Global Variables to communicate between loops but beware of race-conditions. Use the State Variable Cluster Typdef for this.
- Develop suitable error handling
- I used 250ms as the timeout value for the Event Structure. Take care that the State Machine returns to the Idle state regularly to execute the user events,
otherwise user events will have a delay. This is one of the cons of this architecture.
Hope i could help you with this example.
03-25-2013 09:46 AM
Dear Wouter,
I totally agree with the previous two replies. The only tihng I would add is to launch your driver(s) in separate processes by launching it/them asynchronously as Sub VIs:
The communication between the mutiple sections is still the same (Named Queue with a "State" [string] and "Data" [variant]) It does not add much complexity and it really helps to keeping the code neat and well divided as the application grows. I usually end up with 2-6 of those VIs running in parallel. Functional global usually do the trick to exchange larger chunks of data or share state information.
Olivier
03-25-2013 10:05 AM - edited 03-25-2013 10:09 AM
Thank you all for your replies.
I'll definitely try to seperate UI and statemachine. It's is not strictly necessary for my application but it seems to be a good habit! I will most likely use queues to send data to the statemachine.
The UI will require some updates (like status and graph) too. Is it best to place these objects to be updated in a seperate loop with its own queue?
Wouter
03-25-2013 10:19 AM
@WouterVleugels wrote:
The UI will require some updates (like status and graph) too. Is it best to place these objects to be updated in a seperate loop with its own queue?
Like I said, user events work great for UI updates. You can use the same event structure that you are using for updates from the user to update indicators.
03-25-2013 10:23 AM
The objects themselves, if they need to be accessed from multiple loops, should live in functional global VIs (un initialized shift regristers.)
As for handling the update of the UI, there are different ways to handle this but the easiest is to put a timeout on your "User Event" structure and update the UI when there is no event (Event Timeout case)!
Olivier
03-25-2013 10:30 AM
@crossrulz wrote:
@WouterVleugels wrote:
The UI will require some updates (like status and graph) too. Is it best to place these objects to be updated in a seperate loop with its own queue?
Like I said, user events work great for UI updates. You can use the same event structure that you are using for updates from the user to update indicators.
Ok, tnx again. I think this will be a good solution for me!
03-25-2013 10:31 AM
@OlivierL wrote:
The objects themselves, if they need to be accessed from multiple loops, should live in functional global VIs (un initialized shift regristers.)
As for handling the update of the UI, there are different ways to handle this but the easiest is to put a timeout on your "User Event" structure and update the UI when there is no event (Event Timeout case)!
Olivier
Actually the prefered approach would be to use user events to single the UI task to update the display. Using the timeout simply to update the UI defeats the purpose of using the events. It turns the UI from an event driven task to a polling task.