LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Is this a good design pattern?

Solved!
Go to solution

Hi,

 

I am working with a team to create an application that can acquire data from up to 24 thermcouple channels.  We plan to create a wizard to assist the user in setting up the test (specifiying stop conditions, sample rate, channels to sample, output file, and email/text notifications).  After the setup, if the user does not cancel out, then the program continues.  We have defined parallel loops and their roles, trying to fit into a producer/consumer design pattern.  I have attached the main file which shows the structure of the program.  We are trying to keep it clean and modular.  Before diving into development, we are finalizing a detailed design specification so that different people can work on each of the loops' subvis.  I was hoping that people could review the block diagram and offer suggestions for improvement or validate that we have chosen a good method of implementation.

 

Notes about the block diagram

The plan is for data driven stop conditions to be detected by Event Notifier, handled by the Main UI event, and then the Data Collector is instructed to stop (as well as the Main UI loop).  When Data Collector stops, it releases queues, the queue reference becomes invalid, and then the loops with the Dequeue will be stopped.

 

I am not sure if an additonal event structure should be in the DataCollector to specifically handle the Stop button on the UI because if it is in the Main UI event structure, the DataCollector would not be stopped immediately.  This is important to stop quickly because the sample rate could be VERY long.  I understand about using an event structure instead of WAIT, but didn't know if there is an efficient way leaving it down in the Main UI event structure....????

 

Data Collector is the producer, it currently only collects data and passes it on.  If the program is going to contain a start collection button, or pause/resume, I need to figure out how to handle this with the Main UI event structure.

 

Event Notifier consumes data from the Data Collector.  It looks at all data and should set a flag if a stop condition is met.  The flag will be handled by the Main UI event structure to tell Data Collector to stop.  The event notifier also sends a notification to the Email/Text Caller when thresholds have been exceeded warranting a reason for the user to be notified via text or email.

 

Email/Text Caller waits for notification and then calls a subVI to send an email or text with certain data and channel information.  The subVI call is lengthy, so we decided to put this in its own loop instead of a case structure inside the Event Notifier.

 

Report Generator logs all collected data to a file.  A second queue was used, but uses the same data as the first.  Is this the correct implementation since two consumers need the same data?

 

Main UI - handles changing of sample rate, possibly the stop button, possibly start/pause/resume of data collection.  Also handles when Event Notifier sets flag for a data driven stop condition, which then should provide a mechanism to stop the Data Collector.

 

A big question that i have is.... Should the Main UI event structure just be in the Data Collector so that the loop can be stopped immediately?  All of the UI events (stop button, start/pause/resume data collection) directly effect the Data Collector.  Should the data Collector have a state machine instead?

 

I feel that the 3 consumer loops (Event notifier, Email/Text Caller, and Report Generator) seem like a good implementation, but i am not confident about the Data Collector and Main UI loops.  Should they be combined?

 

Message 1 of 6
(2,753 Views)

I would strongly recommend a state machine. Five parallel loops for something as simple as monitoring and logging thermocouples seems excessive. Two loops should be fine. The notification loop contents can also be part of your new state machine, because it's not really a parallel task. If an email or text alert needs to be sent, you've probably paused data collection anyway, right?

Richard






0 Kudos
Message 2 of 6
(2,734 Views)

It looks very reasonable. Good enough to earn your very first kudos!

 

No time to look more closely at your questions and code but I will try to take a look later today. You might be interested in this thread on Lava.

=====================
LabVIEW 2012


0 Kudos
Message 3 of 6
(2,731 Views)

I cannot say if the user would want data collection to pause or be interrupted.  I have to assume that they don't in applications where the data collection is critical.  The email or text is sort of a warning and i don't want it to affect the sample rate.

 

 

0 Kudos
Message 4 of 6
(2,729 Views)
Solution
Accepted by topic author glstill

A couple of thoughts:

 

Overall it looks workable- remember to name your queus and notifiers- then you can depop the BD and launch each loop in its own sub-vi without wiring all those queues between loops- Just obtain ref to named queue.

 

"Data collector" needs a supervisor to control how often the data is collected- I'm thinking a QSM with "init- collect- stop" states.  A simple timed loop could produce the "time to acq ticks" under control of the sample rate control. This puts both the DAQ init and cleanup functions within the Data Collector's perview so it aids coehesion and solves the exit without waiting for the loop to iterate.

 

I'm not a fan of duplicating data- I assume analisys is pretty much just some comparisons- so it is pretty quick- Why not append summary data to the same queue? And make it a single element queue- the report loop can then inspect the queue and look for a summary data "index" - if its greater than the last index written append the darn data to the report?  Preview queue works great for these situations.

 

Do not combine the UI handeler with anything else! Do you see the snag?- hint: here thar be spaghetti.  keep the functions seperated for solid scalable and maintainable code.

 

One last thought:  Its getting less popular to stop loops on the error out of a dequeue.  First it returns a default element that can cause your listeners some headaches.  Second it doesn't let you run cleanup code.  Use a stop command <enum> built into the element data as an executive to determine when to stop.  We'll try to get the examples updated to show current best practices.


"Should be" isn't "Is" -Jay
Message 5 of 6
(2,688 Views)

Just looked at the code -> go with it. I'd also implement a user event to send from whereever needed any messages (report errors, report status, ...)  to the GUI controller. Then all loops except the event structure can be SubVIs.

Pay some attention on the behavior if an error occures, make sure that all loops shut down still (e.g. don't wire the error wire to a enqueue(stop) function).

 

Some nasty idea pops into my mind. What about writing a global variable just to show the status of each subVi. Just a write-only global for debugging.

 

Felix

Message 6 of 6
(2,666 Views)