LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How would you program a stop button into a state machine

Solved!
Go to solution

I have a basic state machine that will be used to perform automated test procedures. I have a stop button on the outside of the state machine that I want to use to end the current state, and move to a "shutdown" state that will turn off the equipment. I have some instances where I need to implement a wait period so that a function generator can complete it's programmed loop. I found an example where a for loop was used to split the wait period up so that a Boolean flag of some sort could be read during each loop to see if the stop button was pressed, but I'm finding that I can't get a signal passed the case structure. The only thing that works for me is to put the stop button inside the For loop, but this is not practical because I would have to have a stop button for each state, and I have a state machine for each test sequence that I need to automate, so I would end up with a lot of stop buttons. I basically just want one stop button on the main menu so that the testing can be interrupted at any point in the test.

 

I've attached an example below. This is just one attempt at me trying to get this to work.

0 Kudos
Message 1 of 14
(1,686 Views)

Better to Use Event Based State Machine and Handle the Stop Button using Event.

Use Elapsed Timer for Wait Instead of Constant Wait with For Loop and Poll for Stop Button until Time elapses

 

I don't see use of While Loop since you Connected Constant True to Stop the Loop (Which Runs only Once).

----------------------------------------------------------------------------------------------------------------
Palanivel Thiruvenkadam | பழனிவேல் திருவெங்கடம்
LabVIEW™ Champion |Certified LabVIEW™ Architect |Certified TestStand Developer

Kidlin's Law -If you can write the problem down clearly then the matter is half solved.
-----------------------------------------------------------------------------------------------------------------
0 Kudos
Message 2 of 14
(1,682 Views)

Have you learned about the Event Structure and Event Loops?  One common feature of Event Loops is their use in sitting quietly until you push a "Latch When Released" Boolean (those are the ones, like "Stop", that have a rectangular Icon), at which point they "wake up", read the (now True) value of the button, and then "unlatch" it so it goes back to "False").

 

If you put the Event structure into its own (parallel) loop "above" your State Machine Loop, you now need to get the "value" from the loop into the State Machine.  A common way to communicate between parallel loops is via a system that can "sneak data into and out of" structures such as Loops.  Several such structures are available in LabVIEW.  One is the Queue, another is the Asynchronous Channel Wire.  If you Google "LabVIEW Producer Consumer State Machine", you'll find a nice presentation by NI showing how an Event Structure that "produces" commands (like "Stop") can interact with a State Machine that "consumes" commands from the Producer (and also can generate commands to itself, like "Do This State Next").

 

Bob Schor

0 Kudos
Message 3 of 14
(1,673 Views)

Hello

 

I looked into the Producer-Consumer State Machine and it has definitely given me a lot of ideas, but I don't think it will work for my use case. It still seems that even using the Queue functions to pass a new state into the case structure would not work in interrupting a wait. Also, it looks like all of the states are taken care of be the user in the example shown. I would want the state machine to run automatically until the stop or pause buttons were pressed. 

 

You did say that queue can "sneak data into and out of" a state, but is that possible when a case is running with a wait?

 

 

thanks,

0 Kudos
Message 4 of 14
(1,649 Views)

@taylorblack wrote:

Hello

 

I looked into the Producer-Consumer State Machine and it has definitely given me a lot of ideas, but I don't think it will work for my use case. It still seems that even using the Queue functions to pass a new state into the case structure would not work in interrupting a wait. Also, it looks like all of the states are taken care of be the user in the example shown. I would want the state machine to run automatically until the stop or pause buttons were pressed. 

 

You did say that queue can "sneak data into and out of" a state, but is that possible when a case is running with a wait?


You cannot have a constant wait in any of the Program, You should have a Case where it will Poll for Particular Duration and Move to required State, During this Process it should Accept any events comes from UI/Queue.

----------------------------------------------------------------------------------------------------------------
Palanivel Thiruvenkadam | பழனிவேல் திருவெங்கடம்
LabVIEW™ Champion |Certified LabVIEW™ Architect |Certified TestStand Developer

Kidlin's Law -If you can write the problem down clearly then the matter is half solved.
-----------------------------------------------------------------------------------------------------------------
Message 5 of 14
(1,645 Views)
Solution
Accepted by topic author taylorblack

As @Palanivel says, you shouldn't have a conventional "Wait" inside a State of a State Machine.  So what do you do?  Make a "Wait" State.  You want a State that is "interruptable", but without "interrupts".  How about loading the number of seconds you want into Shift Register "Timer", and loading the Next State into Shift Register "Next State".  You now call the "Wait" State.  It decrements the Timer and puts it back into the Shift Register, calling itself as the Next State if the Timer is > 0, otherwise calling whatever was saved as "Next State".  This allows the Stop button to call the "Stop" State "asynchronously".  If the State Machine is running the "Wait" State, one second later it will exit, putting either "Wait" or "Next State" on the Queue, which will go behind the call to the Stop State.  Now that you are processing the Stop State, you can, if you want, flush the Queue, getting rid of "extra" "Wait" or "Next State" requests put on by a running "Wait" State (at the cost of having a possible 1 second delay before handling the Stop Request.

 

And if you need a faster response, have the "Wait" timer be 10 msec, or even 1 msec -- it will take very little time (particularly if you use "Wait on Next Multiple") to execute.

 

Bob Schor

Message 6 of 14
(1,628 Views)

That is genius. Thank you for the idea. I'll try to get that to work.

0 Kudos
Message 7 of 14
(1,613 Views)

So I was able to make a wait state and pass the initial value of the timer to it. I then run the timer for a short time, subtract that value from the initial value, and then pass that value through the shift register, which goes back to the wait state if the value isn't zero. The problem that I am having now is that my stop button value change does not seem to be getting past the while loop. I can see the value being checked at the start of the case (after the wait state is called again) but it still pulls a zero from the while loop tunnel and into the case structure. 

0 Kudos
Message 8 of 14
(1,574 Views)

You are doing something wrong, which probably means you don't quite understand what you are (or should be) doing.  If you posted your code (in LabVIEW 2021 or earlier, by using "Save for Previous Version"), we could open it, clearly see what you are doing, and (probably) quickly see (and advise you) how to "fix it".  Assuming you're using a version of LabVIEW at least as new as LabVIEW 2016, I'd walk you through how to do this using Asynchronous Channel Wires (which I find more "intuitive" and "mnemonic" than Queues).  But since I don't know what you are doing, I can't help you "fix it" ...

 

Bob Schor

0 Kudos
Message 9 of 14
(1,560 Views)

Here it is. Keep in mind that this is something that I threw together as a proof of concept. I did end up getting it working with a local variable tied to the stop button. I have a feeling that it isn't the preferred way to do it though.

0 Kudos
Message 10 of 14
(1,532 Views)