Timers: One Trigger, Two Timers, Different Counters, Whut?

Okay, I have an output routine that needs to cycle through 16 for one set of outputs, and 4 for another. Both of these output timers are triggered by the same event - part of a refresh routine. As in: - Button is presssed on a Controller - MTPro hears this, and data in Global Variables is updated in MTPro per Rules (non-Timer Event) - Timer: Output routine uses the Globals and calcs output to a Sequencer and also back to the controller and sends the appropriate Note On & CC values.

Add'l info: One set of events cycles through 16 bits of a mask and creates one of two CC values depending on the bit's mask status 0/1. The other set of events cycles through 4 bits of a different mask (well, actually two masks separately) and creates Note Velocity values to feedback to the controller.

Can I call one Timer event with different repetitions?

Alternatively, I could do something like: - Call the Timer for 16 repeats - Do the 16 repeat event - Test to see if the counter is divisible evenly by 4 - if it is, then do the 4 repeat event - If not, skip to the end

Questions: - If i use a Jump (GOTO) and put the label at the end of the Rules, I'm assuming the it effectively jumps over the rules in question, gets to the end, does the output, repeats as expected. Yes? - If I use a test such as if the modulo of the counter != 0, then Exit Rules, Execute Outgoing Action *while* in a Timer, does that stop the timer iterations or does the timer continue as normal, just skipping anything at the end of my Rules, but still repeating if there are iterations still to do? - Is there a better way to do this thing? One Timer needs to go 16 times, another goes 4 times, and the simpler it is the better in case I need to troubleshoot later and also because this is a very small part of a much larger project.

I guess, the Timer Control, specifically number of repetitions, is not inherent in the Timer Translator, but in the Translator that called the Timer?

I think my problem is that I'm approaching Timers as a For/Next or a Do/While and that is nerfing my wrapping my head around them.

Jim,

Please structure as follows

First translator

——————

Incoming action – Whatever event you want

Rules – Set count, delays global variables etc

Outgoing – Trigger “16 bit timer event x times

=======

Second translator

———————

Incoming action – Whatever event you want (same event as 1st if you wish)

Rules – Set count, delays global variables etc. Use different global variable for working with this timer than you used in 1st translator

Outgoing – Trigger “4 bit timer event y times

 

Then your two timers to iterate and output as normal although some of you second timer’s outgoing MIDI messages will likely be interspersed with the first timer output messages.

 

If you have to finish one timer before you start the next timer, Then you will either need to delay the trigger of the second timer or use a global variable as a flag to determine when the first time is done (such as when the counter reaches 0).

It is important to realize that global variables do not have locks, so it is good practice to ensure that there is no chance of having two translators changing the value of a global variable. You also need to ensure that when checking the global variable’s value it is at the time you want to check it. If the variable is changed within the same translator then it is not a problem since they execute in sequence. However, if two timers are checking the variable and others perhaps updating it, the timing of checking is more critical.

I often use a global variable as a “flag” to check when a a timer is finished.

You set the flag in the translator that launched the timer.

In the timer itself when you determine it is done, you reset the flag.

I hope this helps!

 

Steve Caldwell
Bome Q and A Moderator and
Independent Bome Consultant/Specialist
bome@sniz.biz

Thanks for your reply, Steve.
I’m having a tough time wrapping my head around Timers.

A single button press on my controller sends a Note On to MTPro that activates my Translator that does the massaging of the bit buckets, toggles, and updating the masks.

The same masks are used by both output routines, so I can’t use two Translators to call two different Timers. Doing so would require modifying the same Global Variables in two different Translators which I’m avoiding for the same reasons as you documented. 🙂

The Timer routines only read the Global Variables dedicated to masks and create the output. The data is destined for two different directions: the destination sequencer and the origin controller to update the LEDs. The former of which requires a 16 count timer and the latter the 4 count timer.

Obviously one counter is divisible by the other, so I think I can do this with a single counter. It’s just that I’m not familiar with some of the Jump or Exit rules. I’ll try some tests on this end.
Thanks for your help Steve!

Hi Jim,
If you are outputting in two different directions, you will certainly need different translators to send MIDI events ; one for each destination. Best to have all of your calculations and massaging in one translator and leave rules blank in the other,

Maybe if you can flow-chart how the variable interact, I can help further. It may need that we use one recurring timer, to trigger one or more other, (perhaps single shot) timers.
You could have, for instance incoming timer 16 iterations that triggers a one shot timer to output to your LED’s and does all the calculations.
The one shot timer would then send the 16 values to your first device

Then the same incoming timer that triggers another one shot timer (at every 4 count) that sends to the other device.

Does this make sense?

Thanks Steve.
I think we’re talking about two different things again. :slightly_smiling_face:
No worries.
I’ll try a few things on this end and if I can’t get it to function, I’ll probably just rewrite the whole thing or scrap the project.

I need to read what you post and try to understand rather than what I do. Many apologies! 🙂

So I have the Calc Routine which calls [Output Ready] 0ms; Once Only Timer
Translator 1: Inc [Output Ready] => Calls 16ct Timer for CC Output
Translator 2: Inc [Output Ready] => Calls 4ct Timer for Btn Output
Translator 3: Inc [16ct Timer] => Does the 16 count for CC Output
Translator 4: Inc [4ct Timer] => Does the 4 count for Btn outputs

Posting this here in case anyone else runs across the same thing and is as messed up in the head as I am requiring repeating everything the smart people say but in terms those of us who are lacking in the brains dept can understand. 🙂