03-13-2025 07:37 AM
Hello Everyone!
Greetings for the day!
I am implementing a LabVIEW state machine with 7–8 different cases. I need the code to stop running immediately when I press the stop button on the UI.
I have tried different approaches:
Event Structure in a Separate While Loop: I placed an event structure in a separate while loop to detect the stop button press and wired it to the stop case in the main VI. However, this caused the UI to freeze, preventing navigation after pressing the stop button.
Using Local Variables in Each Case: I created a button with local variables in each case, using a select function to navigate to the next case if stop is false; otherwise, it switches to the stop case to terminate execution. However, this method did not work effectively.
Since my code is large and contains a lot of data, I am not sharing it here. Please suggest a reliable way to immediately stop execution when the stop button is pressed.
Waiting for your reply:)
03-13-2025 07:46 AM
Hi Varshini,
@VarshiniPasumamula wrote:
I am implementing a LabVIEW state machine with 7–8 different cases.
Since my code is large and contains a lot of data, I am not sharing it here.
A VI with a statemachine of 8 cases/states usually isn't considered "large"…
@VarshiniPasumamula wrote:
I have tried different approaches:
Event Structure in a Separate While Loop: I placed an event structure in a separate while loop to detect the stop button press and wired it to the stop case in the main VI. However, this caused the UI to freeze, preventing navigation after pressing the stop button.
Using Local Variables in Each Case: I created a button with local variables in each case, using a select function to navigate to the next case if stop is false; otherwise, it switches to the stop case to terminate execution. However, this method did not work effectively.
03-13-2025 07:59 AM
It is also sounding like you are doing too much in each state. The loop of a state machine should iterate fairly quickly. If you want to go by the rules of the CLD, the loop should iterate every 50ms. A state can state it should be called again the next iteration. This will allow you to check for any stop condition (stop button, emergency trips, etc.) at the end of each iteration and call the Stop state if you need to shut down.
03-13-2025 09:40 AM
@crossrulz wrote:
It is also sounding like you are doing too much in each state. The loop of a state machine should iterate fairly quickly. If you want to go by the rules of the CLD, the loop should iterate every 50ms. A state can state it should be called again the next iteration. This will allow you to check for any stop condition (stop button, emergency trips, etc.) at the end of each iteration and call the Stop state if you need to shut down.
So to elaborate a bit about this, consider that if you use a for loop to go through testing different channels of something, for instance, and each test takes ten seconds and you have ten tests, if you press the Stop button at the beginning of the first test and the Stop state gets queued, it won't execute the Stop state until the code loops around - about 100 seconds. If you take a little time to think about it, you can instead code to have a test case where a counter starts at zero, you perform a single test (test[counter]), increment the counter, then call the test state again. That way the code loops with every test, giving the Stop state a chance to run if the Stop button was pressed and your maximum wait time is one test (10 seconds).
03-13-2025 10:31 AM - edited 03-13-2025 10:33 AM
@VarshiniPasumamula wrote:
Since my code is large and contains a lot of data, I am not sharing it here. Please suggest a reliable way to immediately stop execution when the stop button is pressed.
"Data" is not "code" and your vague description keeps everyone guessing. We can still tell that your code has serious architectural and dataflow issues and we really (really!) can only give targeted advice one you attach a simplified version of your VI.
03-13-2025 12:05 PM
Like everyone else says, without seeing your code, I can't give advice that's super detailed
I can tell you how I handled a similar problem once though.
One solution is as mentioned before to make your states run faster by having the state be the loop instead of contained loops, but that doesn't always work, especially if there's subVIs involved. So I came up with 2 alternates.
The first deals with loops. I added a conditional pass-through on any While or For loop's "Stop" or "Continue" terminal. The passthrough VI was like this:
Internally it can use any signal you want to send, whether that's a Notifier, a FGV, a global variable, or something else. Just add it to every loop:
For loops just have to add a right-click "Conditional terminal" since they don't start with one.
The second was that if there were any "Wait" VIs of any kind, I replaced them with waits that stopped when they got a user event to stop early, and never started if it had already fired. The contents of the wait VI would be something like this:
The other cases ("True" when the stop had already happened, and the "Timeout" event) were also empty. Note that the registration happens before the global stop check, otherwise there is a small chance of a race condition.