LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Parallel While Loops

Hi All.

 

In the project attached I am running 2 parallel while loops. The top one is reading data from the console (quiet fast) and the bottom one is taking a reading whenever the button is pressed. It works fine at the moment as the bottom loop isn't doing much but eventually will and will probably be a state machine within. So my question is, is it ok to run loops parallel like this, how is the resource allocated. If the bottom one gets more involved would that add delays to the console read on top. Does labview alternate between the two or are they really in parallel?

 

Also I am using one stop button to stop both loops but when I press it, it stops the top one and I still have to hit the abort button to stop completely. Is there a better way to do this.

And is it possible to replace the local variable with a wired connection. I tried wiring directly but dosn't work but variable works fine. Seems a bit odd.

 

Thanks,

 

Mark.

0 Kudos
Message 1 of 6
(5,278 Views)

I did not specifically look at your application but You can get very good performance using parallel loops. You can also write bad code and get poor performance. The key is to minimize unnecssary processing. Also be aware that using porperty nodes will cause tasks to switch to the UI thread which is the lowest priority thread and could cause perfomrance issues. I have written applications with four parallel loops within a single VI with many other background processes running which were spawned dynamically.

 

In terms of stopping both loops using a single button there are a few ways you can do this. One of the most basic is to use a local variable which the second loop reads. This variable will be set to True (to stop) when the first loop completes. thta way both loops will stop when the button is pressed. The first loop will check the value of the button. the local varibale in the second loop could be for the button itself. Just make your your mechanical action is set properly so the button is not cleared as soon as it is read. I also use queues with explicit stop message to stop parallel loops. You could also use notifiers or user events (if you are using event structures). You definitely want to avoid using the abort button since that is the equivilent of stopping your car by slamming into a brick wall. It works, but it isn't very nice.

 

I will try to acually take a look at your code if I get some time. I tried to look at your code but I don't have LV 2016 installed yet. Can you save it for 2015?



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 2 of 6
(5,260 Views)

"With Data Flow, you get Parallelism" (I just made that up).  LabVIEW's Data Flow paradigm means that two While loops with no inter-dependencies (the input of one doesn't depend on the output of the other) will (following the rules of Data Flow) run in parallel, with the Run-Time Engine doing its best to ensure that both loops get a "fair share" of the CPU.  When one loop includes an Event structure, something that "blocks" unless an Event fires, all of the CPU time goes to the other loop (unless it has some kind of "wait" inside it, such as a Timed Wait, or an I/O function "waiting for data").  There are Design Patterns that specifically take advantage of this -- look up Producer/Consumer (or make one yourself by starting LabVIEW, click File, New ... (the three dots are important!), and click From Template, Design Patterns, Producer/Consumer Design Pattern (Events).

 

The other thing to ask is if you know about State Machines, generally a good way to configure your Main Loop, particularly if you are doing sequential things like Initializing stuff (DAQmx), reading stuff (repetitively), stopping stuff, and Cleaning Up.

 

If that still makes sense, a way to combine the two nicely is with the Queued Message Handler.  The idea is that your State Machine becomes the Consumer of "State" messages, many of which it sends to itself (using a Queue, hence the "Queued" in the name).  A Message is a Cluster of two elements -- the State (in this case) and a Variant called "Data", often empty.  So you start things off by establishing the Message Queue, enqueuing "Initialize" (or whatever you want to call the first State), and sending the Queue into the Main Message Handler loop.  You dequeue it, unbundle the Message, and wire the State element to a Case Selector (to select the State).

 

Now here's where the fun comes.  Your Event Loop also sends Messages to the State Machine.  In particular, when a Control changes, you send the "Get Voltage" message (for example) and include the (new) Voltage as the "Data" part of the Message.  The QMH (that's the shorthand name for the Main Loop) will process this message, will know that there is "Voltage" in the Data, and can use it (or save it in a Shift Register for other States to use).

 

Best of all, you now have a "safe" Stop method.  Put the Stop Button in the Event Loop with a Value-change Event.  When this Event fires, send a "Stop" Message (you don't need to send any data) to the QMH.  The Event loop can "stop itself" by simply wiring Stop through the Event "wall" to the Stop indicator.  Meanwhile, the QMH can undertake whatever orderly steps you need to take (it might want, for example, to call for the Cleanup State next).

 

Bob Schor

Message 3 of 6
(5,247 Views)

Here is the 2015 version.

0 Kudos
Message 4 of 6
(5,221 Views)

First, you are using the wrong action for you stop button.  Don't use Switch Until Released.  If you don't hold it down long enough that both loops have a chance to read it, the loops may not stop.  Use Switch WHEN Released.

 

For your loop with the event structure, you can add an event for the value change of the stop button and wire that to the stop terminal of the loop.  Right now because you are using the local variable, it is probably false when the loop iteration begins.  Then the event structure waits for an event.  Even if you do something to fire an event, (the Get Voltage Value Change), the stop wire is still false even if you have since changed the button to true.  It won't get read again until the next iteration, but the loop won't end until the event structure executes because it is now waiting on another event to occur.  With your wrong mechanical action, you can never get this to work because you can't get the loop to iterate again until you press the Get Voltage button, but as soon as you do, the Stop button is no longer true (because you released it with the "Until Released" action.)

 

To Summarize:

1.  Change Stop button to Switch WHEN Released.

2.  Add event case for stop button value changed.  Wire that to the lower loop's stop terminal.

3.  You'll want to add a local variable that will reset the stop button back to falseat the beginning of the program before the loops begin if you restart, or better, after both loops have had a chance to finish at the end of the program.

Message 5 of 6
(5,209 Views)

Thnaks for the tips guys.

 

Smiley Happy

0 Kudos
Message 6 of 6
(5,106 Views)