LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

state machine with event structures that share a control

Solved!
Go to solution

This simulates a state machine system I have that will share a common "Quit" button that will perform the closing steps when the "Quit" button is pressed, regardless of which state it is in.

 

I am trying to have this toggle between loop1 and loop2 with each press of the "step" button.  Right now is blows right through "loop2" as it responds to the same "step" event triggered in "loop1", even though the event is already spent, and I even purge all the events after each event trigger (which shows 0 events purged anyway).

 

I got this to work when I registered the "step" button as a user event and passed this user event into the event structure via the Dynamic Event terminal. Unfortunately, the larger system this is simulating has a large number of user controls I bundled into a user event register so I am unable to try that route.

 

Is there a better way to set this up?

0 Kudos
Message 1 of 48
(2,071 Views)

It would probably be better that the QUIT control have only one event structure associated with it, and clicking on it would generate commands to shut each state machine down.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
Message 2 of 48
(2,006 Views)

You really need to reconsider your architecture. When you were talking about multiple loops I assumed that you were talking parallel loops. You really need to get rid of the nested loops. 

 

In any event, have you read the Caveats and Recommendations when Using Events in LabVIEW? You should not have two event structures in the same loop. Best practices generally has only one event handler in a program. 

 

My guess is that you've oversimplified your example program. Is there any way that you can share share the actual program? This would be helpful to suggest the most appropriate architecture changes. The architecture that you have in this example is unsustainable and not very scalable to larger applications.

0 Kudos
Message 3 of 48
(1,998 Views)

I did share the VI, it is in the OP. It is a simple state machine with an event structure in each state.

0 Kudos
Message 4 of 48
(1,996 Views)

Look at the JKI State Machine, down load it from VIPM.

 

Process your event then go into any other needed states. See how it is set up.

0 Kudos
Message 5 of 48
(1,994 Views)

@jgvarner57 wrote:

I did share the VI, it is in the OP. It is a simple state machine with an event structure in each state.


You said that the vi that you shared is a simulation (I take that to mean stripped down version) of a larger project. In any event this is NOT a state machine. You should not have loops within the loop. I suspect that there is a reason that you believe that you need to do this in your larger application - but without seeing that code it is hard to advise you on how to better structure your code. The main thing, though, is that you don't need the nested loops. I did a quick restructuring of your example to show you how this can be accomplished (see attached). I also got rid of the local variables.

Message 6 of 48
(1,984 Views)

Unfortunately I am using LabVIEW 2013 so I can't open your example. I am unsure what you mean by 'nested loops'. There is the main 'while loop' for the state machine that contains the case statement, and each case (state) has a single event structure that is inside its own 'while loop', which is the very definition of a 'state machine' in LabVIEW. In this cut down version, both states operate pretty much the same way, so it is not a perfect example, but the 'step' button should switch between states, and the quit button should exit either state immediately. What I am seeing is that when I press the 'step' button, that triggers the static event in the first state's event structure, exiting that state's loop. What I am finding is that when it enters into the other state, that static event still seems to be active causing the second state to exit as well and return to the first state, which then goes back into waiting. I have no idea why that 'event' is still present when the first state exits and the other state starts. That event should have been cleared by the triggering in the first state.

 

I know placing the 'step' terminal in its static event structure pane causes that structure to 'read' the control value and reset the control. Since I can't place the terminal in the second state as well, it apparently does not act the same way as the first state. I can't find an alternate way of placing the terminal in the other state as well, not even with a property node. I am not sure what the correct approach is here.

 

I did find, however, that I can register multiple differing events by clustering them, and then I can use dynamic events instead of static ones for better effect, so I may have answered my own question.

0 Kudos
Message 7 of 48
(1,951 Views)

Hi jgvarner,

 


@jgvarner57 wrote:

I am unsure what you mean by 'nested loops'. There is the main 'while loop' for the state machine that contains the case statement, and each case (state) has a single event structure that is inside its own 'while loop', which is the very definition of a 'state machine' in LabVIEW.


Nope!

 

A statemachine is a while loop with a case structure inside. There are no more while loops hidden inside the cases, and there should be only one event structure in the VI.

I guess this is what was expressed as "reconsider your code architecture"…

 

You really should rethink your code design. You really only need just one event structure and you don't need to hide loops within cases within a loop! (Did you read the LabVIEW help on event structures?)

 

What's the point of having a 50ms timeout event and a step valuechange event which both go the the same next state?

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 8 of 48
(1,946 Views)

@jgvarner57 wrote:

Unfortunately I am using LabVIEW 2013 so I can't open your example.


I apologize. I had saved the file to LabVIEW 2013 but mistakenly uploaded the wrong file. I have attached the 2013 version here.

 


@jgvarner57 wrote:

I am unsure what you mean by 'nested loops'. There is the main 'while loop' for the state machine that contains the case statement, and each case (state) has a single event structure that is inside its own 'while loop', which is the very definition of a 'state machine' in LabVIEW.


As GerdW has already said this is NOT the definition of a state machine. A state machine only has one while loop, and most definitely should not have multiple event structures.

 


@jgvarner57 wrote:

 In this cut down version, both states operate pretty much the same way, so it is not a perfect example, but the 'step' button should switch between states, and the quit button should exit either state immediately. What I am seeing is that when I press the 'step' button, that triggers the static event in the first state's event structure, exiting that state's loop. What I am finding is that when it enters into the other state, that static event still seems to be active causing the second state to exit as well and return to the first state, which then goes back into waiting. I have no idea why that 'event' is still present when the first state exits and the other state starts. That event should have been cleared by the triggering in the first state.

 


Think Dataflow. One of the inputs to an event structure is the event. The event structure will receive that input even if the code never gets to that event structure. When you get to that event structure it will then handle the event. Did you read the Caveats and Recommendations when Using Events in LabVIEW that I referred to earlier? 

 


@jgvarner57 wrote:

 

I did find, however, that I can register multiple differing events by clustering them, and then I can use dynamic events instead of static ones for better effect, so I may have answered my own question.


No, this is NOT the solution. This is just a way to hid programming practices that will cause problems in the future. Use a proper state machine architecture - you do not need your while loops with separate event structures inside your state machine. That outer while loop is sufficient, and a single event structure is sufficient. If your real code has complexity that makes a simple state machine unwieldy then perhaps you should consider a different architecture.

 

 

 

0 Kudos
Message 9 of 48
(1,932 Views)

I thank everyone for their help. This is a state machine, it is just a more complicated one. This is representing my larger application (which I can't share as it is proprietary) which has a 'setup state', a 'test state', and a 'quit state' where there is a lot of interaction on all three states, thus the need for multiple event structures. I have made a simple model of this that uses dynamic events that are shared in both state's event structures as well as static events that are unique to each state event structure and it works great. I have the 50ms timeouts because if I didn't the string would not get updated with the current state. I had to use "switched when pressed" mechanical action for the controls and handle them with property nodes, but the automatic handling of "latched when released" was not very elegant, and quite unpredictable, when it came to the states of the controls.

0 Kudos
Message 10 of 48
(1,924 Views)