11-06-2013 10:00 PM
Hi,
I am trying to build a VI using Producer/Consumer architecture and trying to learn how to do it. I am measuring two types of data that must be used "simultaneously" to create output commands. The attached vi is a simplified version that I am using to try to understand how the data flows before I build my much larger more complex VI.
I will be collecting three values in an array from a DAQ sequence, and then one single value (also from another DAQ function) in another loop, so, the two loops are labelled THREE VALUES and ONE VALUE. The DAQ's run at different rates, so, that is the reason for the producer/consumer architecture. I want to take each of the three values, and pair it with the most recent one value, (hence the LOSSY ENQUEUE set to max size 1) and create a serial command to be output. (Actually, I would create 3 serial commands, one per value from the THREE loop.)
In the attached VI, I create an array of 3 values, but, I see only one of them during execution. I am trying to see all 4 values, but, I see only one of the THREE, and one of ONE. I think I should see 1, 23, 44, and 99, but, I see only 44 and 99. Where did 1 and 23 go? I want to be able to use (see) 1 and 23 in my consumer loop.
Thanks
11-06-2013 10:38 PM - edited 11-06-2013 10:40 PM
You have a race condition. You have 3 enqueues happening at nearly the same time. Chances are the other two are being tossed out of the lossy queue before the consumer loop has a chance to come around and read it. It's just pure chance as to which of the 3 make it through. And that the other producer loop is able to get its element in the queue is probably because it isn't so tightly synchronized with the loop trying to throw 3 items simultaneously into the 1 element queue.
I see you know about variants. But if you are trying to mix data types like you say in your message subject, then the queue itself should be of the variant datatype.
If you want all of the values to come through, why are you using lossy queues?
PS: Instead of ORing together the 3 error wires, you should just use the Merge Errors function.
11-07-2013 06:33 AM
Haveing a queue size of 1 and then making the enqueues lossy kind of defeats the point of the Producer/Consumer. What you have done here is more of the line of a Master/Slave. You pretty much just turned the queues into a notifier of some sorts. Don't limit the size of the queue and just use the standard Enqueue Element.
From your problem description, it sounds like you actually want to use 2 notifiers (one per DAQ function) to send the data to the processing loop. The notifier only keeps the latest value.
11-07-2013 07:10 AM
Thanks a lot.
Actually, I was advised by NI to use a producer/consumer architecture for the vi I am trying to build, but, they didn't explain how to capture all three of the values from the THREE loop, and the function won't allow me to connect the array directly to the lossy enqueue. The LOSSY enqueue was suggested because I want to capture the most recent value that the DAQ function returns. The DAQ is reading the voltage from 3 sensors, so, I actually want the most recent of each of the three sensors, or an array of 3 voltages. Is it possible to capture them using the LOSSY enqueue by converting them to something that the LOSSY enqueue will allow me to wire to it? And then, how do I get them out again and use those values?
Can you point me in the direction of how to educate myself about "notifiers"? I have not heard that term before.
Thanks,
Dave
11-07-2013 08:39 AM
11-07-2013 10:03 AM - edited 11-07-2013 10:06 AM
@apok wrote:
try this...
(OP NI did you a slight disservice stating Producer Consumer vice Master Slave pattern- you need a master slave pattern)
Close to right Apok, A problem. Two solutions possible:
1)The slowest notifier needs to be waited first and have the ignore previous boolean T (Not sure which is slowest) This "Slow Loop" then throttles the slave loop and the "Fast Loop's" notifier looses data between slow loop samples.
2) Wait the Fast loop's notifier first. and leave both notifiers ignore previous =F And, set the slow loop timeout to 0. This duplicates the slow loop value for each fast loop acquisition.