05-01-2015 03:15 AM
I'm using the Timed Loop Controller class from an example I found. Many of you may already be familiar with it. I have two actors that inherit from Timed Loop but I needed a way to change the rate of the loop while the actors are running, i.e., each actor would have its own specific rate. I came up with the following (see block diagram). A "New Loop Rate" message to Timed Loop sets the Loop Rate control to its new value which is then read in the next iteration of the while loop. This was the best way I could think of to get information into the while loop. I forsaw problems with using queues or synchronization mechanisms.
Does this seem a reasonable way to change the loop rate? I'd appreciate any ideas for a more elegant solution.
Solved! Go to Solution.
05-01-2015 03:30 AM
I would suggest using a notifier, both the to communicate the loop rate, AND as the actual wait function. So the timing loop waits on the Notifier with a timeout, and you can interrupt that timeout by posting a new loop rate to the Notifier. Thus you don’t need to wait for the next iteration to make a change. Another suggestion is to package your timing into a reusable Actor, rather than a custom loop in your Actor Core.
05-01-2015 05:06 AM
Using my initial attempt, I now realize lower rates would only serve to hang up the actor when it received a Stop. I took your suggestion to eliminate that problem with the benefit of immediate updates.
I also added a random string for the notifier name since my requirement is for each actor inheriting from Timed Loop to have their own update rate.
Thank you for the feedback.
05-01-2015 08:02 AM
Why are you giving your Notifier a name at all? Leave it un-named. For comparison, here is the timing loop of the “Metronome” actor I use (note: non-AF framework, but timing issues are similar):
05-01-2015 02:14 PM
Forgive my ignorance. I believed, wrongly, that with more than one actor the unnamed notifiers would not be unique between them. In the Help I found this:
"If you do not wire name, the function creates a new, unnamed notifier reference".
I haven't much experience with LVOOP and AF, and my use of Notifiers in the past has always been to communicate between several VIs where each would obtain the same named notifier. Obviously, in this case that is not necessary as I see now.
Learning something everyday.
Thank you sir!
05-01-2015 02:51 PM
BillMe wrote:
... my use of Notifiers in the past has always been to communicate between several VIs where each would obtain the same named notifier. Obviously, in this case that is not necessary as I see now.
This may be an off-topic, but its too important to be left alone ...
I think named Queues , Notifiers, etc. are much more dangerous than Globals - people tend wiring a name constant to each Obtain Notifier call - making that Notifier an implicit global resource ... You have to search through the entire code base to discover all instances. And using plug-ins makes this even worst.
I always mark this as a top priority candidate for refactoring when reviewing customer code ...
Pulling a Notifier/Queue reference wire through one's code is a much safer practice.
I think NI should clearly mark this as an anti-pattern. It may even deserve a test of its own in the default VI Analyzer test suite ...
05-01-2015 03:18 PM
In my defense (warning: rationalization to follow), I would say that I've been a "user" rather than an "abuser". But I agree with your assessment. It should at least be tagged as "poor programming practice".
05-08-2015 06:24 PM
Have you run into a limit of the number of children your timed data loop can have? I'm finding that I have a hard limit of 4 children. More than 4 and LabVIEW will lock up when I try to stop. These are the four actors that will run and stop correctly:
2 timers (variable from 1ms to 10 seconds)
a DC power supply (1 second rate)
a CAN controller (100ms rate)
When I launch my DAQ and thermal chamber children (both running at 1 second rates), the child actors do not stop.
05-08-2015 10:52 PM
I've currently only got two "timed" actors that inherit from Timed Loop, but I can't think of any logical reason for such a small limit. Have you checked to make sure you don't have an error being generated somewhere?
05-11-2015 10:06 AM
Yes, I've run both of my DAQ and Chamber classes stand-alone and they do not generate any errors. I am also able to wrap the NHR and CAN classes in a diagram disable so the four active classes are Timer 1, Timer 2, DAQ and Chamber. My application will stop correctly as long as there are only 4 actors running off of the Timed Loop class.