如何在MATLAB中使用计时器以固定间隔运行函数 [英] How to use timer in MATLAB to run a function at a fixed interval

查看:221
本文介绍了如何在MATLAB中使用计时器以固定间隔运行函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想每隔30分钟运行一个函数.每次运行该函数时,都会采用不同的输入.假设我要运行100次.函数为lookupweather,输入为location1,location2,location3,...,location100

I would like to run a function at 30 mins interval. Each time the function run, it will take a different input. Let's say I want to run this 100 times. The function is lookupweather and the input is location1, location2, location3,..., location100

我尝试过:

for a = 1:100
    t = timer;          
    t.StartDelay = 30*60*(a-1)       
    t.TimerFcn = @(scr, event) run('lookupweather');
    start(t)
end 

这里的问题是我找不到地方输入位置信息.如果我尝试了一些lookupweather(location1),则代码将失败.当然,如果没有位置输入,lookupweather函数将失败.有人可以帮忙吗?

The issue here is that I cannot find away to input the location information. If I tried something lookupweather(location1), the code failed. Of course, without the location input, the lookupweather function fails. Could anyone help?

我意识到我可以固定间隔

I've realized I could do fixed interval

t = timer;
t.Period = 30*60;
t.TasksToExecute = 100;
t.ExecutionMode = 'fixedRate';
t.TimerFcn = @(src, event) run('lookupweather');
start(t)

尽管如此,我仍然不知道如何将位置信息输入到我的函数lookupweather中.

I still don't know how to input the location information into my function lookupweather, though.

推荐答案

您需要使用单元格数组声明计时器回调函数,如下所示:

You need to declare the timer callback function using a cell array, something like this:

location_index = 1;

t = timer;
t.Period = 1;  %30*60;
t.TasksToExecute = 5;  %100;
t.ExecutionMode = 'fixedRate';
t.TimerFcn = {@timer_callback, location_index};
start(t);

process_locations = true;
while process_locations
    % . . . 
end
stop(t);
delete(t);

function timer_callback(obj, event, location_index)
    fprintf("Location index = %03d\n", location_index);
end

您可能还需要使用位置的一维向量(或数组),如下所示:

You may also need to use a one-dimensional vector (or array) of locations, something like this:

locations = zeros(1, 100);

t = timer;
t.Period = 1;  %30 * 60;
t.TasksToExecute = 5;  %100;
t.ExecutionMode = 'fixedRate';
%t.TimerFcn = {@timer_callback2};
t.TimerFcn = {@timer_callback3, locations};
start(t);

process_locations = true;
while process_locations
    % . . . 
end
stop(t);
delete(t);

function timer_callback2(obj, event)
    persistent location_index;
    if isempty(location_index)
        location_index = 1;
    end
    fprintf("Location index = %03d\n", location_index);
    location_index = location_index + 1;
end

function timer_callback3(obj, event, locations)
    persistent location_index
    if isempty(location_index)
        location_index = 1;
    end
    locations(location_index) = 12.3;  % Get value from temperature sensor.
    fprintf("locations(%03d) = %f\n", location_index, locations(location_index));
    location_index = location_index + 1;
end

版本4

这使用在计时器回调中修改的全局结构.考虑将其封装在处理程序类或嵌套函数中,以避免使用全局变量.

Version 4

This uses a global struct that is modified in the timer callback. Consider encapsulating this in a handler class or nested function to avoid using a global variable.

clear all;
clc;

number_of_iterations = 10;  % 100
number_of_locations = 5;

% Create a global struct for the data.
% Consider encapsulating in a class rather than using a global.
global temperature_data;
temperature_data = struct("IterationIndex", 1, "Processed", false, "Locations", zeros(number_of_iterations, number_of_locations));

t = timer;
t.Period = 1;  %30 * 60;
t.TasksToExecute = number_of_iterations;
t.ExecutionMode = 'fixedRate';
t.TimerFcn = {@TimerCallback4};
start(t);
while temperature_data.Processed == false
        % . . .
        % Yield some processing time.
        time_delay = t.Period * 1000 / 10;
        java.lang.Thread.sleep(time_delay);
end
stop(t);
delete(t);

function TimerCallback4(obj, event)
    global temperature_data;

    % Cycle through locations.
    for location_index = 1:5
        % Get value from temperature sensor.
        temperature_data.Locations(temperature_data.IterationIndex, location_index) = 100 * rand;
        fprintf("temperature_data(%03d, %d) = %5.2f\n", temperature_data.IterationIndex, location_index, temperature_data.Locations(temperature_data.IterationIndex, location_index));
    end

    % Test for completion of processing.
    if temperature_data.IterationIndex >= size(temperature_data.Locations, 1)
        temperature_data.Processed = true;
    else
        temperature_data.IterationIndex = temperature_data.IterationIndex + 1;
    end
end

版本4结果

TimerCallback4() 0.058
TimerCallback4() 1.023
TimerCallback4() 2.033
TimerCallback4() 3.042
TimerCallback4() 3.961
TimerCallback4() 4.975
TimerCallback4() 5.982
TimerCallback4() 6.990
TimerCallback4() 8.002
TimerCallback4() 9.008
   10.7889   18.2228    9.9095   48.9764   19.3245
   89.5892    9.9090    4.4166   55.7295   77.2495
   31.1940   17.8982   33.8956   21.0146   51.0153
   90.6364   62.8924   10.1534   39.0855    5.4617
   50.1283   43.1721   99.7560   81.1603   48.5652
   89.4448   13.7547   39.0005   92.7356   91.7494
   71.3574   61.8337   34.3288   93.6027   12.4774
   73.0585   64.6477   83.3152   39.8282   74.9822
   83.5221   32.2460   55.2262   97.9129   54.9309
   33.0424   61.9472   36.0637   75.6510   41.3901

版本5

此版本使用句柄类.它可以同步或异步处理.

Version 5

This version uses a handle class. It can process either synchronously or asynchronously.

    clear all;
    clc;

    % Define the settings.
    number_of_iterations = 10;  % 100
    number_of_locations = 5;
    period = 1;  % 30 * 60  % Seconds.

    % Create the object with required settings.
    temperature_processor = TemperatureProcessor(number_of_iterations, number_of_locations, period);

    % Do the process synchronously.
    temperature_processor.ProcessSync();
    disp(temperature_processor.Locations);

    % Do the process asynchronously.
    temperature_processor.IsProcessed = false;
    temperature_processor.ProcessAsync();
    while temperature_processor.IsProcessed == false
        % Do other stuff.
        % . . .

        % Yield some processing time.
        %pause(0.001);
        java.lang.Thread.sleep(1);  % milliseconds.
    end
    disp(temperature_processor.Locations);

    % Delete the object.
    delete(temperature_processor);

TemperatureProcessor.m

    classdef TemperatureProcessor < handle

        properties
            IsProcessed = false;
            Locations;
        end

        properties (Access = private)
            % Define default values.
            NumberOfIterations = 100;
            NumberOfLocations = 5;
            Period = 30 * 60;  % Seconds.
            AsyncIterationIndex = 1;
            AsyncTimer;
        end

        methods
            % Constructor.
            function obj = TemperatureProcessor(number_of_iterations, number_of_locations, period)
                fprintf("obj.TemperatureProcessor() constructor\n");

                if nargin == 3
                    obj.NumberOfIterations = number_of_iterations;
                    obj.NumberOfLocations = number_of_locations;
                    obj.Period = period;
                end
                obj.Locations = zeros(obj.NumberOfIterations, obj.NumberOfLocations);
            end

            % Destructor.
            function delete(obj)
                fprintf("obj.delete() destructor\n");
                try
                    stop(obj.AsyncTimer);
                    delete(obj.AsyncTimer);
                catch
                end
            end

            function ProcessSync(obj)
                fprintf("obj.ProcessSync()\n");

                iteration_index = 1;
                the_timer = timer;
                the_timer.Period = obj.Period;
                the_timer.TasksToExecute = obj.NumberOfIterations;
                the_timer.ExecutionMode = 'fixedRate';
                the_timer.TimerFcn = {@TimerCallbackSync};
                tic;
                start(the_timer);
                wait(the_timer);
                delete(the_timer);

                function TimerCallbackSync(timer_obj, timer_event)
                    fprintf("obj.Process.TimerCallbackSync() %0.3f\n", toc);

                    % Cycle through locations.
                    for location_index = 1:obj.NumberOfLocations
                        % Get value from temperature sensor.
                        obj.Locations(iteration_index, location_index) = 100 * rand;
                        fprintf("obj.Locations(%03d, %d) = %5.2f\n", iteration_index, location_index, obj.Locations(iteration_index, location_index));
                    end

                    % Test for completion of processing.
                    if iteration_index >= obj.NumberOfIterations
                        obj.IsProcessed = true;
                    else
                        iteration_index = iteration_index + 1;
                    end
                end
            end

            function ProcessAsync(obj)
                fprintf("obj.ProcessAsync()\n");

                try
                    stop(obj.AsyncTimer);
                    delete(obj.AsyncTimer);
                catch
                end
                obj.AsyncIterationIndex = 1;
                obj.AsyncTimer = timer;
                obj.AsyncTimer.Period = obj.Period;
                obj.AsyncTimer.TasksToExecute = obj.NumberOfIterations;
                obj.AsyncTimer.ExecutionMode = 'fixedRate';
                obj.AsyncTimer.TimerFcn = {@obj.TimerCallbackAsync};
                tic;
                start(obj.AsyncTimer);
            end

            function TimerCallbackAsync(obj, timer_obj, timer_event)
                fprintf("obj.Process.TimerCallbackAsync() %0.3f\n", toc);

                % Cycle through locations.
                for location_index = 1:obj.NumberOfLocations
                    % Get value from temperature sensor.
                    obj.Locations(obj.AsyncIterationIndex, location_index) = 100 * rand;
                    fprintf("obj.Locations(%03d, %d) = %5.2f\n", obj.AsyncIterationIndex, location_index, obj.Locations(obj.AsyncIterationIndex, location_index));
                end

                % Test for completion of processing.
                if obj.AsyncIterationIndex >= obj.NumberOfIterations
                    try
                        stop(obj.AsyncTimer);
                        delete(obj.AsyncTimer);
                    catch
                    end
                    obj.IsProcessed = true;
                else
                    obj.AsyncIterationIndex = obj.AsyncIterationIndex + 1;
                end
            end
        end
    end

版本5结果

obj.TemperatureProcessor() constructor
obj.ProcessSync()
obj.Process.TimerCallbackSync() 0.051
obj.Process.TimerCallbackSync() 1.029
obj.Process.TimerCallbackSync() 2.026
obj.Process.TimerCallbackSync() 3.025
obj.Process.TimerCallbackSync() 4.034
obj.Process.TimerCallbackSync() 5.024
obj.Process.TimerCallbackSync() 6.023
obj.Process.TimerCallbackSync() 7.023
obj.Process.TimerCallbackSync() 8.023
obj.Process.TimerCallbackSync() 9.023
obj.ProcessAsync()
obj.Process.TimerCallbackAsync() 0.009
obj.Process.TimerCallbackAsync() 1.005
obj.Process.TimerCallbackAsync() 2.004
obj.Process.TimerCallbackAsync() 3.005
obj.Process.TimerCallbackAsync() 4.007
obj.Process.TimerCallbackAsync() 5.005
obj.Process.TimerCallbackAsync() 6.005
obj.Process.TimerCallbackAsync() 7.005
obj.Process.TimerCallbackAsync() 8.005
obj.Process.TimerCallbackAsync() 9.005
obj.delete() destructor

这篇关于如何在MATLAB中使用计时器以固定间隔运行函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆