04-03-2019 08:27 AM
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:
Thanks for your patience and help.
Solved! Go to Solution.
04-03-2019 10:27 AM
LV2018 is not mainstream yet. You'll probably get more people looking at your code if you backsave to a previous version.
04-03-2019 10:40 AM
Hi Aputman,
I didn't realize - thanks for letting me know. Attached are the VI's in LabVIEW 2017.
04-03-2019 11:24 AM
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.
04-03-2019 02:38 PM
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.
04-03-2019 02:51 PM
@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.
04-03-2019 06:38 PM - edited 04-03-2019 06:39 PM
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.