06-13-2012 04:47 PM
In a state machine, if a state contains a loop that would run for a few second, it would cause the state machine to become non-responsive for a few seconds. To alievate the problem, instead of using a loop in a state, the developer would elminate the loop and cause the program to enter/exit the state multiple of time. For example, if you want to use a for loop wth 10000 iternation, you would not choose a loop and cause the program to enter/exit the state 10000 times instead, so that the program would be more responsive. With the later method, the responsiveness goes up, but the complexity of the code goes up as well. Is the latter way the preferred way? If so, is there a way to keep the complexity to a minimum? Any thoughts?
06-13-2012 05:09 PM
The latter is preferred. As for the complexity, just create a reusable library or class.
Here is a timer that I wrote which has pause and resume.
http://forums.ni.com/t5/LabVIEW/statemachine-with-multiple-timer-possible/m-p/1837925#M628024
06-13-2012 05:09 PM
HI,
Doesn't seem to complex to cycle through the state. Depending on your code and needs, the program would "check controls/ do other things" outside the state, presumably inside the main loop that holds the case structure.
You would probably then decide to make all the "check controls / do other things" their own states, and you could continuously cycle through a series of states, one of them being the state you are interested in.
Not sure if this could be called preferred, but within the limits of simplicity it would be easy cycle through the state 1000 times, with checks, etc... Outside the state.
06-13-2012 05:12 PM
Another option is to have a third loop that manages this "state" and in your state machine you can just queue up a command to that loop to go run for "x" seconds. This of course causes added complexity and shutdown schemes, along with potentially being overkill, especially if you need to pass data to this loop that is already in your existing loop.
06-14-2012 08:37 AM
@jyang72211 wrote:
In a state machine, if a state contains a loop that would run for a few second, it would cause the state machine to become non-responsive for a few seconds. To alievate the problem, instead of using a loop in a state, the developer would elminate the loop and cause the program to enter/exit the state multiple of time. For example, if you want to use a for loop wth 10000 iternation, you would not choose a loop and cause the program to enter/exit the state 10000 times instead, so that the program would be more responsive. With the later method, the responsiveness goes up, but the complexity of the code goes up as well. Is the latter way the preferred way? If so, is there a way to keep the complexity to a minimum? Any thoughts?
DISCALIMER: I am a physicist and only program for a living so the "correct" approach is outside my area of expertise.
As I understand the State Chart Toolkit was developed to adhere to the UML standards which were developed the "right way".
If you are using the SCT it is the latter method that is natural.
So I think that is the correct answer.
But since I was never taught the "right way" I approach this in a different fashion in that the requirement "Loop must be abortable" should be applied to the lower loop so the logic should be checking if it was aborted. SO I write code to check for that condition inside the lower loop.
Choose your poison,
Ben
06-14-2012 10:08 AM
I think the right way boils down to a state machine that is responsive. There are various ways as to accomplish that. But in the end, you system should not get into a state where it will ignore outsides events such as an abort for long periods of time. As Ben mentioned you could do the check in the inner loop. My personal preference is to have the check outside and use the state machine itself to control execution.
06-14-2012 10:32 AM
For the abortable loop, the only thing that I can think of is using a local variable. Is there a better way?
06-14-2012 10:35 AM
@jyang72211 wrote:
For the abortable loop, the only thing that I can think of is using a local variable. Is there a better way?
If the loop is in the same VI as the control then the local would be fine.
The answer is a "depends" of course since the loop that we are trying to abort may be running on another machine somehwere.
Ben
06-14-2012 11:21 AM - edited 06-14-2012 11:24 AM
@jyang72211 wrote:
For the abortable loop, the only thing that I can think of is using a local variable. Is there a better way?
That is nice and simple. If you end up putting the loop in a subVI then you could use a global or a functional global.
See this micro-nugget. It describes one method of aborting loops using a functional global and also has some other goodies about wrappers, libraries and access scope.
[Edit: And the nice thing is that if the loop ends up being on a different machine in the future, you could modify the "abort" library to use some communications method and not have to modify any of the code that uses the library]
06-18-2012 07:22 PM
Nice.