11-11-2013 11:25 AM
Hi...
I'm trying to update a basic program to handle control events more efficiently. The program needs to perform the following functions on start button press:
1) Import data file and parse instrument settings from multiple (X) rows
2) Perform loop with case for each row changing input settings, the read test equipment, and store data in new output data file
I've looked at producer/consumer example and the continuous measurement and logging example, but not sure if either (or none) of the following two options is the best way to handle the looping from the file...
A) Use events to trigger looping for all input cases within a consumer (I've had a problem with this due to not being able to terminate the loop within the consumer with an abort button)
B) Make the consumer only a single data acquisition and load loop inputs as queues and generate output queues to be handled by another parallel logging loop
Any advice?
11-11-2013
11:49 AM
- last edited on
08-13-2024
10:33 AM
by
Content Cleaner
Have you looked at this?
Not knowing much about what you are doing, I would guess the second picture on the page is a better fit.
Then, inside the case structure of the consumer you can place a for loop to process each line. If you want to abort the for loop, just add the conditional element to the for loop and tie it to the abort button. If abort just needs to stop the for loop, that is all you need to do. However, if abort needs to clean up other processes, you can tie it (or a local variable of it) to the conditional stop and have the producer loop enqueue another task that "cleans up" after the aborted for loop.
11-11-2013 02:29 PM
Thanks for the feedback. I did take a look at the whitepaper. I would like better error handling as you suggested instead of just terminating the for loop. Could you clarify your last sentence. Are you suggesting to take the button out of the event handler and leave a local variable in it's place?
I was thinking that having parallel loops would allow for independing acquisition and logging/display of data but wasn't sure how to handle the looped nature of the data flow. It would seem like the single FOR loop option would force me into a sequential function of acquire then log/display. Any suggestions or other references on how to queue up the data?
11-12-2013 08:59 AM
Hi bripple,
Based on what you've described above, a Producer/Consumer Design Pattern (Events) might work. There is a template for this design pattern that ships with LabVIEW which you can access by going to File > New > VI > From Template > Frameworks > Design Patterns. When the user clicks the start button on your front panel, you can queue up a command that will trigger your consumer loop to read the file and loop over each instrument setting. Within that loop, you should be able to queue up additional events corresponding to each instrument setting and reading.
In terms of error handling, you can conditionally stop a loop if you detect an error. If your user decides to push a button on the front panel to stop the entire process, you can use Enqueue Element at Opposite End to put a stop command at the beginning of the queue. When your consumer loop encounters this event, it can flush the queue and do any cleanup it needs to perform.
One additional thing to be cautious of is that queues can only handle one data type. Because of that, you may also want to consider a Queued Message Handler design pattern. This design pattern allows you to send both a command and data along with that command. I think that would be ideally situated for you since you could send a "Read Instrument" command along with the data for its settings. You can access this design pattern from within LabVIEW as well. If you have LabVIEW 2012 or LabVIEW 2013, see these instructions. The things I've said above also hold true for the Queued Message Handler as well.
Let me know if you have any questions or if this is helpful.
Regards,
11-12-2013 09:17 AM
Matthew-B...
Thanks for your input. I see the utility of the queued message handler, but I'm trying to figure out the best way to pass the data to the consumer loop. Would it be better practice/more efficient to pass the consumer a string of queues where each queue corresponds to a test case (each row of my input file corresponding to certain settings) or to send the consumer the entire array of test cases (as data with the QMH) and let the consumer loop through the array of test cases?
It seems like the first option may be the best for error handling and not getting stuck in a for loop, but I'm assuming there would be an issue if I queue up 1,000 test cases into the QMH?
11-13-2013 09:33 AM
Hi bripple,
I'm not sure what you mean by string of queues, but it would probably be more efficient to send your consumer loop the entire array of test cases. Inside the consumer loop, I would traverse the array and queue up the each row in order. If you run into an error condition or the user stops the VI on the front panel, you can queue up a stop message at the beginning of the queue rather than the end so this stop event is the next event to be run. In the stop message handler, you can flush the queue of the remaining events and safely close your application.
Regards,
11-13-2013 03:59 PM
It sounds like you could use a state machine in your consumer. A couple of years back Norm Kirchner did a presentation at NIWeek with a new model for a state machine. He called this the Top Level Baseline which he also posted on LAVAG. We had Norm come out to our Chicago User group last year and he brought an updated version there. I have attached it. We have been using it lately for our projects and once you get used to it it is extremely powerful.