Timer object is triggering much faster than specified?
Show older comments
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
Accepted Answer
More Answers (0)
Categories
Find more on Startup and Shutdown in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!