08-25-2020 06:21 AM - edited 08-25-2020 06:58 AM
I'm unable to share my whole program, sorry, but I can give relevant snippets. I have an event handler that reads in a script file at a push of a button. This feeds data to a multiple embedded case statement.
One of the commands is a "WAIT" command that is supposed to stall the reading in of the next command based on the number of seconds specified by the command (ie WAIT 30), but it's nested inside the case statement, and when it runs, it stalls my main while loop until the timer expires.
Is there another implementation of this stall timer that I could use to pause the execution of the next script command that won't stall my main while loop?
Edit - I threw together a full event showing how it's connected - the main goal is to pause the execution of the next script command but not the main loop.
Solved! Go to Solution.
08-25-2020 07:02 AM
I typically use an FGV for timers, it's about the only thing I use an FGV for anymore. When you get one of these waits, write to it, then read it continuously and when the timer has elapsed, you can process the next command.
Hard to tell exactly what your architecture is because there are no While Loops shown, but judging from the first picture, your queue isn't structured correctly. This is what a proper producer-consumer design pattern should look like. Getting a proper architecture down will also help you.
Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.
08-25-2020 07:02 AM
Change your structure to a state machine.
08-25-2020 07:29 AM
Sorry - somewhat new to labview - about 1 year experience. Not familiar with the acronym FGV - maybe under a different name?
So I posted an edit - if I made that my "producer" outside my main while loop, that could serve as a separate state? Basically, the program I started with (somewhat inherited) was all able to be run under one while loop, I had to add the scripting part so I figured it could run under the same loop. I attached a vi - is this what you are implying/indicating should be done?
08-25-2020 07:59 AM
Functional Global Variable. More information here. Save your example VI in 2017 and upload?
Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.
08-25-2020 09:21 AM
Look at the Producer/Consumer template. You're pretty close already, but the dequeue should be in a loop of its own.
You basically only need to move the Obtain Queue outside the loop, and use the reference in both loops and you're there.
08-26-2020 06:06 AM - edited 08-26-2020 06:09 AM
Ran into an issue. When run in parallel, I need the event handler outside the loop or else it will ask to open a file as soon as the loop starts it's second iteration. The issue lies with the queue. If they're run in parallel, producer runs command 1, consumer runs command 2, producer runs command 3, etc. If I try to serialize it, the data never makes it to the second loop until the first loop has exhausted commands. What I need is for the one loop to pass commands through to the second loop and only pause when the "WAIT" command is read (for the duration of the wait). Files attached, including test file. When I run them (Execution highlighted) it appears to be executing commands correctly, as previously explained. Just need to get the stall function running.
With respect to the example of the producer-consumer that was previously posted, I'm not really too familiar with event handlers, is that the proper solution for passing the commands through to the consumer? In my case, the consumer loop will need to function normally (user inputs) when the text file is not being executed...
08-26-2020 06:42 AM - edited 08-26-2020 06:45 AM
I only have 2017 so I can't open your VI that is saved in 2019.Upload the VI in 2017.
@jedi.engineer wrote:
The issue lies with the queue. If they're run in parallel, producer runs command 1, consumer runs command 2, producer runs command 3, etc.
The producer should have as little code in it as possible. It only responds to user button presses and other actions, and enqueues states in response to those actions, to be handled by the consumer loop. It shouldn't "run" any commands.
@jedi.engineer wrote:
With respect to the example of the producer-consumer that was previously posted, I'm not really too familiar with event handlers, is that the proper solution for passing the commands through to the consumer? In my case, the consumer loop will need to function normally (user inputs) when the text file is not being executed...
Yes, that is the proper solution. You enqueue commands in the producer loop with Enqueue Element and Enqueue Element at Opposite End, then dequeue them in the consumer loop as they come in with Dequeue Element.
This is nice because if there is nothing in the queue, the consumer loop just sits there, and if there are no user actions to capture, the producer loop just sits there. No iteration of either loop happens when it doesn't need to. This is of course not the case if you have timeouts enabled.
Saying "Thanks that fixed it" or "Thanks that answers my question" and not giving a Kudo or Marked Solution, is like telling your waiter they did a great job and not leaving a tip. Please, tip your waiters.
08-26-2020 06:59 AM - edited 08-26-2020 07:00 AM
Thanks, the file is attached.
Again, unsure of how an event handler would help in this case. I have no timeouts in this code.
08-26-2020 07:08 AM
In your latest example you have one producer (the event structure which runs exactly once). You have a race condition as both of your loops are consuming data from the queue. Can you explain more what you're trying to accomplish? What you would normally do is have the producer loop react to UI events (event structure) and send any relevant information to the consumer loop. My thoughts are that in your case the information would be the serialized list of commands. If the command is Wait then the stall the Consumer loop (I would personally have a way to abort the wait if the times are long, perhaps as a Functional Global Variable which is sometimes also referred to as an Action Engine). The Producer loop would keep running and handle any user interactions.