LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

elegant solution to array problem?

Hello,
 
I am looking for an elegant solution to the following problem.  I already know the brute force way to do it.
 
I have a 2D array containing a column of time increments and two columns containing 1's (to indicate a device should be on) and 0's (to indicate the device should be off).  So it looks like this...
 
0.000000   1   1
0.000197   1   1
0.000198   0   0
0.000417   0   0
0.000418   1   1
0.000660   1   1
0.000661   0   0
0.000843   0   0
etc.
 
As you can see, in this example case, the device needs to be on for 197usec, then transition, then off for 219usec, then transition, then on for 242usec, then transition, etc.  For a 13-second-long set of data, the array in this format will contain approximately 42,000 points. 
 
What I need to do is convert this 42,000 point array into an array containing 1's and 0's wherein each point is now spaced 5usec apart, then convert the 1's and 0's to voltage levels (which will be dependent upon a user-specified parameter), then feed it to my device using a 200kHz sample rate.  I can do the voltage conversion at the same time I do the time calculation -- so the voltage conversion can be done in little chunks.
 
The brute force way to do this, of course, is to extract the first two points of the first array column, (0,0 and 0,1), subtract the value at 0,1 (in this case, 197usec) from the value at 0,0 (in this case, 0), divide by 5 (to get the 5usec spacing between points), and create an array containing that many 1's (in this case, we'd have 39 1's since 197 / 5 =39).  Then you extract the next two points of the array and repeat the process, appending the resulting array of 0's to the existing array of 1's.  Then repeat for the next two points, etc. I'd have to do this for 21,000 pairs.  This would give me an array of approximately 2,000,000 points, all nicely spaced 5usec apart.  Then it can either be written to my analog output channel as a DBL array with the sample clock rate set to 200kHz, or as a waveform with delta t set to 5usec.
 
Naturally, the ON / OFF time lengths are random.  I really do have to separately calculate the length of time for each array pair.  Of course I can do this in a FOR loop, using a shift register to increment the index of the array by two, using another shift register to hold the output array I'm building, etc., but I'd have to execute the loop 21,000 times.
 
Is a loop really the most efficient way to do this?  Or is there a better way?  Is it better to pre-process my array and have LabVIEW deal with a 2,000,000 row spreadsheet file instead?
 
Thanks for your help,
Diane
0 Kudos
Message 1 of 9
(3,662 Views)
You'll want to preallocate the array and use replace array subset to generate the large array (appending arrays in a loop can becoming very expensive). I attached an example (should open in 8.0 or higher) to show the difference in speed between converting it in LV and loading a preconverted version (converting is much faster than spreadsheet and about twice as fast as loading a binary file on my system).

Note: I didn't take into account the time to load the 42000 point array and my example probably isn't doing exactly what you want. It also writes a temporary file which it deletes. The codes a bit messy too.

Matt W
0 Kudos
Message 2 of 9
(3,638 Views)

There are a couple of things that are not clear to me. In your example, the second and third column are the same. Do we need to process both?

Attached is a simple program that generates a 1D array that, if processed at 200kHz, will produce roughly the signal you want.

The inputs are:

  1. three column Input array as specified.
  2. Voltage level for "0"
  3. Votage level for "1"

Maybe you can adapt it for your purpose, or at least get some ideas. Good luck! 🙂

Message 3 of 9
(3,623 Views)

hi there

i think the "Expand Digital Data" VI is what you need. see attachment.

 

Best regards
chris

CL(A)Dly bending G-Force with LabVIEW

famous last words: "oh my god, it is full of stars!"
Message 4 of 9
(3,609 Views)

I was totally unaware of this function. this is a beauty one also 🙂

i will have to revise my codes...the way i was doing such things up to now, was to look on the spot at the next element time, and check the actual time (i.e. the time of the element presently treated). a For loop is the created to fill in empty array, and send to card.

in order to avoid memory leakage, i had to prepare an initial array size of 100000, and replace into this array until filled, at which point it is flushed (to buffer of the card), and count for this array restarted to zero.

It is usefull to do it this way, if the array with time and data is created on the spot (i.e via a queue), and variable in length. i tested it to work easily at 2MHz.

Anyhow, since there is "expand" function, i will revise and see if it works better (faster or more elegant).

-----------------------------------------------------------------------------------------------------
... And here's where I keep assorted lengths of wires...
0 Kudos
Message 5 of 9
(3,597 Views)
Using DAQmx you even can connect the digital data type directly to the VIs for sending the data to the hardware.
Best regards
chris

CL(A)Dly bending G-Force with LabVIEW

famous last words: "oh my god, it is full of stars!"
0 Kudos
Message 6 of 9
(3,594 Views)

Thanks guys!  Altenbach, the code you sent is very similar to what I'm doing already, so it's nice to know that it's a reasonable idea.  🙂  I will pre-allocate the array and use "replace array subset" instead...thanks Matt!  Chrisger, I was unable to open the "expand digital data" vi in LV8.0 -- it tells me it was saved in LV8.2.  Would it be possible to save it as LV8.0 and post it again?  I'd love to take a look at it.

Also, Matt -- thanks a lot for the time comparison...I was pretty sure that it would be quicker to do the conversion in LV than it would to generate a 2e+6 point file and mess around with that but one never knows.

The help is much appreciated!

Oh...to clear up Altenbach's question...the columns of 1's and 0's in the original data file are not necessarily identical, in spite of what I posted in my example.  (That was rather misleading of me, wasn't it?)  They represent two independent, totally different data streams and probably won't bear a whole lot of resemblance to each other, come to think of it.  So they both do need to be processed.  Since that can be done in parallel, I don't think it's an enormous deal.

Thanks again, guys!

d

0 Kudos
Message 7 of 9
(3,555 Views)


@Desmith wrote:

Chrisger, I was unable to open the "expand digital data" vi in LV8.0 -- it tells me it was saved in LV8.2.  Would it be possible to save it as LV8.0 and post it again? 


Here's the example now really in 8.0. I am not familiar with digital data, but that seems to be the way to go. See attached


@Desmith wrote:
Oh...to clear up Altenbach's question...the columns of 1's and 0's in the original data file are not necessarily identical, in spite of what I posted in my example.  (That was rather misleading of me, wasn't it?)  They represent two independent, totally different data streams and probably won't bear a whole lot of resemblance to each other, come to think of it.  So they both do need to be processed.  Since that can be done in parallel, I don't think it's an enormous deal.
One little tweak can adapt my example or multiple columns, see attached.
Download All
Message 8 of 9
(3,536 Views)

That "expand digital data" vi is really slick.  Especially since now I can open it.  🙂  I'll still wind up doing some processing on the array since it expands it into 1usec increments instead of 5usec increments, but I don't imagine that will be particularly challenging.  Very cool!

Thanks for all of your help!  Much appreciated!!

d

0 Kudos
Message 9 of 9
(3,518 Views)