09-13-2013 08:53 AM
Hello,
For my current program I want to test devices. At the moment my code is the flat structure in the picture below.
Even tough some steps are relatively short (set power), some other steps are way to long (+5 hours) to keep in the current form (... cal and ... cal) (before the red circle). So even the fact that this program is great for testing/debugging if I give this to a operator they'll probably gona hate me or something.
So my question is: what is the best design pattern to convert this "blob" to a more usable form. (On a side-note: I know of NI teststand but a "full LabVIEW" solution is required.)
So far I looked at the queued message handler and the model view controller design patterns and the model view controller has at the moment the best chance of succeeding but I really would like to know if there are other/better design patterns to accomplish this task.
09-13-2013 09:28 AM
Hey,
For me this will depend on the number of individual tasks you want to complete, the time it takes them and their dependancies.
For example if you can only do one task at a time, and they are relatively quick (like the turn on power you mention, but not +5hrs you discuss) then convert your program into a state machine. They've been mentioned here a lot and are probably the most widely used/standard programming technique. If you aren't familiar with them this is the basics right here:
The snippet above shows a very simple version of the state machine - you can put the actions in different panes of the conditional state structure. There are lots of other ways to do this too - and a lot of things you should do (like add in an error handling page and similar). Using this you can put the 'red circle' part into different pages on the state machine and the user can select them as he needs to.
However if the tasks you are talking about take a long time but can be run asychonously then I'd suggest you use an event driven producer consumer loop (lots of literature on this too). In the consumer loop I'd dynamically start the sub-tasks in separate VIs (using the run asynchronous command (apologies for my spellings)) or something similar. This would allow the user to start the tasks and run a number of of the long ones in parallel without locking up the UI. If you go with this appraoch it will be important to track what parts of your code is running, check the status of the tasks and block the user from doing things which may be dangerous and so on (starting a new Task#1 when Task#1 is already running etc). Thereore user-events (to update your UI) will also be important.
This is a bit more advanced than the state machine;-)
I hope this helps - best of luck,
Dave
09-13-2013 09:29 AM
Oh...and in the VI snippet, the second enum in 'Task 1' page should be 'wait for input'....otherwise the code will repeate Task 1 again and again.....shoudl've debugged;-)
09-13-2013 09:45 AM
In addition to DeltaJ's advice, there is another advantage to a state machine: flexibility.
Which tasks are required every time the program is to be run, and which are optional, repeatable, and/or can be run out of your sequence shown? Specifically, are the time-consuming cal steps necessary every time, can they be eliminated, or is there a shorter procedure which can be used in their place after the first run-through with a device? If the data from them is required before going further, a QMH, P-C, or other 2-loop solution won't help you, you could set up the whole procedure with a state machine, just to make it more easily adaptable if/when your procedure changes. If the data is only required on the first run (or it won't change with a second cal) or if there is a shortcut procedure which can be taken after the first run, then the state machine can be forked to bypass those steps and/or include the shortcut in their place.
Cameron
09-16-2013 02:45 AM
Thanks for the replys so far.
Personnaly I am not a hudge fan of the state machine design patern. The resaon for this is that all the other states are hidden on the block diagram. (only 1 state is visible.)
The number of tasks that have to be started in paralel is limited to 3 1 for the UI, 1 for the UI handler and 1 for the test that is running.
However since this program has to be easy to maintain it would be great if I can load the test procedure from a file.
[stupid idea mode]
Since Dynamic dispatch and Start Asynchronous Call/Wait On Asynchronous Call are both powerfull functions inside LabVIEW. Is it a good idea to combine the 2 and to load the procedures from a file so everything is loaded/unloaded fully dynamic? Or will this result in a hudge mindf**k that is better avoided?
[/stupid idea mode]
For your enterainment I attached the 1st .... cal procedure from the 1st image. And Yes I know that I have to remove the "time delay" blocks from the block diagram. Asside grom the delay in these blocks the "wait 4 ... settle" also takes a long time to finish.