08-26-2020 07:22 AM - edited 08-26-2020 07:26 AM
I think we might have gotten off track a little from the original topic, when we went down the road of the producer-consumer structure, which can be a help, I think. What I'm trying to do is this:
Right now, my main loop (consumer if we go by this example) reads all commands and executes them. When the WAIT command comes through, it pauses the entire main loop until the wait time has finished executing, because the loop that produces the delay is nested in a case statement inside my main loop. I only want it to pause the commands so that the rest of the functions (timed) in my main loop can finish executing.
This is slightly new territory for me. I'm unsure of which way to go with this.
08-26-2020 07:25 AM
Ok... Probably your biggest issue is that you are trying to dequeue elements in multiple loops. You can enqueue from however many places you want, but you need to dequeue from a single loop. The basic structure of a producer-consumer state machine is a while loop with an event structure on top (producer) and a while loop with a case structure at the bottom (consumer).
Your error wires are doing absolutely nothing the way you have them wired, so you may as well get rid of them. And honestly, if the only thing they are wired to is the queue functions, then there will essentially never be an error present anyway.
Now your case structures... I think you have a fundamental misunderstanding about how they work. The two bottom loops both have 4 nested case structures, but the 3 inner ones only have one case each!
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 07:38 AM
The case structures are set up that way as an example of how some of my commands are structured to pass multiple variables into the cases. I currently have hundreds of variables to deal with in the case statements. This was just a crude example.
If I dequeue from the main/consumer loop, when the WAIT function is called and executed, it will stall my whole loop. This is the original question I had - how do I use a wait function to allow my main loop to continue without pausing my main/consumer loop? I'm only trying to pause the execution of the command following the WAIT command. The rest of my main/consumer loop has other timed cases that need to finish execution, and IO to a DAQ that cannot be paused or stalled.
As for error... suggestion there too?
08-26-2020 08:28 AM
Basically, remove your 'producer loop' and Place a while loop around your event strucuture and you have a producer/consumer (though your 'Main loop' is actually the consumer)
Reading files and queueing up commands and such should happen in the event loop. (unless it's slow process in which case it should just be queued up and performed in the consumer loop)
08-26-2020 08:30 AM
I did forget that you said this is just an example and your full program is doing a lot more. Without the full program, or at least an image of it, it's hard to see the full picture and therefore hard to help. I'll do some fixing of your example VI when I'm able to.
As far as the error wires go, if you have an error wire going into a loop it NEEDS to use a shift register to pass errors from one iteration to the next.
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 08:52 AM - edited 08-26-2020 08:56 AM
@FireFist-Redhawk wrote:
I did forget that you said this is just an example and your full program is doing a lot more. Without the full program, or at least an image of it, it's hard to see the full picture and therefore hard to help. I'll do some fixing of your example VI when I'm able to.
As far as the error wires go, if you have an error wire going into a loop it NEEDS to use a shift register to pass errors from one iteration to the next.
Aah, I see. I'll fix the error issues, Thanks.
I wish I could send the program, but I can't - I'm restricted. It would make my life easier, but I won't have a job if I do. I was allowed this much. It's all I have to work with.
08-26-2020 08:54 AM - edited 08-26-2020 08:56 AM
@Yamaeda wrote:
Basically, remove your 'producer loop' and Place a while loop around your event strucuture and you have a producer/consumer (though your 'Main loop' is actually the consumer)
Reading files and queueing up commands and such should happen in the event loop. (unless it's slow process in which case it should just be queued up and performed in the consumer loop)
Scroll back through the comments, that version was tried already. The event structure continues to request a file after the loop completes its first iteration and does not execute the commands prior to. Can you provide an example of what you're suggesting?
08-26-2020 09:21 AM
@jedi.engineer wrote:
If I dequeue from the main/consumer loop, when the WAIT function is called and executed, it will stall my whole loop.
You need to put your WAIT function only where you need to wait. It would appear that you need a loop solely devoted to handling the commands sequentially. Pass the commands to that loop via queue. Put the wait in that loop. The loop that is passing the commands (your main/producer loop) will continue running. What you did was not producer consumer. Please take a look at the Producer/Consumer Design Pattern (Events). You do this by creating a new VI from template. This is a good starting point to give you and understanding of a Producer/Consumer. Since we can't see your application it is hard to advise, but you may need a third loop that handles your IO and DAQ.
08-26-2020 09:38 AM - edited 08-26-2020 09:39 AM
@johntrich1971 wrote:
@jedi.engineer wrote:
If I dequeue from the main/consumer loop, when the WAIT function is called and executed, it will stall my whole loop.
You need to put your WAIT function only where you need to wait. It would appear that you need a loop solely devoted to handling the commands sequentially. Pass the commands to that loop via queue. Put the wait in that loop. The loop that is passing the commands (your main/producer loop) will continue running. What you did was not producer consumer. Please take a look at the Producer/Consumer Design Pattern (Events). You do this by creating a new VI from template. This is a good starting point to give you and understanding of a Producer/Consumer. Since we can't see your application it is hard to advise, but you may need a third loop that handles your IO and DAQ.
ok, so if I understand you correctly, this is what is needed:
I've tried this as well. Attached to this message. What happens is, or rather what I'm seeing while using the highlighted execution feature, whether using the queue or just passing data, the first loop halts ALL data from being passed out of it until that loop finishes. Lend me your eyes, tell me where it went wrong, and if you see a solution, please let me know.
Do I possibly need a second queue? Would this help?
08-26-2020 10:09 AM - edited 08-26-2020 10:10 AM
@jedi.engineer wrote:
@johntrich1971 wrote:
@jedi.engineer wrote:
If I dequeue from the main/consumer loop, when the WAIT function is called and executed, it will stall my whole loop.
You need to put your WAIT function only where you need to wait. It would appear that you need a loop solely devoted to handling the commands sequentially. Pass the commands to that loop via queue. Put the wait in that loop. The loop that is passing the commands (your main/producer loop) will continue running. What you did was not producer consumer. Please take a look at the Producer/Consumer Design Pattern (Events). You do this by creating a new VI from template. This is a good starting point to give you and understanding of a Producer/Consumer. Since we can't see your application it is hard to advise, but you may need a third loop that handles your IO and DAQ.
ok, so if I understand you correctly, this is what is needed:
- obtain queue - connect to event handler. Probably should have an initializer linked to the event structure.
- when the structure is triggered, it loads the script file into the queue and halts.
- the queue is read by a loop looking for the WAIT command. Upon finding it, commands to the main/consumer loop are halted or a generic variable indicating a wait function is called is parsed/passed.
- when WAIT is no detected, the data to the main loop is passed straight through.
I've tried this as well. Attached to this message. What happens is, or rather what I'm seeing while using the highlighted execution feature, whether using the queue or just passing data, the first loop halts ALL data from being passed out of it until that loop finishes. Lend me your eyes, tell me where it went wrong, and if you see a solution, please let me know.
Do I possibly need a second queue? Would this help?
No. This is exactly opposite of what I said. Move your wait out of the loop that's sending the commands and into the loop that is receiving the commands. Also, the examples that you posted make absolutely no sense. The loop that you're calling MAIN WHILE LOOP will not begin until your other loop has completed. Why are you adding all the complexity to this? Send the command directly to your bottom loop - no need for the middle loop.
Please do look at the training resources available at the top of this forum.