필터 지우기
필터 지우기

Timer object is triggering much faster than specified?

조회 수: 5 (최근 30일)
Chris Georgiou
Chris Georgiou 2023년 8월 31일
댓글: Chris Georgiou 2023년 9월 7일
Hello, I have written some code to read modbus registers at a frequency of 2 Hz using a timer object, but when I examine the sampling intervals recorded, they vary from 0.05 to 0.27 s, with a median of 0.08s. Could you please help me to understand why and how to fix this? If there is a cleaner way to write this functionality, I would appreciate your comments about this too.
I have included the whole code below, but think these 3 lines are the most important for this issue:
samplingPeriod=0.5; %sampling interval in seconds
tim=timer('ExecutionMode','fixedRate','BusyMode','drop','Period',samplingPeriod,'TasksToExecute',numReadings,'StopFcn',@deltim,'TimerFcn',{@getreading},'Name','mTimer');
start(tim)
%To stop part way through, type stop(tim) into the command line
%% User definable variables
IP1='192.168.1.1'; %IP address of 1st instrument to interogate
FileNameO = "ABB_31AUG23_NoT2corr_2.csv";
measParamNamesO = ["meas1","T1","T2","Out2", "P1","Out3"];%parameter names to measure
measParamAddressO = [1, 401, 451, 453, 501, 458]; %parameter modbus addresses. Must be input register type.
runTime=4*24*60*60; %Total measuring time in seconds
samplingPeriod=0.5; %sampling interval in seconds
numReadings=round(runTime/samplingPeriod +1); %number of readings to take
%% define preset variables
format longG;
global reading
global k
global measParamNames
global measParamNum
global measParamAddress
global m1
global measParamTypes
global FileName
FileName = FileNameO;
measParamNames = measParamNamesO;
measParamAddress = measParamAddressO;
measParamNum = length(measParamNames);
measParamTypes = strings(1,measParamNum);
measParamTypes(:,:) = "single";
reading=table('VariableNames',["time","sTime",measParamNames],'VariableTypes',["double","double",measParamTypes],'Size',[numReadings,2 + measParamNum]);
k=1;
%% setup Modbus connection
% Create a Modbus Object.
m1 = modbus('tcpip', IP1);
m1.Timeout = 1;
%% Setup timer
tim=timer('ExecutionMode','fixedRate','BusyMode','drop','Period',samplingPeriod,'TasksToExecute',numReadings,'StopFcn',@deltim,'TimerFcn',{@getreading},'Name','mTimer');
start(tim)
function getreading(mTimer,~)
global reading
global k
global measParamNum
global measParamAddress
global m1
try
reading.time(k)=now;
for i=1:measParamNum
reading{k,i+2} = read(m1,'inputregs', measParamAddress(i), 1, 1, 'single');
end
k=k+1;
catch
fprintf('Error in getreading function %s\n', datestr(now,'HH:MM:SS.FFF'));
end
end
function deltim(mTimer,~)
%% Finishing func
global reading
global k
global FileName
reading(k:end,:)=[];
reading.sTime=(reading.time(1:end)-reading.time(1))*24*3600;
writetable(reading,FileName);
hold off
hold on
plot(reading.sTime,reading.meas1)
xlabel("Time (s)");
ylabel("Measured Value (%)")
hold off
figure()
histogram(reading.sTime(2:end)-reading.sTime(1:end-1))
title('Sampling period histogram');
xlabel('Sampling period (s)');
ylabel('Number of instances');
delete(mTimer);%clear timer object
clear m1 k runTime period numReadings IP1 measParamTypes measParamNum measParamNamesO measParamNames measParamAddressO measParamAddress % Clear the Modbus Object created.
disp('Logging has finished')
end

채택된 답변

Varun
Varun 2023년 9월 4일
편집: Varun 2023년 9월 4일
Hi Chirs,
I understand that you are attempting to read modbus registers at a frequency of 2 Hz using a timer object. However, you mentioned that the recorded sampling intervals vary and are not consistent with the desired sampling period of 0.5 seconds.
The MATLAB timer object is implemented using a combination of MATLAB's event-driven architecture and the underlying operating system's timer mechanisms. It internally utilizes the operating system's timer mechanisms to trigger timer events. However, the actual timing may be affected by factors such as system load, other tasks running concurrently, handling timer queuing conflicts, and the underlying hardware capabilities. Avoid using timer objects for real-time applications.
To address this issue and achieve more accurate timing, you can consider the following suggestions:
  1. Use the “tic” and “toc” functions: Instead of relying solely on the timer object's fixed rate, you can use the tic and toc functions to measure the elapsed time within each iteration. Internally, tic and toc do not rely on the operating system for timing. Instead, they use the high-resolution performance counter of the CPU to measure the elapsed time. It typically has a much higher resolution than the system clock used by the operating system. Here's an example:
desiredPeriod = 0.5; % desired sampling interval in seconds
numReadings = 10; % number of readings to take
tic;
for i = 1:numReadings
% Perform your modbus register reading here
% Calculate the elapsed time
elapsedTime = toc;
% Wait for the remaining time to achieve the desired period
remainingTime = desiredPeriod - elapsedTime;
if remainingTime > 0
pause(remainingTime);
end
% Reset the timer
tic;
end
2. Consider using the timer object's “StartDelay” property: You can set the StartDelay property of the timer object to delay the start of the timer execution, allowing for a more accurate initial timing. This can help compensate for any initialization or setup delays.
Please refer the following pages to learn more on the Limitations of “timer” object and Handling Timer Queuing Conflicts:
  댓글 수: 1
Chris Georgiou
Chris Georgiou 2023년 9월 7일
Thank you Varun
Restarting MATLAB eliminiated the error. I'm not sure what was going on.
If there were queing conflicts or issues with system load, wouldn't timer frequency decrease? What I have observed is a large increase.
Your suggestion to use the tic toc and pause functions is an interesting 1, I quite like that. Do you think that this would be able to keep time over days? For instance if I set such a function running at 2Hz after exactly 24 hours would we have 2*60*60*24 samples, give or take a couple?

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Whos에 대해 자세히 알아보기

태그

제품


릴리스

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by