diff --git a/@MyLogger/MyLogger.m b/@MyLogger/MyLogger.m index 8cff1db..1602ee7 100644 --- a/@MyLogger/MyLogger.m +++ b/@MyLogger/MyLogger.m @@ -1,175 +1,175 @@ % Generic logger that executes MeasFcn according to MeasTimer, stores the % results and optionally continuously saves them. MeasFcn should be a % function with no arguments. Saving functionality works properly if % MeasFcn returns a number or array of numbers, while intrinsically the % logger can store any kind of outputs. classdef MyLogger < handle properties (Access=public) MeasTimer = []; % Timer object MeasFcn = @()0; save_cont = false; save_file = ''; data_headers = {}; % Cell array of column headers % format specifiers for data saving and display time_fmt = '%14.3f'; % Save time as posixtime up to ms precision data_field_width = '24'; data_fmt = '%24.14e'; % Save data as reals with 14 decimal digits % Format for displaying last reading label: value disp_fmt = '%10s: %.3e'; end properties (SetAccess=protected, GetAccess=public) % Trace = MyTrace(); % Trace object for communication with Daq timestamps = []; % Times at which data was aqcuired data = []; % Stored cell array of measurements last_meas_stat = 2; % If last measurement was succesful % 0-false, 1-true, 2-never measured end events NewData; end methods function this = MyLogger(varargin) p=inputParser(); % Ignore unmatched parameters p.KeepUnmatched = true; - filt_varargin = parseClassInputs(p, this, varargin{:}); + parseClassInputs(p, this, varargin{:}); if ismember('MeasTimer', p.UsingDefaults) % Create and confitugure timer unless it was supplied % externally in varargin - this.MeasTimer = timer(filt_varargin{:}); + this.MeasTimer = timer(); this.MeasTimer.BusyMode = 'queue'; this.MeasTimer.ExecutionMode = 'FixedRate'; this.MeasTimer.TimerFcn = @(~,event)LoggerFcn(this,event); end end function delete(this) %stop and delete the timer stop(this.MeasTimer); delete(this.MeasTimer); end function LoggerFcn(this, event) time = datetime(event.Data.time); try meas_result = this.MeasFcn(); % append measurement result together with time stamp this.timestamps=[this.timestamps; time]; this.data=[this.data; {meas_result}]; 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 triggerNewData(this); % save the point to file if continuous saving is enabled and % last measurement was succesful if this.save_cont&&(this.last_meas_stat==1) try exstat = exist(this.save_file,'file'); if exstat==0 % if the file does not exist, create it and write % header names createFile(this.save_file); fid = fopen(this.save_file,'w'); writeColumnHeaders(this, fid); else % otherwise open for appending fid = fopen(this.save_file,'a'); end fprintf(fid, this.time_fmt, posixtime(time)); fprintf(fid, this.data_fmt, meas_result); fprintf(fid,'\r\n'); fclose(fid); catch warning(['Logger cannot save data at time = ',... datestr(time)]); % Try closing fid in case it is still open try fclose(fid); catch end end end end % save the entire data record function saveLog(this) try createFile(this.save_file); fid = fopen(this.save_file,'w'); writeColumnHeaders(this, fid); for i=1:length(this.timestamps) fprintf(fid, this.time_fmt,... posixtime(this.timestamps(i))); fprintf(fid, this.data_fmt,... this.data{i}); fprintf(fid,'\r\n'); end fclose(fid); catch warning('Data was not saved'); % Try closing fid in case it is still open try fclose(fid); catch end end end function clearLog(this) this.timestamps = []; this.data = []; end function writeColumnHeaders(this, fid) % write data headers to file if specified fprintf(fid, 'POSIX time [s]'); for i=1:length(this.data_headers) fprintf(fid, ['%',this.data_field_width,'s'],... this.data_headers{i}); end fprintf(fid,'\r\n'); 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 %Triggers event for acquired data function triggerNewData(this) notify(this,'NewData') end end end diff --git a/@MyTpg/MyTpg.m b/@MyTpg/MyTpg.m index c70f75d..0463b6c 100644 --- a/@MyTpg/MyTpg.m +++ b/@MyTpg/MyTpg.m @@ -1,157 +1,157 @@ % Class for communication with Pfeiffer TPG single and dual pressure gauge % controllers. % Tested with TPG 361 and TPG 362. classdef MyTpg < MyInstrument properties (Constant=true) % Named constants for communication ETX = char(3); % end of text CR = char(13); % carriage return LF = char(10); %#ok % line feed ENQ = char(5); % enquiry ACK = char(6); % acknowledge NAK = char(21); % negative acknowledge end properties (SetAccess=protected, GetAccess=public) pressure1 = 0; % numeric values of pressure pressure2 = 0; stat1; stat2; gauge_id1; gauge_id2; pressure_unit = ''; end properties (Dependent=true) pressure_str1; % display string with measurement unit pressure_str2; end methods (Access=public) function this = MyTpg(interface, address, varargin) this@MyInstrument(interface, address, varargin{:}); connectDevice(this, interface, address); end % read pressure from a single channel or both channels at a time function p_arr = readPressure(this) query(this.Device,['PRX',this.CR,this.LF]); str = query(this.Device,this.ENQ); % Extract pressure and gauge status from reading. arr = sscanf(str,'%i,%e,%i,%e'); - p_arr=arr(2:2:end); + p_arr=transpose(arr(2:2:end)); this.pressure1 = p_arr(1); this.pressure2 = p_arr(2); % Status codes: % 0 –> Measurement data okay % 1 –> Underrange % 2 –> Overrange % 3 –> Sensor error % 4 –> Sensor off (IKR, PKR, IMR, PBR) % 5 –> No sensor (output: 5,2.0000E-2 [hPa]) % 6 –> Identification error this.stat1 = gaugeStatusFromCode(this, arr(1)); this.stat2 = gaugeStatusFromCode(this, arr(3)); triggerNewData(this); end function pu = readPressureUnit(this) query(this.Device,['UNI',this.CR,this.LF]); str = query(this.Device,this.ENQ); % Pressure units correspondence table: % 0 –> mbar/bar % 1 –> Torr % 2 –> Pascal % 3 –> Micron % 4 –> hPascal (default) % 5 –> Volt pu_code = sscanf(str,'%i'); pu = pressureUnitFromCode(this, pu_code); this.pressure_unit = pu; end function id_list = readGaugeId(this) query(this.Device,['TID',this.CR,this.LF]); str = query(this.Device,this.ENQ); id_list = deblank(strsplit(str,{','})); this.gauge_id1 = id_list{1}; this.gauge_id2 = id_list{2}; end function p_arr = readAllHedged(this) openDevice(this); try p_arr = readPressure(this); readPressureUnit(this); readGaugeId(this); catch p_arr = [0,0]; warning('Error while communicating with gauge controller') end closeDevice(this) end function code_list = turnGauge(this) query(this.Device,['SEN',char(1,1),this.CR,this.LF]); str = query(this.Device,this.ENQ); code_list = deblank(strsplit(str,{','})); end % Convert numerical code for gauge status to a string function str = gaugeStatusFromCode(~, code) switch int8(code) case 0 str = 'Measurement data ok'; case 1 str = 'Underrange'; case 2 str = 'Overrange'; case 3 str = 'Sensor error'; case 4 str = 'Sensor off'; case 5 str = 'No sensor'; case 6 str = 'Identification error'; otherwise str = ''; warning('Unknown gauge status code %i', code); end end % Convert numerical code for pressure unit to a string function str = pressureUnitFromCode(~, code) switch int8(code) case 0 str = 'mbar'; case 1 str = 'Torr'; case 2 str = 'Pa'; case 3 str = 'Micron'; case 4 str = 'hPa'; case 5 str = 'Volt'; otherwise str = ''; warning('unknown pressure unit, code=%i',pu_num) end end end %% Get functions methods function p_str = get.pressure_str1(this) p_str = sprintf('%.2e %s', this.pressure1, this.pressure_unit); end function p_str = get.pressure_str2(this) p_str = sprintf('%.2e %s', this.pressure2, this.pressure_unit); end end end diff --git a/GUIs/GuiLogger.mlapp b/GUIs/GuiLogger.mlapp index 87c8033..47df90d 100644 Binary files a/GUIs/GuiLogger.mlapp and b/GUIs/GuiLogger.mlapp differ diff --git a/GUIs/GuiTpg.mlapp b/GUIs/GuiTpg.mlapp index 6d37aac..27aeaf1 100644 Binary files a/GUIs/GuiTpg.mlapp and b/GUIs/GuiTpg.mlapp differ