LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Architecture advice please for separation of UI and DAQ loops

Hi,
 
I am trying to write a program for a simple test sequencer that sequences fairly simple I/O : temperature and pumps and uses an Agilent 3970 to collect data for logging, graphing and state change determination. Most of my core data acquisition functionality is working in the single while loop I have attached. (I have not included the Agilent drivers in the attachment).
 
For good User Interface responsiveness, I understand that I should separate my code into parallel loops for say UI; sequencing logic; data acquisition; logging; pump control; temperature control. Most of these loops will have small amounts (and occasional) of data passing between them, say commands to turn a pump on or a few sequences steps or a fairly infrequently updated status.
 
However, I am having a brain fault with separation of the UI (graphing) and data acquisition and logging functions. It seems to me that if I separate the data acquisition from the graphing and logging. I will have to send multiple copies of the data to these loops as well as the state controller for end of state determination and that I will have to communicate all the User Input configuration settings down to the data acquisition loop for initialization. Is this interpretation correct? If so, is flattening the data to a string the "best" way to transfer between custom user events (mechanism I am using for loop separation).
 
Thanks in advance for any wisdom,
Kathryn
 
0 Kudos
Message 1 of 6
(2,938 Views)
Kathryn,

I usually use an architecture with three parallel loops: GUI, DAQ, and Processing. Each loop is a state machine. The GUI uses an event structure for handling user inputs and updates indicators, if needed, in the timeout case. DAQ acuires inputs and send outputs to external instruments and devices. Processing does everything else: Data analysis, formatting and reduction, saving to files, parameter error checking, mode determination (Is everything ready to permit Run?...), and so on.

I use two pairs of queues for inter-loop communication. GUI-Process and Process-DAQ. The GUI loop does not talk directly to the DAQ loop. One queue in each pair carries commands, queries, requests along with parameters while the other takes reponses in the opposite direction. If you are using a recent version of LV, you can pass the data via queues without flattening (older queues only handled strings). I often use a cluster with an enum, a numeric, and a string for the command queue and an enum, numeric, and string or array, depending on the data types, for the response queue. The enums are typedefs which define the nature of the data being passed. Some commands such as Pause or Halt need no parameters. Setup DAQ might require sampling rate, number of channels, and number of samples per scan to be sent. Responses include Status, Error, Stopped, as well as Data. The Data response might include Channel number (or Name), the data, and a timestamp.

Some people use the destruction of the queue and the error generated by attempting to read it as a "Stop the parallel loop" command. I prefer an explicit "Halt" command and a status response "Stopped" to let the program know that orderly shutdown has occurred.

Lynn
0 Kudos
Message 2 of 6
(2,914 Views)
I think the attachment didn't stick the firest time.
0 Kudos
Message 3 of 6
(2,907 Views)
Kathryn,

Typically the best way to communicate between loops in a producer/consumer architecture such as the one you are describing is to use queues.  One loop, such as the UI loop with an event structure inside captures user interaction and places appropriate command messages/data on a queue.  This is the producer loop.  Another loop - the consumer - runs in parallel pulling commands off the queue and taking the appropriate action.

You mentioned that you are using custom user events to transfer data between loops.  My interpretation of how you would do this requires having an event structure in each loop -- this is a big no-no as far writing robust code goes.  Typically, I would caution you against using event structures to handle anything other than user interaction and then only use one event structure to handle all events.

Regards,

Simon H
Applications Engineer
National Instruments
http://www.ni.com/support/
0 Kudos
Message 4 of 6
(2,869 Views)

Dear Lyn,

Thank you very much for sharing your solution with me - and the hint "not to flatten". I'd appreciate it if you could clarify a couple of points:

 >Setup DAQ might require sampling rate, number of channels, and number of samples per scan to be sent....The Data response might include Channel number (or Name), the data, and a timestamp

If GUI and DAQ do not directly communciate, am I correct in assuming that the above setups come from the GUI via your process loop and then to the DAQ. Similarly if you have a graph on the front panel, I assume the data comes from the DAQ via the process loop to the GUI?

If this is indeed the case I guess I am on the right track and just need to shuffle data among the loops.

Regards,
Kathryn

0 Kudos
Message 5 of 6
(2,849 Views)
Kathryn,

Yes, I think you have the general idea of the approach I use. These are guidelines, not hard and fast rules.

Setup parameters and returned data do pass through the Process loop on their way from GUI to DAQ and back. If there is a lot of traffic between GUI and DAQ and the Process loop does not do anything except repeat it, a direct link may be used. However, if the process loop calculates the sample rate or the number of samples from a preset user selection, then the direct link is not as useful. (Think about a user selecting from an enum with items like: DC Offset, Frequency Response, Distortion at 1 kHz. The user selects a test from a human-meaningful list and the Process loop can determine number of samples and sample rates, which will be different for each test. The user may not know or care what those parameters are.) Similarly, if the DAQ collects many more data points than will be displayed, let Process do the data reduction (averaging or decimation) before passing the reduced data to the GUI.

In the planning and design stage of the project look at the dataflow: How much data is needed where and when? That is where the decisions about how to move the data around should be made.

Lynn
0 Kudos
Message 6 of 6
(2,838 Views)