Search code examples
matlabtimer

Create an array that grows at a regular interval on Matlab


I have been thinking about how to create an array that grows at a regular interval of time (for instance every 5 seconds) on Matlab.

I figured out 2 ways, either using tic/ toc or timer function. Later this program will be complexified. I am not sure which way is the best but so far I am trying with using timer.

Here is what I have tried :

clc;

period=5;%period at which the file should be updated
freq=4;
l=freq*period;
time=[0];

a = timer('ExecutionMode','fixedRate','Period',period,'TimerFcn',{@time_append, time,l,freq},'TasksToExecute',3 );
start(a);

function [time]=time_append(obj,event,time,l,freq)
        time_append=zeros(l,1);
        last_time=time(end)
        for i=1:1:l
            time_append(i)=last_time+i/freq;
        end
        time=[time;time_append];
end

After compiling this code, I only get a time array of length 1 containing the value 0 wheras it should contain values from 0 to 3x5 =15 I think it is a stupid mistake but I can't see why. I have tried the debug mode and it seems that at the end of the line time=[time;time_append], the concatenation works but the time array is reinitialised when we go out of the function. Also I have read that callback function can't have output. Does someone would know how I could proceed? Using globals? Any other suggestion?

Thank you for reading


Solution

  • You can do this by using nested functions. Nested functions allow you to access "uplevel variables", and you can modify those. Here's one way to do it:

    function [a, fcn] = buildTimer()
    
    period=5;%period at which the file should be updated
    freq=4;
    l=freq*period;
    time=0;
    
        function time_append(~,~,l,freq)
            time_append=zeros(l,1);
            last_time=time(end);
            for i=1:1:l
                time_append(i)=last_time+i/freq;
            end
            time=[time;time_append];
        end
        function out = time_get()
            out = time;
        end
    
    fcn = @time_get;
    
    a = timer('ExecutionMode','fixedRate',...
        'Period',period,...
        'TimerFcn',{@time_append,l,freq},...
        'TasksToExecute',3 );
    start(a);
    end
    

    Note that the variable time is shared by time_append and time_get. The timer object invokes time_append, and updates time. You need to hand out the function handle time_get to retrieve the current value of time.

    >> [a,fcn] = buildTimer; size(fcn()), pause(10); size(fcn())
    ans =
        21     1
    ans =
        61     1