LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Data Acquisition: Multiple Producer Loops and Queues

Solved!
Go to solution

Hello,

 

I have a couple questions about producer/consumer loops with multiple producers and multiple queues since there seems to be a lot of conflicting information. 

 

Attached is a zip file containing the main VI (FAV-1 Flight Testing Data Recorder_serial_v5) and accompanying subVI's.

 

Here are some questions I have specifically about the main VI:

 

  1. From my research it seems like it is best practice to stop the producer loops with a button and let the consumer loop continue processing data until the queues are empty. Two problems with this:
    1. The program throws Error 1 when I press the Stop button, which is interesting because the queues should not be released until after the consumer loop has finished.
    2. With this line of thinking, the end condition of the consumer loop should be if the stop button is pushed and all the queues are empty. However, when I use the Get Queue Status VI, the number of elements in the queue is always zero. Any insight into what I might be doing wrong here?
  2. I’d like to be able to write the serial data to a separate file when the flag data button is pressed (just like I do with the DAQ data), so I tried placing another Write Serial Data vi in a loop nested within the consumer loop, but that was affecting the data processing already happening in the loop. Any thoughts on what architecture might be best for accomplishing that? Do I need to put a Wait in there somewhere?
  3. Smaller issue item, but now that I’m using a local variable for the stop button, the button doesn’t default back to false after I push it. In a similar vein, the boolean indicator from the Write to Measurement File VI for whether the data is being written to a file (Saving Data) doesn’t default back to false after the program ends. Is there something more elegant than implementing a flat sequence structure and wiring a false to those indicators in the frame before the program ends?

 

Thanks for your patience and help. 

 

0 Kudos
Message 1 of 7
(4,267 Views)

LV2018 is not mainstream yet.  You'll probably get more people looking at your code if you backsave to a previous version.

aputman
------------------
Heads up! NI has moved LabVIEW to a mandatory SaaS subscription policy, along with a big price increase. Make your voice heard.
0 Kudos
Message 2 of 7
(4,241 Views)

Hi Aputman,

 

I didn't realize - thanks for letting me know. Attached are the VI's in LabVIEW 2017.

 

 

0 Kudos
Message 3 of 7
(4,238 Views)

There is a lot going on here. I am not sure that this is the best way to implement the producer consumer pattern. The "consumer" that you have here is processing the data and writing to file, and it is also doing a VISA call and writing to file. One of the basic concepts to keep in mind with parallel loops generally is the separation of concerns.

 

It sort of makes sense that you are doing data acquisition in separate loops. Why are you not doing the VISA communication in it's own loop? If there is some sort of synchronization issue, you may be able to use one of the synchronization types (notifiers, queues, semaphores) to accomplish this.

 

As for stopping issue, there are a number of reasons for that behavior as well. By reading the stop value from a local variable, all the loops stop whenever they finishing executing the most recent loop iteration. This is something close to a race condition. In most cases, the "consumer" loop is probably finishing execution and ending first when the stop button is pressed, which is then closing the queues before the "producer" loops are done. Once they are closed, the "producer" loops no longer have a valid reference to the queue and will error. In the current setup of the software, you need to at least check in the consumer to see if all the producers have stopped (with a flag maybe?) before ending. As for the "unpressing" of the stop button, it needs to be set to some form of latching behavior

 

Hope this helps.

0 Kudos
Message 4 of 7
(4,230 Views)
Solution
Accepted by topic author sdol16

THINK DATAFLOW!!!!

 

Is there a reason you need 3 different producer loops?  What happens when one loop produces data on its queue faster than the other two loops?  I don't know how likely this is but I could see this happening if your running system experiences a slowdown.  If you actually want to implement the "Stop when queue empty" feature, you may run into issues.  Since you have 3 dequeue operations with no timeout in the same loop, each iteration of the consumer loop is dependent on data being available in all 3 queues.  If one of those queues has fewer elements than the others, the consumer loop will never end.  I think you would be better off combining the read functions into a single loop, cluster the data from each instrument together and add it to a single queue. 

 

The stop button is all wrong.  Again, think dataflow.  As soon as you start this program, the code is going to read the value of the stop button and update the local variable.  And then it will not be checked when you actually want to stop the program. If you are not going to use an event structure, you need to come up with something different for stopping the loops.  One suggestion is to add an empty value to the queue.  In the consumer, check to see if the dequeued value is empty and if so, exit the loop and release the queue.

 

I modified some of your code to give you a few ideas. 

 

Since your producer loops are running relatively slow, you may want to add the VISA code into the same combined loop, if the serial data is related to the TC/strain/accel data.  You just need to be aware of timing since serial is a slow protocol.  Currently your producer loops are running one iteration per second (samples and sample rate are the same).  In order to avoid buffer overflow on the DAQmx devices, your serial connection needs to be able to run at a similar rate. 

aputman
------------------
Heads up! NI has moved LabVIEW to a mandatory SaaS subscription policy, along with a big price increase. Make your voice heard.
0 Kudos
Message 5 of 7
(4,213 Views)

@User002 wrote:

The "consumer" that you have here is processing the data and writing to file, and it is also doing a VISA call and writing to file.


Consumer loop is not doing a VISA call. It is reading data from the serial queue and writing it to a file, same for the DAQmx data.  However, if this serial data is not related to the DAQmx data in any way, I think that the serial data should have it's own consumer loop or the dequeue function should have a timeout value so as not to hold up the DAQmx consumer loop.  If the data is related to the DAQmx data and the timings all work out (see my previous post), I think the producers should be combined and all of the data fed into a single queue. 

aputman
------------------
Heads up! NI has moved LabVIEW to a mandatory SaaS subscription policy, along with a big price increase. Make your voice heard.
0 Kudos
Message 6 of 7
(4,205 Views)

Aputman,

 

I cannot thank you enough! Your input was so helpful. I implemented your suggested changes and added some new functionality. The program now functions exactly as anticipated (files attached for anyone interested).

 

Changes made were:

- Bundling the 3 DAQmx Read tasks into one producer loop and feeding the data into one queue while leaving the serial read in its own producer loop

- Placing the serial write in its own consumer loop

- Wiring a stop button to the end conditions of the producer loops. The last item to be added onto a queue is a signal to end the queue (empty waveform data for the DAQmx tasks and the string "empty" for the serial read). These "signals" are used to stop the consumer loop.  

 

 

0 Kudos
Message 7 of 7
(4,191 Views)