02-14-2011 08:37 AM
Hi,
I have attached some vi's that I am trying to use to run some experiments. The function of them is to measure the temperature and send information to a heating source based on what time it is in the program. This works ok, but the problem is if I try to run multiple instances of these vi's, they slow down dramatically. This in turn affects the heating profile because the temperature measurement does not sample fast enough for accurate feedback. I am pretty sure this is due to poor programming, but I can't figure out exactly what to change. Any assistance will be greatly appreciated.
Thanks
02-14-2011 08:50 AM - edited 02-14-2011 08:52 AM
Suggestions:
1.) Map out the program flow with a flow chart
2.) Take the flow chart and produce a true state machine for the "main" and the "1_1a_cycle.vi" vi's
3.) Get rid of the sequences and all of the nested case structures.
4.) Don't use any locals or globals.
I suppose that each instance uses different physical channels. It would probably be more efficient just to setup one program to scan and process all of the channels in one instance.
02-14-2011 09:06 AM
One of your biggest problems is that you are trying write LabVIEW code as if it were a text-based language. This doesn't work, as it leads you to try to turn controls and indicators as pretty things to place on the block diagram and then ignore them, choosing to use local variables all over the place. This can (and often does) lead to race conditions.
The structure of your VI is quite suspicious. I don't understand why you are building arrays for Duty Cycle and Temp Data. Those arrays will not be updated until the loop completes, and once the loop completes the VI stops. You're not using the Run Continuously button on the front panel are you? If you are, STOP, as that is not the purpose of that - it is meant to be used in specific debugging situations, not as a normal way to run a VI.
You said that when you run "multiple instances of these VIs" it slows down. Which VIs?
02-14-2011 03:16 PM
The reason for the arrays for Duty Cycle and Temp Data are to record those values to a text file which I need for documentation. I am not using the Run continuously button on the front panel. Is there a better way of recording these values? As far as the VI's that slow down, the main VI will slow down if more than one instance of it is running. I need to run more than one to get the temperature feedback for multiple temperature inputs.
Thanks again
02-14-2011 05:50 PM - edited 02-14-2011 06:00 PM
If you are running multiple copies of your VI then you should be aware that any subVI will block all parallel tasks that are using it unless that subVI is marked as reentrant. In other works when a VI is not reentrant than only one copy of it exists and only one task can use it at a time. Therefore if this subVI takes a bit of time to execute all the tasks will effectively line up to use it and only one task will be able to run. (This assumes that the parallel tasks are calling the subVI at the same time.) If the subVI is marked as reentrant LabVIEW will automatically make a clone of teh VI which will allow each parallel task to operate on its own copy. This will allow the tasks to truly run in parallel.
There is no need to mark all of your subVIs as reentrant. If the VI executes very fast (say a simple algorithm that computes something) there is no need to be concerned since the execution time will be so short you won't notice the impact of the parallel tasks waiting for this VI to be available. However, if your are doing some complex number crunching on large data sets you probably want that to be marked as reentrant.
You definitely should remove all the frame structures and use more data flow to drive the flow of execution. In addition, consider using state machines. While this may look similar to a stacked frame structure it is MUCH different. State machines which use case structures make it easy for data to flow through all cases. Stacked frames are much more difficult to pass data between frames. In addition, a state machine can be stopped or its flow altered. Stacked frames CANNOT. Once in, every frame MUST be executed.
As mentioned, don't use local and global variables. They should only be used sparingly for specific tasks (notably UI handling). While you are learning you should set the rule to never use them. Force yourself to work with, learn and understand dataflow programming. Only after you really understand that can you consider using local variables. You should never use global variables.
When writing applications it is always a good idea to separate the UI processing from the data processing. This allows for a very flexible design and makes it much easier to reuse your processing tasks.
02-15-2011 10:22 AM
When I mark my subVI as reentrant, I get an error saying: "Physical channel not specified." Would making multiple copies of this subVI for each copy of my main VI solve thvi execution too solve the problem of non-parallel task operation?
Thanks
02-15-2011 01:07 PM
If your VI is reentrant is doesn't usually retain any variable memory so you'll need to feed it from the outside.
Slight cleaning of Main included.
/Y
02-16-2011 10:40 AM
could you save that vi as a labview 9.0 file, I don't have 10
thanks
02-17-2011 10:51 AM
Attached a down converted version. For future reference, there's a forum where people can help you out with those sorts of things.
http://forums.ni.com/t5/LabVIEW/Upconvert-VI-Requests/td-p/1067230/page/50
02-22-2011 03:04 PM
What should i do instead of using nested case structures and local and global variables? My cycle vi uses nested case structures because depending on where the process is in it's execution determines what setpoint values from the main vi are being used. For example, the program cycles between initial denature, anneal, extend, and the other setpoints in a specific manner, and this depends on how many cycles are set in the main vi front panel. I'm sorry if this does not make sense, I am trying my best to explain what it is i want this vi to do. As far as the variables go, once the cycle vi determines what the setpoint is and how far off the actual temperature is, it sends this information to a global variable. This global variable is called upon by another vi for feedback purposes to adjust the temperature so that it is closer to the setpoint. How can I eliminate these things from my vi?
Thank you