% Generic logger that executes MeasFcn according to MeasTimer, stores the % results and optionally continuously saves them. % MeasFcn should be a function with no arguments. % MeasFcn need to return a row vector of numbers in order to save the log % in text format or display it. With other kinds of returned values the % log can still be recorded, but not saved or dispalyed. classdef MyLogger < handle properties (Access=public) % Timer object MeasTimer % Function that provides data to be recorded MeasFcn = @()0 save_cont = false % Format for displaying last reading (label: value) disp_fmt = '%15s: %.2e' end properties (SetAccess=protected, GetAccess=public) % If last measurement was succesful % 0-false, 1-true, 2-never measured last_meas_stat = 2 % MyLog object to store the recorded data Log end events % Event that is triggered each time MeasFcn is successfully executed NewData end methods (Access=public) function this = MyLogger(varargin) P=MyClassParser(this); processInputs(P, this, varargin{:}); this.Log=MyLog(P.unmatched_nv{:}); if ismember('MeasTimer', P.UsingDefaults) % Create and confitugure timer unless it was supplied % externally in varargin this.MeasTimer = timer(); this.MeasTimer.BusyMode = 'drop'; % Fixed spacing mode of operation does not follow the % period very well, but is robust with respect to % function execution delays this.MeasTimer.ExecutionMode = 'fixedSpacing'; end this.MeasTimer.TimerFcn = @(~,event)LoggerFcn(this,event); end function delete(this) %stop and delete the timer stop(this.MeasTimer); delete(this.MeasTimer); end % save the entire data record function saveLog(this) saveLog(this.Log) end function clearLog(this) clearLog(this.Log) end function start(this) start(this.MeasTimer); end function stop(this) stop(this.MeasTimer); end function str = dispLastReading(this) if isempty(this.timestamps) str = ''; else str = ['Last reading ',char(this.timestamps(end)),newline]; last_data = this.data{end}; for i=1:length(last_data) if length(this.data_headers)>=i lbl = this.data_headers{i}; else lbl = sprintf('data%i',i); end str = [str,... sprintf(this.disp_fmt,lbl,last_data(i)),newline]; end end end end methods (Access=protected) % Perform measurement and append point to the log function LoggerFcn(this, event) time = datetime(event.Data.time); try meas_result = this.MeasFcn(); this.last_meas_stat=1; % last measurement ok catch warning(['Logger cannot take measurement at time = ',... datestr(time)]); this.last_meas_stat=0; % last measurement not ok end if this.last_meas_stat==1 % append measurement result together with time stamp appendPoint(this.Log, time, meas_result,... 'save', this.save_cont); triggerNewData(this); end end %Triggers event for acquired data function triggerNewData(this) notify(this,'NewData') end end end