Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to identify if the Ticker has already been triggered at least once? #55

Open
georgevbsantiago opened this issue Sep 3, 2022 · 6 comments

Comments

@georgevbsantiago
Copy link

georgevbsantiago commented Sep 3, 2022

My goal is to identify whether Ticker has already been called to handle its interval().
That is, identifying the first ticker trigger and being able to manipulate the interval with interval().

Example: I would like a callback to fire at the very beginning of the loop execution and then every 300 seconds (5 minutes).
I currently use a global variable for this, but I would like to know if Ticker has any features or can implement some solution so that the global variable is not needed.
Ex:

Ticker uplink_TICKER(uplink_function, 10, 0, MILLIS);

bool first_uplink = true;

main { ... }

loop {

uplink_TICKER.update();

            if(first_uplink == true) {
            
                        first_uplink = false;
            
                        uplink_TICKER.resume();

                        uplink_TICKER.interval(300000);          
            }

}
@sstaub
Copy link
Owner

sstaub commented Sep 3, 2022

There is no internal solution. Maybe you create two tickers with the first to shoot only once.

@sstaub
Copy link
Owner

sstaub commented Sep 3, 2022

Forgot, there is also counter() function, which gives you back the ticks count.

@georgevbsantiago
Copy link
Author

georgevbsantiago commented Sep 5, 2022

Would the approach below be viable? If the user set true, the 1st callback would only be at 300000 millis. But if the user set false, it would make the 1st callback execute immediately (at 0 millis) and the rest of the callbacks every 300000 millis.

Ticker uplink_TICKER(uplink_function, 300000, 0, MILLIS, true);
image

Ticker uplink_TICKER(uplink_function, 300000, 0, MILLIS, false);
image

At first, I don't see a problem because there are situations where the user wants the callback to be triggered, but the resource is not used by another callback.
Example: The user wants the display to show an "ERROR in Execution" message with TICKER_1 (which triggers a callback immediately only once with a total duration of 8000 millis), but wants this message to stay for 8000 millis, using the logic of RUNNING or STOPPED to trigger a TICKER_2. if(TICKER_1.state() == STOPPED) { TICKER_2.resume(); }

Ticker display_TICKER_1(uplink_function, 8000, 1, MILLIS, false);
image

Currently, to achieve this, I create a TICKER with 2 repetitions and immediate execution and handle interval() and counter(). At counter() == 1, the callback does nothing. Then counter() == 2 (show message on Display) with interval() of 8000 millis.
If Ticker display_TICKER_1(uplink_function, 8000, 1, MILLIS, false); is feasible, it wouldn't need to handle interval() and counter().

@sstaub
Copy link
Owner

sstaub commented Sep 5, 2022

Why didn't you trigger the callback function manually?

@georgevbsantiago
Copy link
Author

georgevbsantiago commented Sep 16, 2022

My intention with the proposal would be to solve two problems:

  1. Configure a Ticker (function, 8000, 0, MILLIS, false) and immediately trigger the function registered in the Ticker callback at the very beginning [counter == 0] in the first iteration of void loop() and the following a every 8000 millis.
  2. No need to handle interval() and counter() to allow a semaphore approach to using the Display (ie only one Ticker at a time, showing messages on the Display).

The first proposal I described above. The second is described below:

I needed to apply an approach that respected the idea of priority and semaphore to use the 16x02 Display with only one Ticker at a time.
If I run a function without TICKER, I can't structure priority and semaphore logic. Ticker helps in this objective by manipulating the states (STOPPED, RUNNING, PAUSED).

Example:
image

However, in Ticker's current approach, I can only handle the RUNNING state with 2 tickers (two executions). And my idea would be to manipulate it with just 1 ticker, as in the example below:
image

NOTE: I currently do the first approach (with two tickers/executions) in my code: I analyze counter() and I handle interval() . But if second approach were viable, it would solve 2 problems at once.

NOTE 2: In the first approach, there is still the problem of TICKER_2 being interrupted by human action (pressing a button) in the middle of the execution process and not resetting the initial interval to 10 millis. So I still put additional code in the loop() to force TICKER_2 to 10 millies. Ex: If TICKER_2 == STOPPED, then interval(10);
If the second approach were viable (function, 8000, 0, MILLIS, false), it wouldn't need this additional code, as there would be no danger of TICKER_2 to be interrupted and "save" the wrong start range (keep 8000 millis instead of 10 millis on first run).

Sorry if I'm saying something stupid. I'm just a Maker who uses and really likes your library. Thank you for developing this fantastic library.

@georgevbsantiago
Copy link
Author

georgevbsantiago commented Nov 10, 2022

Maybe the queueFunction example from the H4 library will help something about this issue:

https://github.com/philbowles/H4#introduction

With one exception (queueFunction) all tasks start after the first specified time interval and not immediately. Using the infinite task "every(1000..." will invoke the first instance of user callback at Tstart + 1sec (1000 mS).

/*
every // run task every t milliseconds
everyRandom // run task continuously rescheduling at random time nMin < t < nMax milliseconds
nTimes // run task n times at intervals of t milliseconds
nTimesRandom // run task n times rescheduling at random time nMin < t < nMax milliseconds
once // have a guess
onceRandom // have another guess
queueFunction // run task NOW* - no initial interval t.[* on next schedule: MCU-dependent, but ~uSec]
randomTimes // run task any number of times nMin < n < nMax at intervals of t
randomTimesRandom // run task random number of time nMin < n < nMax at random intervals of nMin < t < nMax milliseconds
repeatWhile // run task until user-defined "countdown" function (type H4_FN_COUNT) returns zero then cancel
repeatWhileEver // run task until user-defined "countdown" function (type H4_FN_COUNT) returns zero then reschedule [ See Note 1]

Thanks for developing Ticker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants