Showing results for 
Search instead for 
Did you mean: 

Help Needed for an Application Recording and Storing Values in an Array

Go to solution



Hope this explanation isn't confusing. I've explained my desired application in text below,and also attached a skeleton VI + screenshot hoping it will clarify

I'm attempting to make a VI that does the following:
1. Some code (blue SubVI) runs every 200ms
2. Every 200ms a random number is generated
3. The random numbers are stored in an array in time intervals of 0.8s ("iterations")
4. At every point in time, the code (blue SubVI) needs to have access to the random numbers that were generated in "the previous iteration"

To clarify, the iterations are as follows:
Iteration #1: 0-1.8s
Iteration #2: 2-2.8s
Iteration #3: 3-3.8s

Iteration #4: 4-4.8s
And so on..

So for every iteration: the code (blue SubVI) needs to have access to the random numbers that were generated in the previous iteration, for example:

Iteration #1 (0s-1.8s): The code (blue SubVI) gets an array containing only zero's (random numbers are recorded for the first time)
Iteration #2 (2s-2.8s): The code gets an array containing the random numbers from iteration #1
Iteration #3 (3s-3.8s): the code gets an array containing the random numbers from iteration #2
Iteration #4 (3s-3.8s): the code gets an array containing the random numbers from iteration #3
And so on..

At any given point in time;
- The code is being fed an array containing all random numbers recorded during the previous iteration
- Values from before the previous iteration are discarded and not stored anywhere


So for example, at iteration #7:

- Values recorded during iteration #6 are being made available to the code in the form of an array

- Values from iterations #1 to #5 have been deleted and are not stored anywhere

It's important that all values recorded from before the previous iteration are deleted as they are not needed as the actaual VI will be running for a long time storing much more numbers than what I have indicated here


Screenshot of the Skeleton VI:




I've tried playing around with arrays, case structures and shift registers, but every time I try I end up doing something wrong


The Skeleton VI is also attached (Iteration_VI, and Code_SubVI)


Any suggestions?



0 Kudos
Message 1 of 16

OK, you managed to confuse things in your description by being slightly careless in your descriptions of "iterations" (Iteration 1 was 2 seconds, the rest were only 1 -- clearly you mean Iteration 1 to go from 0 to 1 second (don't say 0 to 0.8), etc.


I'd write a sub-VI that (a) generates a new Random number each time it is called, adding it to an internal Array of Random numbers, (b) accepts as an input an Array of 5 Random numbers, and (c) returns either the input array of 5 random numbers (a Passthrough), or, if its Internal Array has 5 members, it returns the "new" array and zeros out its Internal array, waiting to generate the next five numbers.


This "isolates/insulates" the whole process of generating these Random Numbers to this one routine.  What your Timed Loop sees is the "current set of 5 Random Numbers generated on the previous Iteration" -- everything else is either "invisible" (inside the sub-VI) or "discarded".


Bob Schor

Message 2 of 16

Thanks for your response


You're correct, iteration 1 is supposed to be only 1 second


The random number is actually a measurement from an FPGA I/O block containing various outputs, perhaps I should have mentioned that in the beginning


Does your suggestion still work then?





0 Kudos
Message 3 of 16

@phg wrote:

The random number is actually a measurement from an FPGA I/O block containing various outputs, perhaps I should have mentioned that in the beginning


Does your suggestion still work then?


Absolutely.  Inside the sub-VI, being called every 200 msec, you "generate" a value.  In your original post, you said "a random number", so you'd use the Random Number function on the Numeric Palette (transforming it to approximate the distribution you want).  On the other hand, if it is really "a reading from an FPGA I/O block", then as long as you can put the code to get that value inside the sub-VI, sure, why not?  [I don't do much FPGA work, so I don't know how easy it is to get the data ...].


Bob Schor

0 Kudos
Message 4 of 16

Ahh, I understand now. That shouldn't make a difference no


The only thing I can't see how I would do is;

How can I empty the array like this, while still sending it for being used at the "next iteration"?


Also: with this structure, doesn't make a difference if it happens in a SubVI or not?

0 Kudos
Message 5 of 16

Recall how the sub-VI works.  It starts with "nothing", an empty Array (on a Shift Register) and an empty "Count" (also on a Shift Register).  It has an Input, Array In and an output, Array Out, coming from the Calling Routine.


So each time it is called, it does the following:

  1. Increments its Count.
  2. Adds a new Element to its internal Array (the "Array Next Time").

Now, when the Count is 1, 2, 3, or 4, it just passes Array In to Array Out, meanwhile "building" up the Array Next Time.  When the Count gets to 5, you Do Something Different -- you pass out Array Next Time, reset the Count to 0, and zero out Array Next Time (for the next call).


You do not need to do this in a sub-VI, but (a) it "isolates" this element of the code, allowing you to (for example) put a Random Number Generator in there to test it, then replace it with FPGA code "for real", (b) it gets clutter out of your Timed Loop so you can see the "important stuff", namely what you are doing inside the timed loop, and (c) if you create an Icon for your sub-VI (something as simple as a 32x32 Box Outline with "FPGA Last Sec" (to remind you this is giving you FPGA data from the last second), you might remember in a month what you did.


Bob Schor 

Message 6 of 16

Do you mean for the SubVI to have it's own while loop with a shift register, or use the main loop at the main VI?

0 Kudos
Message 7 of 16

This seems to be working


Edit: not working after all, it keeps skipping a value at each iteration (tried feeding the iteration count instead of a random number to check)


Also not sure if this is how you meant though, perhaps I've used way too much code?


Edit: Sorry; it's not letting me upload the VI's, here's a screenshot of the main VI and sub VI:


Main VI:



SubVI, "false case":



SubVI, "true case":


0 Kudos
Message 8 of 16
Accepted by topic author ghp_1
08-28-2016 03:49 PM

Yes, I agree you need help.  First, you really need to learn more about LabVIEW -- spend a few hours with the Tutorials, such as the ones mentioned on the first page of the Forums.  Oops -- the Links to the Tutorials that had been present for years appear to have been moved "someplace else" with the August 2016 reorganization of the LabVIEW Community.  But look for them ...


Here are some VIs that basically implement what I described above (with some minor modifications).  First, here is a Top Level VI that runs at 5 Hz (200 msec waits).  It starts with a 5-element array of 0, then once a second this is replaced with a 5-element array of random numbers generated by the Random 5-Array sub-VI.  Note that I don't use a Timed Loop -- those are really designed for LabVIEW RT, but use the simpler functions on the Timer Palette.

Random 5-Array Caller.png

Do you see how this works?  The Initialize Array on the left starts you off with a 5-element Array of 0's.  The Timer inside the Loop makes it run at 5 Hz, "Index" counts 1, 2, 3, ... to tell you where you are, and Array of 5 shows you whatever is living on the Shift Register.


Now, the sub-VI Random 5-Array is supposed to do the following -- if it has been called 5, 10, 15, ... times, it should return a (new) Array of 5 random numbers, otherwise it should return the Array that was passed in to it.  So if everything "works", Array of 5 will show 0, 0, 0, 0, 0 for the first second, a random array for the second second (that's not redundant!), a different random array for the third second, and so forth.  I already told you one way to build this, but I chose a slightly different (equivalent) method.

Random 5-Array 5.png

Each time this is called, a new Random Element is generated and added to the end of a (growing) Random Array stored in the Shift Register.  If its size become 5, we send this Random-Array-of-5 out through Array Out and reset the Shift Register to an Empty Array.

The Default case (when the size doesn't equal 5) is shown below -- we just return the input Array In and accumulate the growing new Random Array.

Random 5-Array Default.png

These code fragments are VI Snippets.  If you have LabVIEW 2016 (see the "2016" in the upper right of the image?  That shows that it is a LabVIEW 2016 Snippet), you can open a blank Block Diagram and drag this image onto it, where NI Magic will convert it to a VI.  Otherwise, code it yourself and try it out.


Caveat -- This is designed to be run once.  If you run the Top Level program a second time, you might find that the new Random 5-Array pops up at 0.4", 1.4", 2.4" (instead of 1", 2", 3").  I leave it as an Exercise for you to (a) figure out why this is, and (b) fix the code.  If you can't do this, then spend another 3-4 hours with the LabVIEW Tutorials (or start playing with this code, modifying it in little ways and figure out how it works).


Bob Schor


Message 9 of 16

Thanks! This is a lot simpler than my initial attempt

a) This would happen if the VI is stopped and the 'internal array' in the SubVI has some values (but less than 5), the values remain there when the main VI is started again- so there needs to be some initialization here (?)

b) Still working on that:

- Simply adding an initialization to the shift register (for the 'internal array') inside the SubVI doesn't work

- Perhaps I need some logic to check if the VI is at the first iteration, and if so, intialize the 'internal array' inside the SubVI for that case alone?

Would these be the videos you referred to?

0 Kudos
Message 10 of 16