From 11:00 PM CDT Friday, May 10 – 02:30 PM CDT Saturday, May 11 (04:00 AM UTC – 07:30 PM UTC), ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Better way to change rate of Timed Loop?

Solved!
Go to solution

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.

Timed Loop.png

0 Kudos
Message 1 of 22
(7,866 Views)
Solution
Accepted by topic author BillMe

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.

0 Kudos
Message 2 of 22
(4,804 Views)

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.

Timed Loop.png

0 Kudos
Message 3 of 22
(4,804 Views)

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):

Timing loop.png

0 Kudos
Message 4 of 22
(4,804 Views)

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!

0 Kudos
Message 5 of 22
(4,804 Views)

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 ...

Message 6 of 22
(4,804 Views)

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".

0 Kudos
Message 7 of 22
(4,804 Views)

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.

task_variable.PNG

actor_launch.PNG

0 Kudos
Message 8 of 22
(4,804 Views)

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?

0 Kudos
Message 9 of 22
(4,804 Views)

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.

0 Kudos
Message 10 of 22
(4,804 Views)