Timer object initiating function over extended period of time using too much CPU memory

7 views (last 30 days)
I am attempting to run a timer object that refers to a function that reads and plots a data point from a pH probe. I plan on running this timer object for up to 3 days, but after 2-3 hours matlab and the computer crashes because CPU usage slowly increases to 100%.
To start the timer I'm using:
h.measuretimer = timer
set(h.measuretimer, 'executionMode', 'fixedRate', 'Period', 4, 'TimerFcn', 'Cori_read')
start(h.measuretimer)
My attempts at fixing this problem have been: 1. Using the "return" function at the end of the code being called upon by the timer object.
Result: CPU crashed after running for 2-3 hours
2. clearing and deleting the timer object after each single measurement, then restarting it.
To do this I wrote: stop(h.measuretimer) delete(h.measuretimer) clear h.measuretimer clearvars return
Result: CPU crashed after running for 2-3 hours
3. Removing the timer object all together and replace with a while loop.
Result: Program ran for 3 days with no problems, CPU usage stayed below 1%. However, this solution prevents further applications I hope to use with this program because the measurements are interrupted when I perform other actions.
My questions are: 1) Why is this happening? 2) Is there a way to properly end a script and remove all memory it used? 3) How do you properly use a timer object over an extended period of time?
Thank you
  9 Comments
Sean
Sean on 4 Sep 2012
Within the function for the button toggle that refers to Cori_read, I have defined the variables:
h.phlog = (1:100000)*NaN;
h.timelog = (1:100000)*NaN;
h.timestart = clock;
h.number = 100000;
The code for Cori read is:
function Cori_read()
global h
%This code opens the pH meter, h.s, retrieves a number, records the time %the number was recorded, and sets it to a variable, h.out
fopen(h.s);
fprintf(h.s,'*IDN?');
h.time=etime(clock,h.timestart)/60
h.out=fscanf(h.s);
fclose(h.s)
%This is my error check for the number coming out of the pH probe. The %number range I am looking for all have 5 elements to them before str2num, %so this safe guards against any bad numbers coming off the probe
while numel(h.out)~=5
fopen(h.s);
fprintf(h.s,'*IDN?');
h.time=etime(clock,h.timestart)/60;
h.out=fscanf(h.s);
fclose(h.s);
end
h.phvalue=str2num(h.out);
h.phlog(h.number)=h.phvalue
h.timelog(h.number)=h.time
% plot a limited length of the data points
if h.number<99950
plot(h.timelog(h.number:h.number+50),h.phlog(h.number:h.number+50)
else
plot(h.timelog,h.phlog)
end
h.number=h.number-1
end
Sean
Sean on 4 Sep 2012
h.s is the ph probe. To set up h.s. I use the code:
h.s = serial('COM4')
set(h.s,'BaudRate',38400,'Terminator','CR')
Upon running the code
fopen(h.s);
fprintf(h.s,'*IDN?');
h.out=fscanf(h.s);
fclose(h.s)
h.s values are:
Communication Settings
Port: COM4
BaudRate: 38400
Terminator: CR
Communication State
Status: closed RecordStatus: off
Read/Write State
TransferStatus: idle
BytesAvailable: 0
Values Recieved: 5
Values Sent: 6

Sign in to comment.

Answers (2)

Walter Roberson
Walter Roberson on 4 Sep 2012
Don't use plot() each time through the timer callback. Instead, create a line object the first time through, and after that set() the XData and YData of that line object to update it.
Do you really need to plot all 100,000 points? The graphics effort for that is going to be non-trivial and get worse as you gather more points. At 100,000 points your resolution will be what, 100 points per pixel? Consider plotting only every h.number/1000 pixel (assuming a plot window 1000 pixels wide).
Also, as you go you are having to change the x-axis limits each time because you are plotting more and more time. Consider picking a time-window, last N seconds only, and displaying that, with xlimmode set to manual and you adjusting the xlim from time to time but not every update.
  1 Comment
Malcolm Lidierth
Malcolm Lidierth on 9 Sep 2012
You could plot then just update the YData values - much faster than a high level plot.
Opening/closing the file each time could be avoided by passing a file handle to the callback and closing it on timer deletion.
Also don't use clock - it's not reliable because the OS may reset system time during the 3 days.
As @Sean asked, does this happen with a trivial (e.g. empty) callback?

Sign in to comment.


Daniel Shub
Daniel Shub on 5 Sep 2012
If h.number ever exceeds 100000, and it looks like it might since you do the following check
if h.number<99950
Then you phlog and timelog are not preallocated and growing on every timer callback. This could take a lot of time. Further, plotting 100000 points is a lot. Even if each point is 1x1 pixels, you would be using 20% of your monitor.
  1 Comment
Sean
Sean on 5 Sep 2012
So the program is never plotting any more then 50 data points at any one time. That is what the check does. Each data point is put into this array of NaN's which is 100000 points long. NaN's are never graphed so they don't show up. What shows is the real data points put in place of the NaN's. What is graphed is controlled by the ever decreasing h.number and the 50 points in front of it.
h.number never exceeds 100,000. It is set at 100,000 and decreases to zero. When it hits zero, the program will fail out and end, but I hope to stop the program by that point.

Sign in to comment.

Categories

Find more on App Building 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!