LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

how to call a subvi to run in background?

i have a timed loop which is gathering data and storing it in an array.  when the array reaches a certain size, i would like to store it to a file while continuing to process new data into the array quickly.  how can i pass the array to a file storage vi from within the loop without preventing the loop from continuing to iterate until the file access is complete?  in other words, i would like to pass the data out of the loop and have the loop continue to run at the same rate while the data is written to a file as a lower priority task.

thanks.

Ben.
0 Kudos
Message 1 of 5
(3,316 Views)

Hi Ben,

      Is it mandatory to keep the data in the temporary array?  If, instead, new data was buffered in a queue, then another VI (running asynchronously) could watch the queue and, when enough elements were present, dump the queue to disk(?)  Just out of curiosity, how often and how many samples would be written to disk?

Cheers!

Message Edited by tbd on 03-06-2007 08:44 PM

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 2 of 5
(3,310 Views)
... for the record, there's no reason you can't accomplish exactly what you requested using the same technique - with one, periodic, write to a queue, instead of many/frequent writes.   In fact your way might be much more efficient, though I haven't done any tests!
 
Cheers!
 
"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 3 of 5
(3,303 Views)
here's a little more about my situation, and why i am not using a queue--
i am running two instances of the same dynamometer control application to allow a user to control a pair of dynos for tracked vehicle testing.  each instance of this vi is gathering status and measurement data off a CAN bus.  i want to log this data as well as (in the future) data from other control VIs running on the same computer.  so i set up a global variable to which each vi writes it's measurement data, and i have a logging application periodically (up to 100Hz) capture the status of the entire global as a new row in a 2D floating point array.  because i am adding a couple dozen elements each time the logger cycles, i did not want the performance hit of dynamically resizing the data structure to which i was storing the data, so i predfine the 2d array and then use an integer to store the index of the next row i want to write to.  the problem comes when i fill up the array (64k lines, the most that excel will process from a csv file)--i would like to store it to a file without inturrupting the logging, but the conversion from float to string plus the file access time takes up too much time to handle inside an iteration of my logging loop.  so i'd like to pass the array to another task which would take care of converting and storing it in the background.

i'm afraid if i store the data in a queue, the application might slow down once the queue gets too large, and i don't want to bog down the other control vis that are running on the same machine.  if i call a sub vi to write that data, the current loop iteration does not complete until the file write is done and i miss a few periods of data.  if i want to  use a seperate  loop to monitor the array size and perform the file access, i need to make the array available to both loops, which seems to require making it a hidden control on the front panel.... but then i have to access this large data structure via local variables, which will give me a huge memory hit, right?  so i think what i would really like to do is pass the entire contents of the array off all at once to another vi, then let that vi store the data in the background while the fast loop continues to begin filling up its array again.  if i call a subvi with an invoke node, i can set "wait until done" to false.... but then how do i pass the data?

thanks for any advice...

Ben.
0 Kudos
Message 4 of 5
(3,282 Views)

Hi Ben,

      ...well, last-things first...

> if i call a subvi with an invoke node, i can set "wait until done" to false.... but then how do i pass the data?
Once you have a VI reference, you can us the "set Control Value" method to hand your array to the dynamically-called sub-VI, however...

What happens if the sub-vi doesn't finish by the time another 2D array is ready? (I know that's not supposed to happen, but what if?)

I think having a queue to which the entire 2D array is written as a single element would be better, and I doubt that launching a sub-vi and passing an array would be any more efficient than writing to an existing queue.  To be honest, I don't know whether the call to the sub-VI will pass the array by value or by reference.  If by value, then a copy is being created - why not create it in a queue?  If by reference, then you have two sections of code writing to the same buffer at the same time - opening the door for data-over-runs.

In the old days, code took a big performance-hit by using Globals this way - frequent writes/reads.  Your application seem to fit a "Producer/Consumer" paradigm - which is routinely implemented using queues.

With that much data, I'd be looking for ways to keep it in binary format for Excel - (LabVIEW uses a conventional binary representation for storing floats) - I'd be surprised if it isn't possible to keep it that way.

If anyone else has ideas to share, I'm happy to step aside.Smiley Happy

 


@bs05442 wrote:
here's a little more about my situation, and why i am not using a queue--
i am running two instances of the same dynamometer control application to allow a user to control a pair of dynos for tracked vehicle testing.  each instance of this vi is gathering status and measurement data off a CAN bus.  i want to log this data as well as (in the future) data from other control VIs running on the same computer.  so i set up a global variable to which each vi writes it's measurement data, and i have a logging application periodically (up to 100Hz) capture the status of the entire global as a new row in a 2D floating point array.  because i am adding a couple dozen elements each time the logger cycles, i did not want the performance hit of dynamically resizing the data structure to which i was storing the data, so i predfine the 2d array and then use an integer to store the index of the next row i want to write to.  the problem comes when i fill up the array (64k lines, the most that excel will process from a csv file)--i would like to store it to a file without inturrupting the logging, but the conversion from float to string plus the file access time takes up too much time to handle inside an iteration of my logging loop.  so i'd like to pass the array to another task which would take care of converting and storing it in the background.

i'm afraid if i store the data in a queue, the application might slow down once the queue gets too large, and i don't want to bog down the other control vis that are running on the same machine.  if i call a sub vi to write that data, the current loop iteration does not complete until the file write is done and i miss a few periods of data.  if i want to  use a seperate  loop to monitor the array size and perform the file access, i need to make the array available to both loops, which seems to require making it a hidden control on the front panel.... but then i have to access this large data structure via local variables, which will give me a huge memory hit, right?  so i think what i would really like to do is pass the entire contents of the array off all at once to another vi, then let that vi store the data in the background while the fast loop continues to begin filling up its array again.  if i call a subvi with an invoke node, i can set "wait until done" to false.... but then how do i pass the data?

thanks for any advice...

Ben.



"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 5 of 5
(3,272 Views)