Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using tic/toc functions instead of a timer

Using timer objects gets too complicated especially when you have to use more than one timer so I was trying to think of alternative approaches.

I want to avoid using pause, since it stops other functions from executing. I thought of using the tic toc functions to measure elapsed time but the code I have written below does not work as I expect.

time=tic;
if(abs(toc(time)))==3 %% if 3 second past
    my function
end

How can I modify this code so that it executes the command after 3 seconds?

like image 717
xava Avatar asked Jan 28 '26 04:01

xava


1 Answers

TLDR;

A tic/toc pair and a while loop is literally no different than using pause since they both block execution of any other functions. You have to use timer objects.

A More Detailed Explanation

In order to make this work, you'd need to use a while loop to monitor if the required amount of time has passed. Also, you'll want to use < to check if the time has elapsed because the loop condition isn't guaranteed to be evaluated every femtosecond and therefore it's never going to be exact.

function wait(time_in_sec)
    tic
    while toc < time_in_sec
    end

    % Do thing after 3 seconds
    fprintf('Has been %d seconds!\n', time_in_sec)
end

The unfortunate thing about a while loop approach is that it prevents you from running multiple "timers" at once. For example, in the following case, it will wait 3 seconds for the first task and then wait 5 seconds for the second task requiring a total time or 8 seconds.

wait(3)
wait(5)

Also, while the while loop is running, nothing else will be able to execute within MATLAB.

A much better approach is to setup multiple timer objects and configure them with callbacks so that they can run at the same time and they will not block any operations within MATLAB while they run. When you need multiple timer objects (which you consider to be a pain) is exactly when you have to use timer objects. If it's really that cumbersome, write your own function which does all of the boilerplate stuff for you

function tmr = wait(time_in_sec)
    tmr = timer('StartDelay',       time_in_sec, ...
                'ExecutionMode',    'SingleShot', ...
                'TimerFcn',         @(s,e)status(time_in_sec));
    tmr.start()

    function status(t)
        fprintf('Has been %d seconds!\n', t);
    end
end

wait(3)
wait(5)     % Both will execute after 5 seconds

Also since the timers are non-blocking (when the callback isn't running), I can execute commands immediately after starting the timers

wait(3)
disp('Started 3 second timer')
wait(5)
disp('Started 5 second timer')

If you try this with your while loop, you'll see the while loop's blocking behavior.

like image 145
Suever Avatar answered Jan 29 '26 18:01

Suever