Jump to content

JKI State Machine Events Front Panel Not Responsive


Recommended Posts

Hello,

 

I have done a few applications with the JKI State Machine, however I can never find a way to get into the "", "Idle" state in order to scan for Events.

 

I tried passing various strings such as "", Idle or use an intermediary case event. Also tried modifying the Timeout on the event case.

 

There's already an Event Case inside of JKI SM, so why would we need to add a another loop in order to control it as a Producer-Consumer for the front Panel to be responsive?

I don't think the implementation of the Producer-Consumer on http://forums.jki.net/topic/1347-jki-state-machine-producer-consumer-loop/ would work since it does requires detecting an event.

The only way I can think on how a P-C would work, it would require adding a "Add State(s) to Queue" between the "Parse State Queue" and the main case structure, where the data inserted would come from some kind of shared variable between the Procuder loop and the Consumer loop. Then you would still need to clear that variable and manage the new states to be added only on a change of the variable after it is added and cleared.

 

How can we force the scan for Events when we want with the standard JKI SM loop?

 

The only way that I see the JKI Events being useful is on single clicking applications, where the actions on the front panel always end up clearing the Queue. The while loop would only be used to keep the application active.

 

The only workaround that I found is to add all local variables within the states that would break the sequence if modified. Which is bad because you will need to track every interface item manually.

 

 

 

Here is an example:

LoK6YwW.png

(Not sure if the image is working as they are blocked where I work so I added it also to attached files)

 

This State loops on itself until an action is done to stop the loop, such as toggling the Read DMM or stopping the VI (I shouldn't even need to track those...). As you can see the issue remains that the front panel remains non responsive if I modify anything that is not one of those 2 buttons. I have tried forcing the Idle state through a Timeout case which sends "Idle" to the JKI SM.

 

Thanks,

Link to comment

Back when I used to “loop†states in a JKI template in this way, I would just call “idle†if I wanted to give an Event a change to be handled.  Often, I would modify the Timeout case such that the timeout could be specified in the “idle†command.   So my “DMM_Read†state would post:

 

idle >>100

DMM_Read

 

Does calling “idle†not work for you?

 

— James

 

BTW, I would currently recommend creating the ability to fire a “delayed User Event†at the Event Structure.  So “DMM_Read would send a User Event, delayed by 100 ms, containing the command “DMM_Readâ€.  The advantage of this is that any number of “loops†can be occurring in the JKI statemachine at the same time, with independent cycle times, and with all Events being unblocked.

Link to comment

For me I don't ever add an "Idle" to the Add States.  It just goes there after it is done doing what I asked it to do.  So you go to the Macro Initialization.  It does the states you tell it to, and then when it's done it goes to Idle, where you may have a timeout.  In the timeout it might go to another Macro to do stuff, and after all of the states I add are done it goes back to Idle.  It does this because when there are no more states to pull out, it passes out an empty string, so you should go to the "" case.

 

Drop down the JKI template and run it.  If you press the OK button or close the window it should react to your request by going to the Macro Exit case.  It does this because it was in the idle case polling the event structure.  You could add you own "Idle" to the states but I have never had a need for that, it will just go there when I'm done.

 

And going to the idle case doesn't need to wipe away your string queue.  If you go to the "Idle" case then perform an event with a button press, you can still use the Add States to add more.  But in my software, since I never add and "Idle" case, to the states to go to, I will only go to the Idle case if all state have been processed.

Link to comment

Adding calls to the "Idle" state is an easy way to allow a long process to run without hanging the UI (and without launching an actor).

Oh that's a great idea, and a case I haven't really thought of because I generally have had another actor doing the actual work, and the state machine is just the UI, but there are plenty of times the quick and dirty is to have it be in one state machine.

Link to comment

Thanks, I found why my states were never going into the idle state while still doing everything else that I request. I tend to use the "States In Front" too much in my software. So it always does what I request and skip the idle states queuing them at the end.

 

You use it too little; one should ALWAYS use “States in Frontâ€, never at back.   Enqueue the “idle†at front.  Don’t think of it as a queue, think of it as a call stack.

Adding calls to the "Idle" state is an easy way to allow a long process to run without hanging the UI (and without launching an actor).

 

But note that there are better and more flexible ways to do this.  Another example is to have a separate loop fire “Do XYZ†User Events at the JKI machine.  One can have multiple such loops with independent periods, and the UI remains instantly responsive, even if the periods are long.  

Link to comment

You use it too little; one should ALWAYS use “States in Frontâ€, never at back.   Enqueue the “idle†at front.  Don’t think of it as a queue, think of it as a call stack.

I don't completely agree with your Always statement.  If JKI didn't want us to be able to enqueue at the end then they shouldn't have included that feature.  They obviously saw a need, or their users saw the need for it.

 

Oh and jcarmody said without launching an actor.

Link to comment

You use it too little; one should ALWAYS use “States in Frontâ€, never at back.   Enqueue the “idle†at front.  Don’t think of it as a queue, think of it as a call stack.

 

But note that there are better and more flexible ways to do this.  Another example is to have a separate loop fire “Do XYZ†User Events at the JKI machine.  One can have multiple such loops with independent periods, and the UI remains instantly responsive, even if the periods are long.  

 

With the flexibility of the JKI State Machine and the fact that it already has the Event Case integrated into the main loop, the extra loop for User Events (Producer-Consumer implementation) can be somewhat avoided if the code runs without much of a delay. I would like to see some way that the JKI State Machine's Event Case could be activated to behave as a Producer-Consumer without having an additional loop with a queuing system.

Link to comment

If JKI didn't want us to be able to enqueue at the end then they shouldn't have included that feature.  They obviously saw a need, or their users saw the need for it.

 

With the JKI one has a single stack-like, last-in-first-out, method but TWO queue-like, first-in-first-out, methods: States on back, and an Event queue.  The former has priority over the latter, but one can mess with that by adding “idle†states at various places.  Having two very different methods of doing the same thing is complicating without creating meaningful additional capability.   Reducing things a single event queue, with a subVI-like stack handling of each event is actually much simpler.  

 

The easiest way to do this is just the replace “States on back†with a User Event message to oneself, but with a little sophistication one can create reusable subVIs that either do a delayed User Event or set up a “trigger source†of periodic events.  Here’s an example of a JKI with two timed triggers:

Periodic Triggers with JKI statemachine.zip

  • Like 2
Link to comment

The easiest way to do this is just the replace “States on back†with a User Event message to oneself, but with a little sophistication one can create reusable subVIs that either do a delayed User Event or set up a “trigger source†of periodic events.  Here’s an example of a JKI with two timed triggers:

attachicon.gifPeriodic Triggers with JKI statemachine.zip

 

Very impressed with the simplicity and elegance of that timer solution.

 

<possible thread hijack>

Along the same lines....do you guys ever use the DAQ Events functionality within the JKI state machine in the same manner?  eg using the DAQmx events along with a daqmx read in the event structure similar to LabVIEW example:

 

\examples\DAQmx\Analog Input\Voltage (with Events) - Continuous Input.vi

 

Or are the downsides to reading daq at high speed in an event loop outweigh the potential benefits?

 

post-549-0-71469700-1434569873.png

Link to comment

That's an interesting approach, with several pros and cons over the typical poll the timeout case and check method.  A few comments, you aren't closing lots of various references, and I figure you probably just threw this together.  You have a VI reference, notifier, and user event for each trigger that aren't being closed, and you aren't unregistering for the user events.  Some of these take care of themselves when the VI stops but I don't think they all do.  Also I'm not sure you are aware of this or not, but you can create an array of user events, and register for all of them at once as long as the data type of the user events are the same.  This might help make things scale easier because you could be making timing sources in a for loop, and to add another source you just need to run the for loop another iteration.  Overall I like the concept.

 

I keep going back and forth, but I do not think I have a need for adding things to the end, and front.  If I go off and do some things, and I want to go to Idle periodically to see if there is new events to handle (like a trigger) my first thought is I would want to add Idle states to the front, then add the states added in the event structure at the end, unless it is a critical thing like shutdown.  But this isn't true because when I add Idle cases is is probably going to be in a Macro all at once, so it doesn't matter if it is at the end or front.  And as for going to Idle periodically, I wouldn't want to go there until I was done doing what I'm doing anyway, and then the event structure will act like a queue and my events will be waiting for me when I'm done doing what I'm doing.

 

In the past I've seen where the states were always added to the end, except for an exit which was added to the front.  But again with this design you're not usually going to go check to see if you should exit, until you're done going to your states, so it didn't really matter.

 

Oh and I've used the DAQmx events.  Just like all state machines where you have work, and UI stuff in one loop you need to be mindful that things should happen quickly, so the UI appears responsive, and you don't delay the work going on.  Like you probably wouldn't want logging in that same loop because an event is generated for taking DAQ, then you take the DAQ log it, do limit check, database, or whatever, and this whole time your UI is unresponsive.

Link to comment

Along the same lines....do you guys ever use the DAQ Events functionality within the JKI state machine in the same manner?  eg using the DAQmx events along with a daqmx read in the event structure similar to LabVIEW example:

 

 

I’ve used DAQmx Events multiple times.  Also IMAQdx “Frame Done†Events.

 

 

Or are the downsides to reading daq at high speed in an event loop outweigh the potential benefits?

 

 

 

I wouldn’t worry about the Event Loop overhead.   

Link to comment

A few comments, you aren't closing lots of various references, and I figure you probably just threw this together.  

Yes, I just threw this together as an example.  It would need some work to be a robust reusable component, though it does properly shut itself down and close all references as used in the example.  The actual code that this example is modeled on is a component called “Metronome" built into Messenger Library**.

 

The point, though, is that one can build such a reusable, easy-to-use component, and use it simplify use of the JKI template.

 

** See the Messenger Library example "Example of Recurring Event Methodsâ€.  It shows both this “trigger†method and an alternative “delayed message to self†method.

This is the template I now use, BTW, which will be in the next version of Messenger Library:

 

post-18176-0-29374200-1434578751.png

 

It uses JKI-like strings, but as a “follow-on action†stack, where there is no ability to call “idleâ€.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.