10-20-2020 05:08 PM
Hello,
Given: Can't assign attributes for individual elements of an array.
But we can, obviously, have different values for each element of an array.
In attempt to make a blinking progress bar (where only one element is blinking), I:
1) Used an array of color boxes (I think you suggested this in another post).
2) Constructed an actor that blinks a color box.
a. Parameters are fgd, bgd, blink rate and a reference to the color box to be blinked.
b. This works for individual color boxes (where I can easily get a reference to them).
3) I can't, and I've tried, find a way to get a reference to an element of an array (that I can then pass to this actor).
Note: I'm not trying to change the attributes of elements of this array, only their values via a reference.
Q: Is this reality? Or is there an entirely different way to do this?
Thanks in advance,
Dave
10-20-2020 05:26 PM
You take a reference to an entire array of color boxes. The value property is an array of values. Change the value of individual elements within that array. (Replace Array Element).
10-21-2020 01:18 PM
Thanks again!
Here's the working code. Is this doing a read-mod-write on the whole array? Just to overwrite one element?
-Dave
The reason this could be important is that other threads may be accessing (and wanting to blink) other elements of the array. I can see a way to coordinate this, but I don't want to do that if it isn't necessary.
10-21-2020 01:26 PM
Yes. But if you have conflicts because of other stuff accessing it at the same time, you need a better architecture.
I know of at least three options, I'll put them in the order I would use them if it was my project.
1. Older, but still good. A functional global variable. Commands to read an array element or set an array element. It is a single run while loop where the data is stored in the FGV in an uninitialized shift register. Because the subVI is non-reentrant, only 1 location can access it at a time.
2. A data value reference. Came about in more recent versions of LabVIEW, you pass a reference to the data around, Use an In Place Element structure to access the data. It puts a lock on the data so that other locations can't interfere at the same time.
3. Single element Queue. Data is in a queue. Any place that needs it dequeues the array, modifies it, then re-enqueues it. Other places can't conflict because if they try to read it at the same time, the queue will be empty and will wait for it to be re-enqueued. I don't think this is used as much now that Data Value References exist.
10-21-2020 01:31 PM
RavensFan,
Thanks again... three ways of making a mutex. I'll use method (2).
But is it true... that the whole array is read-mod-write?
-Dave
10-21-2020 02:48 PM
I'd say yes and no.
Certainly for method 3.
With method 1 with the FGV, you could create a command that is modify element and use another input to tell which index you are modifying. Then you'd just use Replace Array Subset within that case to act on a specific index.
For Method 2, the In Place Element structure has the ability to also read and replace one or more specific indices.
10-21-2020 04:44 PM
This is working:
Thank you!
-Dave
10-21-2020 09:29 PM
That will work as long as you aren't trying to do that in 2 or more places at the same time.
That is effectively doing the same thing as what you are doing in message 13.
Now if you wrapped that in a non-reentrant subVI and always use that subVI when setting the value of an array element, you'll be okay.
10-27-2020 03:21 PM
Maybe I'm beating a dead horse here, but I'd like this color box blink actor to be agnostic to whether the indicator is a scalar, an element in an array, or in the primary circumstance I'm considering, an element in an array of clusters.
As I understand it, the techniques we've discussed require the blink actor to know how the indicator is "declared".
If I could just pass a reference to a single color box to the actor, regardless of how it's arranged, I'd be good. But I don't yet see a way to get that reference if the color box is in an array (I know how to do this if the CB is an element in a cluster or if it's a scalar).
"Giving up" in this case might mean using a variant and then having the actor figure things out. But it seems so unnecessarily ugly.
What am I missing?
Thanks,
Dave
10-27-2020 03:30 PM
And this use case shouldn't be that uncommon.
1) If I had an array of numerics, where each numeric represents the same process parameter type (temp let's say) measured at different points on a production line and
2) I wanted to use an actor for each element in the array (to update those elements asynchronously to each other) and
3) I wanted the actor to work on scalars or on an array (so I could reuse that code), I'd have the same problem to solve, right?
I must be missing something obvious.
-Dave
PS: Maybe the "scalar" should be an 1D array with only one element in it? That would be a weird work around.