01-30-2012 03:05 PM
When I started making this VI, I had no clue about proper VI flow, sub-VI usuage, and much more I'm sure.
The VI is a program that outputs a 0-5V digiatl signal to a relay board (to actuate an air cylinder) and monitors 4 input voltages (lets say from a pressure transducer) . The program would then shut down the corresponding output channel if a pressure threshold is not met.
Surprissingly for my first LV program, The VI functions "fine" (the quotes are because I know my programming flow is a mess and probably not efficient) unitl I reach a given cycle count or time elasped, at which time my VI blows up and I receive an error for "not enough memory to complete operatoin".
I am wondering if there is a simple DAQmx (or something else) command misplaced or missing that would solve this issue. When I started making this VI I had a poor top down design layout, or lack of one. I would like to believe I have learned a lot from making this program with no LV training and if I were to do it again I would utilize state machines and sub VI's more. However, with time not on my side and LV not a priority in my job I would like to know if this VI is reworkable..?
I should also mention that this program is being run as an executable on a laptop without the full LV development software. I dont know if the executable creation process could have left to this problem either...
Attached is LV version 10 and 11
Thanks for the help
01-30-2012 03:16 PM
At least part of the problem is putting the obtain queue functions inside of a loop. Nevermind. You have an infinite inner while loop so the obtain queues will only execute once. The program is kind of hard to follow. I see that you are enqueing several waveforms in one loop. Is the queue filling up? What you can do for debugging is to put a Get Queue Status function on your queues and look at the # elements in queue.
01-30-2012 03:26 PM
Steve,
Thanks for the response, my program was easier to follow until I decided to use LabViews auto allign (I think thats what its called) button. Nonetheless, using queues was a "big" break-through for me with respect to figuring out how to allow my analog inputs to talk to my digital ouputs. I have to admit, I'm not sure if I'm using them correctly or even if I fully understand there operation. To clarify, I only need to enqueue enough data to be able to recognize if a system has lost pressure (say 30 seconds). After that I can dump / clear the data from memory. With that being said, I can definitly see if they are filling up with data, that could lead to memory issues; is there a way to dump the data after some time?
01-30-2012 03:29 PM
There are some things you can probabaly do fairly easily. Four of the inner while loops appear to be very similar. You could probably make a subVI from one of them and reuse the code. Some of the shift registers are initialized and some are not. I suspect that this is an error, although I did not look closely enough to determine which way is intended. Read up on reentrancy. You may need that for the subVI.
The outer loop, if it is needed at all should be stopped by a front panel boolean, not by the Abort button. Someone on the Forums has suggested that using the Abort button to stop a VI is like using a tree to stop a car - it works but may have undesirable consequences!
Re-initializing the DAQ tasks and clearing them on each iteration is not very effficient, is slow, and may lead to problems.
The inner inner while loops (inside On Cycle and Off Cycle) are very similar, differing mostly in the data written. Perhaps you only need Idle and Run (with Data as a parameter). The inner inner loops might be combined with the outer loops with some change in the way the timing is handled.
You Dequeue in two places in each loop. There is no data dependency bewteen the two Dequeue functions, meaning that you cannot be sure which will execute first. Also, none of the Dequeues has a timeout set. They will wait forever if no data is available. Queues should not usually be read in more than one location to avoid loss of data or confusion about which data came first.
Lynn
01-30-2012 04:35 PM
Thanks for the input, that should keep me occupied for awhile!
01-30-2012 05:11 PM - edited 01-30-2012 05:14 PM
Looking at it I think you owe Steve Chandler a beer. I'll explain.
Look at the loop second from the bottom- The one that is ALWAYS enqueuing elements as they come in from the DAQ. You can't dequeue faster than one point every 20mSec and then ONLY when the graph is "On Cycle." unless you use single element queues that replace obsolete data if it is not dequeued the queues will continue to grow over time. eventually one will need a new buffer allocation and request a size that coanot be found contigueously in memory.----- Guess what you see then?
Oh- and why did you even bother to add the DAQmx close tasks release queues ect.... If your going to depend on the ABORT button to stop do you expect the cleanup code to execute? (Fix the infinate loops before you leave your hardware in an unsafe condition)