07-20-2022 09:26 AM
So I would like to know the best way to stop multiple loops using channel wire without duplication of channel writer. I tried using for loop and it didn't quite work for me. Maybe I was using it the wrong way.
Notice on my block diagram, I have 4 loops.
Also, I noticed there is a delay in stopping the program when I press the stop button. I kind of understand why I have the delay. I believe it's because I have a loop inside of a loop.
Do you think channel wire is a good way to do what I am doing? If not, what would be your suggestion? I think using local variable can be even worse than the channel wire. Let me know what you think.
I attached my code below.
Solved! Go to Solution.
07-20-2022 09:47 AM - edited 07-20-2022 10:37 AM
Well examples like this are hard because they are oversimplified and not realistic to how an actual application would work.
In my application I use several Channel Wires usually something like:
My general architecture is a bunch of independent State Machines and each State machine has a "Stop" state that I can call from the main control loop through the Messenger Channels.
Maybe this picture will help explain what I am saying...
Messenger channels can have several writers but only one reader so...
07-20-2022 10:57 AM
It's the double loops that's causing the delay. You're filling elements into the buffer extremely fast. To give some labels:
Your "A" reader empties the buffer as fast as it can get read. Adding an indicator to the upper While loop's i terminal shows it runs about 300,000 times in a couple seconds.
Same with C- it reads all of the elements about as fast as you can put them in. B, however, is dependent on C's dataflow. B can only read from the queue *once*, then C's loop runs until C's loop terminates. C's loop terminates only after it's read all of its values. When you click Stop, each of the Streams puts an "I'm done" element at the end of their queue. This will stop C's loop, but B has only read one of the 300,000 elements, so B's loop only starts to remove elements in its queue after you stop putting elements into the queue.
If you take away C's loop, your program stops instantly.
It's hard to say how you "should" do it since this is clearly just a simplified example. What are you actually doing in your real application? It may be better to use a Tag stream rather than a High Speed stream. The Tag stream just tells you the latest value read, so it won't get caught in the whole queue.
07-20-2022 11:08 AM - edited 07-20-2022 11:10 AM
First problem:
Use a mechanical action of "latch when released", not "switch until released". It is easily possible to miss button presses, depending on the loop rate and when the button is pressed/released. (And if you use execution highlighting, things get even worse and very unrealistic. Nothing will event stop if you do a short press!)
Second problem:
Don't use convoluted architectures of loops within loops. In the unusual case where you have stacks of loops that all need to stop, all you need is to read the condition in the innermost loop, right?
07-20-2022 12:10 PM
There are three loops running the same sub vi, be careful it will make some problems if any buffers inside.
07-20-2022 01:51 PM - edited 07-20-2022 01:52 PM
@Weiping wrote:
There are three loops running the same sub vi, be careful it will make some problems if any buffers inside.
What does this have to do with the question? (... and there are actually four loops)
07-20-2022 03:06 PM
@GRCK5000 wrote:...I think using local variable can be even worse than the channel wire.
Why would a local variable be worse? The main problem is that you can no longer use latch mechanical action, meaning you need to somehow herd all the cats and make sure that the value resets only after all instances had a chance to read the stop command.
I think the main problem is that you are way overcomplicating your architecture. It is simply not a good idea to pile on new loops with every new feature you are trying to add. Keep the code lean and streamlined.
Instead of showing us convoluted code, explain what you are actually trying to achieve with all this. I am sure there are significantly better architectures that do everything better and with fewer complications.
07-20-2022 04:44 PM
@altenbach wrote:
@GRCK5000 wrote:...I think using local variable can be even worse than the channel wire.Why would a local variable be worse? The main problem is that you can no longer use latch mechanical action, meaning you need to somehow herd all the cats and make sure that the value resets only after all instances had a chance to read the stop command.
I think the main problem is that you are way overcomplicating your architecture. It is simply not a good idea to pile on new loops with every new feature you are trying to add. Keep the code lean and streamlined.
Instead of showing us convoluted code, explain what you are actually trying to achieve with all this. I am sure there are significantly better architectures that do everything better and with fewer complications.
IIRC, the OP's code are mostly hypothetical to learn LabVIEW from, so this might be the actual code.
07-25-2022 10:08 AM
What a great written explanation of the data flow! Thank you Berth!
07-25-2022 10:10 AM
Great advice as usual! Thanks Mr. Altenbach!