如何在MATLAB中使用计时器以固定间隔运行函数 [英] How to use timer in MATLAB to run a function at a fixed interval
问题描述
我想每隔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屋!