I am currently working with two instruments; an Agilent E3646A and an NI 6212 BNC. My objective is to have the 6212 to be continuously taking measurements according to predefined parameters while the E3646A's parameters can be continuously updated. This simple instrument combination is intended to help me learn the necessarry achitecture; continuous measurement, dynamic output control, and more instruments will be added in the future.
I've previously posted on a similar, but more complicated, setup (http://forums.ni.com/t5/Instrument-Control-GPIB-Serial/Split-second-lag-when-controlling-two-instrum... and was advised to try the Producer Consumer Architecture. I've found relevant literature on the site (http://www.ni.com/white-paper/3023/en/, https://decibel.ni.com/content/docs/DOC-2431), searched the forums and constructed my own VI. While my first attempt at a Producer Consumer Architecture has resolved some of the issues I was having when I first posted on the subject, however, new issues have arisen with regard to reading and stopping the VI.
I am currently able to run the VI and update the device parameters. Previously, I would get a freeze while the instrument was being updated and could not toggle parameters until it was done. This has been resolved although the read only updates when a parameter has been updated although it is outside of the event structure. Furthermore the Stop button does not work in any context. I've also gotten occasional errors regarding the Deqeue Element but the bulk of the trouble is Error -200279 "Attempted to read samples that are no longer available" at DAQmx Read. I realize that there is a problem in my Producer Loop but haven't been able to figure out how to resolve it.
This is my first attempt at a Producer Consumer Architecture and already I can see that it is a powerful tool. I read as much as I could and looked at the relevant examples but expected to have some issues in the beginning. Would really appreciate any advice so I can take full advantage of the architecture.
Hope to hear from you,
Solved! Go to Solution.
The read vi is only updating once a parameter changes most likely because they are in the same loop. Because your queue vi is waiting for data to cue, this would cause the program to wait before continuing to execute the loop. You can confirm this by running your vi with highlight execution enabled.
The error at your DAQmx Read VI can be caused by a number of things. One main cause is that your buffer is getting full and then overwriting data that has not been read yet. I would suggest trying to increase your buffer size.
When you hit the stop button as your vi is, it only stops your producer loop. The consumer loop it not affected by this. If you want to stop both at the same time, create a local variable for the stop button and wire that to your consumer loop stop button.
Hope this helps!
Thank you for the response and the suggestions.
I created the Local Variable for the Stop Button and moved the original into its own Event Case. It is now able to stop VI execution although I get Warning -1073676294 which I understand to be the buffer issue. The warning says that this was incurred on VISA Open for the E3646A's Initialize VI which is outside both loops, however, which I don't understand.
I tried increasing buffer size by decreasing the Number of Samples as per suggestions I found on NI forum threads. I've brought it down as low as 1 but the graph still only updates when an Event occurs and I keep getting the same buffer error. You suggested that the problem could be that they are in the same loop; does this mean that the DAQmx read should be outside both Producer and Consumer Loops or moved into the Consumer Loop? I found a couple of links ( http://forums.ni.com/t5/LabVIEW/Producer-Consumer-Design-Pattern-DAQmx-Event-Structure/td-p/2744450 , http://forums.ni.com/t5/LabVIEW/Producer-Consumer-Architecture/td-p/494883 -first response) on dealing with an Event Structure that my own VI is based. Alternatively, I found another link ( http://forums.ni.com/t5/LabVIEW/Producer-Consumer-Design-Pattern-DAQmx-Event-Structure/td-p/2744450 - first response) on a DAQmx Read with an Event Structure that places the graph in the Consumer Loop.
The core of my purpose in setting up this Producer Consumer Architecture is so that I could read continuously while the instrument parameters are updated dynamically so it's very important that I understand how this works. I am particularly struggling with how the Event Structure is controlling the While Loop's Execution.
Hope to hear form you,
You are going to overflow that buffer unless events are generated faster than "Sample rate/number of samples". Period. nothing simpler.
You don't need a local to stop your loops.
Try something like this attachment. I simpley moved the event structure into its own dedicated loop since it had no relationship with the DAQ at all.
The DAQ loop will stop just fine when you destroy the task and destrying the queue stops the power supply (Sending the default values of the queue to the supply control) SO, ADD a cluster of "Safe shutdown" setting to the "Bundle" and wire it to the middle (Prototype) terminal.
Thanks so much for your advice! I adjusted the VI as instructed and got everything working just as it should!
As a followup, I am curious about how this would be different if I wanted to monitor the parameters of the continuous read. This is not an issue for me now but might come up in the future. In such a case, I would imagine the configuration for the DAQmx would go into the event structure but where would the Read subVI sit?
The DAQ loop would expand to a queued message handler, QMH, since you may need to control the task state to apply some settings. The event loop would need a second queue to pass user information to the DAQ QMH.
Good Question! and an interesting way to bring up the Continuous Measurement and Logging (DAQmx) Project template. Feel free to check it out
Thank you for the continued advice and support. I had one more question related to this endeavor which I hope will be the final one.
If I attempt to grow this VI to include multiple instruments, would this require a new Producer Loop? That is, if I wanted to add another instrument, would there have to be a new Producer Loop that dequeued into the consumer or would the new instrument's parameters be added to the original Producer Loop? Finally, if it would be the latter, would there be two seperate queues or one big queue with both instruments' parameters?
I've been fiddling around with this addition and getting lots of bugs. Would appreciate some advice so I can understand the architecture.
Hope to hear from you,
I glad you asked because you might just be missing a key point. In the ve we started with we finally realized good performance by adding a simple DAQ Acquisition and display loop to a basic Producer - Consumer (Events) design pattern and what we have here is a simplified Contineous measeurment and logging (DAQmx) project
Scaling up is very possible but we need to understand the parts and their responsibilityes before we stick things in willy-nilly.
The Producer loop is an event structure and is responsible for taking the users actions and controlling the message handleing loop by passing in commands and data. You would very seldom want multiple producer loops there is only 1 user interface to interact with! Just add event cases to send new commands to a consumer loop.
It is often desireable to have several consumer loops each responsible for taking actions that are related to each other. And thats where we want to make our decision on wether to add another queue or add more states to the existing consumer. If the new actions are not related to the existing functions its a good idea to leave the working code alone and spawn a new consumer.
Thank you for your patience. I am trying to understand the foundation of the architecture so forgive me for the persistant clarifications.
The single queue makes sense to me because I was worried multiple queues would slow down the execution of the Producer Loop. That being said the fear I had is that this queue would update each Consumer Loop even if only one instrument was being updated somewhat defeating the purpose. I did some research and found this Community page on Multiple Queues and Clusters ( https://decibel.ni.com/content/docs/DOC-25591 ).
The way I understand it is that the single queue with multiple insturments should be implemented with Case Structures (State Machines) inside each Consumer Loop that is triggered by a control in the Producer Loop. That is, parameters for all queue elements are updated when there is a change, regardless of instrument, and the Event Case specifies Consumer Loop is activated. If this is in fact the proper way to go about this, my question is what happens to the other, unchanged parameters since they are then still in the queue?
Hope to hear from you,
Don't worry about bogging down the producer loop in that design pattern. It responds to user interaction and users are far slower than enqueueing functions.
And why would each event enqueue to each consumer? if the processes that the consumers control are truely unrelated than Event a can queue to the consumer that needs to do Action when A changes without interupting whatever other consumers are doing with data they don't know what to do with anyway. "Exit" might be enqueued to multiple consumers but most events will not.
The example you linked did not combine the queues themselves. it merely passed all queues on one wire in a cluster and those queues remain as seperate data elements And, required an appropriate unbundle to get the desired queue reference.
And don't worry about asking good questions. The ones you ask might be just a bit basic but I had to learn design patterns once myself. When you DO learn them you can make this LabVIEW thinggy look easy. It only looks easy once you master it.