LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple event handlers in state machine

Apologies if my post is not the clearest, I am returning to LabVIEW after many years, and proper terminology is failing me..

 

I have created a very simple state machine from the template. I modified the 2 provided buttons to be start and stop. The start button starts a random number generator that updates an indicator, the stop button stops it. The stop button can be used either while waiting and doing nothing, or while running. Therefore my state machine has 2 event handlers, the main one in the "wait" state and then a second one in the "running" state. I know that the architecture is a little weird, but this code is a minimal working example of a more complicated issue I am facing with my real code. The example provided doesn't do anything when stop is pressed while in the wait state, but the real program would need to do something.

 

Initial problem (Main1.vi): the code works, but the state button event is registered twice when pressed inside the running state, first by the event handler inside the Running state, and then again in the Wait state. I guess this happens because the event is not "cleared", but I am welcoming a better explanation, or a way to avoid it

 

Attempt at a solution (Main2.vi): I tried fixing the problem using the boolean variable in the data structure. The idea was that the Stop button in the running case would set it, so that when the second event handler triggered I would check it, and effectively do nothing if the variable was set, to prevent catching the stop button twice. This fundamentally works, but it seems a klutzy solution.

 

Common problem to both VIs: when the stop button is pushed while in the "wait" state, the VI freezes and no longer recognizes any button press. I can't figure out why! As far as I can tell if I push the stop button while in wait mode I just stay in wait mode and nothing should happen. Why does it freeze?

 

I would welcome any explanation about why the VIs are behaving the way they do, but I am also hoping for suggestions on how to improve the architecture in general. I am aware of the queued message handler architecture, but it seems a tremendous overkill for what I'm trying to do here. I have attached the project with the 2 VIs.

 

Thank you so much.

0 Kudos
Message 1 of 12
(362 Views)

I (and a lot of other people here) don't have LV2025 and therefore can't look at your code.

Backsave it to LV 2021.

0 Kudos
Message 2 of 12
(329 Views)

Every event will always try to run in every event structure it's located in, no matter if that event structure doesn't seem to be "running" at the time.  If it's on a block diagram of a VI that is running, then every event in its list of events that occurs is an event it will try to execute when it does get to the point where that event structure is "running".

 

The most common way to avoid this is to just use one event structure, running in a separate loop from the rest of your state machine.  In the various event cases, instead of executing code inside them, you instead just send a message to your state machine that it can interpret.  The most common way to do this is with a queue.  If you search for "producer-consumer" in LabVIEW you will likely find many examples of this.

 

The general rule for event structures is to just use one per VI.  If you feel that you need more than one, and know what you are doing, then the specific rule is not to use the same event in multiple event structures unless you REALLY know what you are doing.

 

I made this post quite a while back which gets into more details about events, it might help as a reference:

https://forums.ni.com/t5/LabVIEW/Struggling-with-Event-Structures/m-p/4086346/highlight/true#M117617...

0 Kudos
Message 3 of 12
(328 Views)

(cannot look at your code, please save for 2020 or below)

 

  • A latch action button resets once the terminal executes. This means the terminal belongs in its event case and not somewhere outside.
  • Use the timeout event for the random generation. Keep the timeout in a shift register an change the value between finite and infinite (-1) based on the buttons. Don't use inner loops inside event cases. The outer loop can do it all.
0 Kudos
Message 4 of 12
(311 Views)

Here's probably all the functionality you need for this. (LabVIEW 2020).

 

 

 

0 Kudos
Message 5 of 12
(280 Views)

Yes, a static event is registered and waiting in all event structures. This is why it's recommended to only use 1. A workaround is to use a dynamic event registration to the control-ref in those states and then unregister it afterwards. 

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 6 of 12
(235 Views)

In general, an event structure should be ready* and in the dataflow at all times. In your example 1, you have two event structures for the same control on two different cases of a case structure, which guarantees that only one of then can execute. Both will register the event basically at the same time and both will lock the panel until they complete, but a maximum of one can complete, gumming up the gears. One of them has the terminal, so of that one executed, the button resets. if the other one executes, the button does not reset.

 

*Ready to execute an event means

  • no lengthy (or even interactive code) inside event cases.
  • Don't hide event structures in case structures or sequence frames that prevent them from being reached.
  • Except for certain dialog style subVIs, event structures need to be in a while loop so they are ready again after an event executes.
0 Kudos
Message 7 of 12
(217 Views)

I was not aware about version issues. I tried saving my project for version 20.0, I hope it worked.

0 Kudos
Message 8 of 12
(199 Views)

Nope...

NopeCapture.PNG

 

But your post topic says it all: There should never be multiple event handlers in a state machine.  

 

Use an Event Driven State Machine (EDSM) if that's what you want. Don't put multiple event structures inside a simple state machine.

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 9 of 12
(188 Views)

@vitto2 wrote:

I was not aware about version issues. I tried saving my project for version 20.0, I hope it worked.


Once you do a "save for previous" on the top-level VI,  the down-saved VI and all its down-converted dependencies will be in a similarly named folder next to the original. it will not touch your originals. Zip up that folder and attach.

 

(I sometimes even use that menu to save to the existing version in order to get a clean collection of all needed dependencies 😄 )

0 Kudos
Message 10 of 12
(173 Views)