From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with creating array of notifier references using a loop

Solved!
Go to solution

Dear all,

 

I have attached two VIs. try_ChannelsOn2ndMonitor.vi outputs random values to four graphs, and ChannelGraphsOnSecondMonitor2.vi receives those values via an array of notifier references and outputs them to four corresponding graphs. Essentially, the graphs in the two VIs are supposed to - and do - display the same values.

 

At first, using a loop to create the array of notifier references, I was unable to get the four graphs in the sub-VI to output the desired values. They only showed the values from the 4th graph in the main VI. I tried using indexing, and then I tried using Shift Registers combined with the "Build Array" function, but neither of these methods worked. Finally, the only method that worked was the one you see in try_ChannelsOn2ndMonitor.vi, which was to create four notifiers in parallel and combine them using "Build Array". My question is: why is it not possible to create the array of notifier references using a loop and still get the correct functionality? I spent a few hours wondering about this.

 

Any comments related to my use of notifiers, notifier arrays, or the VI reference in the Sequence Structure are also appreciated. The sequence structure is only there because the sub VI should be output to a second monitor; I basically disabled it by setting FP.State to "Standard".

 

Thank You!

Nemanja

Download All
0 Kudos
Message 1 of 8
(3,756 Views)

I can't see any reason why creating notifiers in a for loop won't work (as long as they either don't have a name or the name is unique). I did have to look twice to figure out why you were using the 'wait on notification from multiple' - I would have been more inclined to create a loop for each graph with a wait on notification in each one so that each graph behaves independently and will update as soon as the notifications are received.

 

Looking at the help for Wait on Notification from Multiple - it will not wait until a new message has been received for every notifier in the array, rather it will continue executing as soon as one of the notifications is received (which maybe means you're duplicate data in your graph?).


LabVIEW Champion, CLA, CLED, CTD
(blog)
0 Kudos
Message 2 of 8
(3,736 Views)

Hey Sam,

 

I totally agree with your first point. Using a loop does work, but the functionality is not the same. Also, the example for the "Wait on multiple..." VI that's included with LabVIEW 2014 shows a case with 2 notifiers that are created in the same way that I created the 4 notifiers in my VI. At first, I thought the same way as you did and created a loop for the four notifiers, but then saw it didn't work and followed the example's method. What do you think?

 

I also understand your point about creating a loop for each graph - simple and probably less buggy than the current implementation. I think I abandoned it because I was afraid of the notifiers getting mixed up in the sub-VI, but after getting more experience with notifiers, I see no reason why it shouldn't work. I will try it out.

 

When you say "it will continue executing as soon as one of the notifications is received", do you know if that means it will send that notification to every notifier or just to the appropriate notifier?

 

An unrelated question:

Is my way of ensuring program flow, by using the VI reference, in try_ChannelsOn2ndMonitor_b.vi effective? The LabVIEW documentation recommends not using sequence structures, so I tried to do that.

0 Kudos
Message 3 of 8
(3,698 Views)
Solution
Accepted by topic author Nemanja123

The array will always maintain the order of the notifier references - so you will know the correct order.


When you say "it will continue executing as soon as one of the notifications is received", do you know if that means it will send that notification to every notifier or just to the appropriate notifier?


I'm talking about the wait on notification from multiple - if you were expecting it to return (and continue executing) once it receives all four notifications I don't think that's what it does according to my understanding of the documentation.

 

OK, now that I've had a proper look at it, I would probably structure the code slightly differently - I would move the SubVI out of the while loop and then put a while loop around the code in the SubVI. Something like this:

2015-09-08_10-20-57.png

 

This is what I meant about having individual loops for the SubVI - the error terminal is wired to the stop so that the loops (and hence the VI) stop executing when you release the notifier. That should remove the need for the Static VI reference as the VI stays running until your top-level VI finishes - you could then move your positioning code inside the SubVI.

 

Using sequence structures there like you have done to ensure that block of code happens before your loop starts is fine, another common way is to wire the error out into (or to) the border of the loop - in a more complicated application you would perhaps put that code into an 'initialisation' state of a state machine.


LabVIEW Champion, CLA, CLED, CTD
(blog)
Message 4 of 8
(3,690 Views)

Thanks for that. I implemented your suggestions and they also function as desired. That means I have three possible approaches now (the second one being with single notifiers sent from a loop).

 

What are you reasons for moving the subVi out of the while loop, and for wiring the error terminal to stop? Are there any negatives to the use of static VI references? In this case, obviously, we want the subVI to remain visible.

0 Kudos
Message 5 of 8
(3,682 Views)

I moved the SubVI out of the while loop because if that VI stops executing or takes a long time to execute it could potentially hold up your main loop (it probably won't because of the 1.5s timing but if it were a tighter loop) - particuarly if for some reason it was waiting on a notification that never arrived. The notifier is essentially surplus to requirements - you could have just wired the arrays of data into the SubVI after the for loop and achieved the same result. Notifiers are used when you want to share data as a snapshot (i.e. current value) between loops.

 

I also prefer to have my UI VIs stay running during execution - maybe later on you might want to add a button or some more functionality which would require loops and/or an event structure (like discarding the panel close event). It also means the VI will stay in memory etc.

 

As I mentioned in my original post, the reason for the wiring the error to the stop is to stop the Sub VI - when you release the notifiers in the top level VI, it causes the wait on notification to produce an error out which stops the loops.

 

My thoughts about the references are as follows:

- If you have a reentrant VI, the Static VI reference won't work

- If your Sub VI stays running, you can set the relevant properties inside the SubVI as they will run once at the beginning of the call and then it will stay open until the loops finish

- In most cases, I prefer each VI to handle it's own window positioning etc. - you can do this is a 'This VI' VI server reference in the SubVI - this will always be correct regardless of whether the SubVI is reentrant or not.


LabVIEW Champion, CLA, CLED, CTD
(blog)
Message 6 of 8
(3,667 Views)

I moved the SubVI out of the while loop because if that VI stops executing or takes a long time to execute it could potentially hold up your main loop

I agree with this.

 


The notifier is essentially surplus to requirements - you could have just wired the arrays of data into the SubVI after the for loop and achieved the same result.

But in this case I would have needed to use the VI Server Reference, in order to keep it open and preventing the graph from "blinking"?

 

 

As for wiring the error to the stop node, my point was that I think it is not good practice, because as you said it before, you need to hope that the only error will come from Wait on Notification. I read the same thing when I used Excel VBA, and although I did not agree with it, I used it because I was quite certain that no other error could reasonably happen at that point in the code.

 

Nevertheless, thanks for all the help so far.

0 Kudos
Message 7 of 8
(3,652 Views)

Yes, the error terminal to a stop condition is probably not 'best practice' but its OK for a simple/quick example (a more complete solution might use user events/queues/notifiers to tell the loops when to exit, triggered by the top-level VI) where you know exactly what is happening at both sides of the notifier - the only errors you're going to get out of the node are if the reference goes invalid (which is what we're using to stop the VI) or if there is a timeout (which won't happen as it's set to never timeout). The caveat is that if the top level VI doesn't release the notifier then your SubVI won't exit. If you had other nodes in the loop which may produce other unexpected errors then you definitely have to be very careful about wiring the it to the stop condition.

 

Yes, you would have needed the VI Server reference if you had just wired the data into the SubVI - I said it was the notifier that was unnecessary in that case! You could have just kept it open from the VI properties (open when called, do not close when finished), but it would have still flickered between running/not running - hence why my preferred solution is to have the VI continue executing for the duration. I can't think of any real problems with what you're doing (that I can immediately think of), but it's never really occurred to me to do it that way!


LabVIEW Champion, CLA, CLED, CTD
(blog)
0 Kudos
Message 8 of 8
(3,639 Views)