LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How do we make shift register init only happen once, so that data can persist across multiple runs of a loop?

Solved!
Go to solution

Here's the situation:

 

We are repeatedly monitoring eight real-world signals and comparing them to a threshold value.  We do this via a For Loop inside a While Loop.  The For Loop runs eight times per pass.  We have set up a 1D binary array and use the For Loop's index as the array index, putting a Boolean result into the array using the Replace Array Subset function.  We want the array data to be "sticky", in the sense that any True value is latched, so even if a False comes later on, that array element stays true.  However, since we have to initialize the array in order for the Replace Array to work, we're finding that each time the For Loop starts over again, it reinitializes the array and wipes out the history.

 

I've attached a simple VI to illustrate the concept, using a random-number generator as a stand-in for the real-world signals.  How would we modify this VI to make and True entries latch across multiple For Loop runs, indefinitely?

 

In case it's not obvious, I'm a relative newby, so please take that into account in your response.

 

Thanks,

B

0 Kudos
Message 1 of 7
(4,660 Views)

Note that your example code doesn't do this -- your random number test resets array elements to true or false depending on the test.  But never mind, you can, in fact, "have your cake and eat it, too".

 

The idea is to use an uninitialize Shift Register, and initialize it (once) inside the While Loop.  Here's a picture (this is a Snippet -- if you drag this into a blank LabVIEW 2015 Block Diagram, through NI Magic, it will become LabVIEW Code).

Start Shift.png

This is more-or-less your original code, except there's a Case Statement in there, and nothing is wired into the Shift Register from the outside.  This means that it "takes on its default value".  Well, because you wired it inside the loop to be an array of Booleans, it take on the default values of Array (empty array) of Booleans (false).  That means that when the program starts, it sees ... an empty Array.  We can test that (that's the Compare function, "Empty Array?") and if it is true, we can execute the code you can't see inside the True case, which here just creates (using Initialize Array) an Array of 4 "False" Boolean values.  Then it exits the Case, hits the Loop, goes back and reenters via the Shift Register as an Array of four False booleans, and away we go!

 

When you stop it and start it again, the Shift Register "remembers" its last value, so it won't re-initialize, as it isn't empty.

 

Enjoy.

 

Bob Schor

Message 2 of 7
(4,649 Views)

I recommend using the "First Call?" function instead of the "Empty Array?" function here. That way it will reinitialize every time you restart the main VI. Otherwise you're bound to have some confusion when you stop your code, restart it, and discover all the previously latched values are still there, because shift registers hold their value between executions even when the main VI stops. Also, for the same reason, if you change the Loop Iterations input and then re-run Bob's code, it won't resize the array.

Message 3 of 7
(4,635 Views)

Based on your description, I would just do this.  No need for case structures or Replace Array Subset.  Just let LabVIEW work on the arrays directly.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 4 of 7
(4,624 Views)

@nathand wrote:

I recommend using the "First Call?" function instead of the "Empty Array?" function here. That way it will reinitialize every time you restart the main VI. Otherwise you're bound to have some confusion when you stop your code, restart it, and discover all the previously latched values are still there, because shift registers hold their value between executions even when the main VI stops. Also, for the same reason, if you change the Loop Iterations input and then re-run Bob's code, it won't resize the array.


As I understood the problem, he specifically did not want to "reinitialize every time you restart the main VI".  I tried First Call?, realized that a restart would result in a "True", so came up with this method.  You are right, however, about resizing the array -- this can also be handled by a similar maneuver (I presume changing the Array Size would mean it's OK to wipe out the previous History).  If you put "Current Size" in an uninitialize Shift Register, then simply comparing "Is incoming size = saved size?" would take you to the "Initialize the Array" step when the size changed, including the first time you run (since the default size is 0).

 

Bob "You Pays Your Money and You Takes Your Choice" Schor

0 Kudos
Message 5 of 7
(4,613 Views)

This is some really good stuff -- thank you all of taking the time look at this.  I'll try to respond here to the various ideas.

 

There are two approaches being proposed: Bob + nathand, and crossrulz.  I'll call these A and B.

 

For A, I *do* want the array to re-initialize when I restart the main VI.  What I don't want is it to re-init every time the For Loop restarts.  I think I understand the overall idea, though, and I appreciate learning about the existence of the "First Call?" function.

 

For B, while I like the simplicity of it, I have a question: Does it address the re-initialization problem?  When does the shift register of the While Loop get initialized -- just once when it launches?

 

Regarding the other part of the challenge, which is to preserve any array elements which are True, does Solution A do this?  It's not clear to me.  Solution B appears to do this via the logical OR function, if I'm reading that right.

 

Thanks!

B

0 Kudos
Message 6 of 7
(4,599 Views)
Solution
Accepted by topic author bconsult

@scottbbb wrote:

For B, while I like the simplicity of it, I have a question: Does it address the re-initialization problem?  When does the shift register of the While Loop get initialized -- just once when it launches?


Yep, the shift register only initializes at the beginning.  You could say each time the While loop is called (not each iteration) the shift register is reinitialized with the array of FALSEs.

 

And, yes, the OR will always keep a TRUE once it becomes TRUE.

 

Usually the simplest solution is the best.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 7 of 7
(4,585 Views)