diff --git a/@MyNewDataEvent/MyNewDataEvent.m b/@MyNewDataEvent/MyNewDataEvent.m index adbba7c..ad62ed6 100644 --- a/@MyNewDataEvent/MyNewDataEvent.m +++ b/@MyNewDataEvent/MyNewDataEvent.m @@ -1,68 +1,67 @@ %Class for NewData events that are generated by MyDataSource and its %subclasses, including MyInstrument classdef MyNewDataEvent < event.EventData properties (Access=public) % Name of the instrument that triggered the event. Usefult for % passing the event data forward, e.g. by triggering % NewDataWithHeaders src_name = 'UnknownInstrument' % New acquired trace. Should be passed by value in order to prevent % race condition when multiple NewData events are triggered by % the same instrument in a short period of time. Passing by value % makes sure that the trace is not modified before it is received % by Daq. Trace % If false then MyCollector does not acquire new measurement % headers for this trace. Setting new_header = false allows % transferring an existing trace to Daq by triggering NewData. new_header = true % If the new data should be automatically saved by Daq. save = false % If 'save' is true and 'filename_ending' is not empty, Daq appends % the ending to the file name before saving. In this way the % default way of generating unique file names by Daq can be % overwritten. filename_ending = '' end methods % Use parser to process properties supplied as name-value pairs via % varargin - function this=MyNewDataEvent(varargin) - P=MyClassParser(this); - addParameter(P, 'Trace', []); + function this = MyNewDataEvent(varargin) + P = MyClassParser(this); processInputs(P, this, varargin{:}); end end %% Set and get methods methods % Ensures that the source name is a valid Matlab variable function set.src_name(this, str) assert(ischar(str), ['The value assigned to ''src_name'' ' ... 'must be char']) if ~isempty(str) str=matlab.lang.makeValidName(str); else str='UnknownInstrument'; end this.src_name=str; end function set.Trace(this, Val) assert(isa(Val, 'MyTrace'), ['Trace must be a derivative ' ... 'of MyTrace class.']) this.Trace=Val; end end end \ No newline at end of file diff --git a/@MyTekScope/MyTekScope.m b/@MyTekScope/MyTekScope.m index d13b8d0..cbf215a 100644 --- a/@MyTekScope/MyTekScope.m +++ b/@MyTekScope/MyTekScope.m @@ -1,201 +1,202 @@ classdef MyTekScope < MyScpiInstrument & MyDataSource & MyCommCont properties (GetAccess=public, SetAccess={?MyClassParser,?MyTekScope}) % number of channels channel_no = 4 % List of the physical knobs, which can be rotated programmatically knob_list = {} end methods (Access = public) function this = MyTekScope(varargin) this@MyCommCont(varargin{:}); P = MyClassParser(this); processInputs(P, this, varargin{:}); this.Comm.InputBufferSize = 4.1e7; %byte this.Comm.ByteOrder = 'bigEndian'; end function readTrace(this) % Configure data transfer: binary format and two bytes per % point. Then query the trace. - writeCommand(this, ... + writeStrings(this, ... ':WFMInpre:ENCdg BINary', ... ':DATA:WIDTH 2', ... ':DATA:STARt 1', ... sprintf(':DATA:STOP %i', this.point_no), ... ':CURVE?'); - y_data = int16(binblockread(this.Comm, 'int16')); + y_data = double(binblockread(this.Comm, 'int16')); if this.Comm.BytesAvailable~=0 - % read the terminating character + % Read the terminating character fscanf(this.Comm, '%s'); end % Read units, offsets and steps for the scales - parms = queryCommand(this, ... + parms = queryStrings(this, ... ':WFMOutpre:XUNit?', ... ':WFMOutpre:YUNit?', ... - ':WFMOutpre:YMUlt?', ... ':WFMOutpre:XINcr?', ... + ':WFMOutpre:YMUlt?', ... ':WFMOutpre:XZEro?', ... ':WFMOutpre:YZEro?', ... ':WFMOutpre:YOFf?'); - [unit_y, unit_x, step_x, step_y, x_zero, ... - y_zero, y_offset] = parms{:}; - + [unit_x, unit_y] = parms{1:2}; + num_params = num2cell(str2double(parms(3:end))); + [step_x, step_y, x_zero, y_zero, y_offset] = num_params{:}; + % Calculating the y data - y = (double(y_data)-y_offset)*step_y+y_zero; + y = (y_data-y_offset)*step_y+y_zero; n_points = length(y); % Calculating the x data - x = linspace(x_zero, x_zero+step_x*(n_points-1), n_points); + x = linspace(x_zero, x_zero + step_x*(n_points-1), n_points); this.Trace.x = x; this.Trace.y = y; % Discard "" when assiging the Trace labels this.Trace.unit_x = unit_x(2:end-1); this.Trace.unit_y = unit_y(2:end-1); triggerNewData(this); end function acquireContinuous(this) writeCommand(this, ... ':ACQuire:STOPAfter RUNSTop', ... ':ACQuire:STATE ON'); end function acquireSingle(this) writeCommand(this, ... ':ACQuire:STOPAfter SEQuence', ... ':ACQuire:STATE ON'); end function turnKnob(this, knob, nturns) is_knob_valid = ismember(lower(knob), lower(this.knob_list)); assert(is_knob_valid, ['Knob must be a member of the ' ... 'scope knob list: ', newline, var2str(this.knob_list)]) writeCommand(this, ... sprintf(':FPAnel:TURN %s,%i', knob, nturns)); end end methods (Access = protected) function createCommandList(this) addCommand(this, 'channel',':DATa:SOUrce',... 'format', 'CH%i',... 'info', 'Channel from which the trace is transferred', ... 'value_list', {1, 2, 3, 4}, ... 'default', 1); addCommand(this, 'ctrl_channel', ':SELect:CONTROl',... 'format', 'CH%i',... 'info', 'Channel currently selected in the scope display', ... 'default', 1); addCommand(this, 'point_no', ':HORizontal:RECOrdlength', ... 'format', '%i', ... 'info', 'Numbers of points in the scope trace', ... 'value_list', {1000, 10000, 100000, 1000000, 10000000}, ... 'default', 100000); addCommand(this, 'time_scale', ':HORizontal:SCAle', ... 'format', '%e', ... 'info', 'Time scale (s/div)', ... 'default', 10E-3); addCommand(this, 'trig_lev', ':TRIGger:A:LEVel',... 'format', '%e', ... 'info', '(V)', ... 'default', 1); addCommand(this, 'trig_slope', ':TRIGger:A:EDGE:SLOpe',... 'format', '%s', ... 'value_list', {'RISe','FALL'}, ... 'default', 'RISe'); addCommand(this, 'trig_source', ':TRIGger:A:EDGE:SOUrce',... 'value_list', {'CH1','CH2','CH3','CH4', ... 'AUX','EXT','LINE'}, ... 'format', '%s', ... 'default', 'AUX'); addCommand(this, 'trig_mode', ':TRIGger:A:MODe', ... 'format', '%s', ... 'value_list', {'AUTO','NORMal'}, ... 'default', 'AUTO'); addCommand(this, 'acq_state', ':ACQuire:STATE', ... 'format', '%b',... 'info', 'State of data acquisition by the scope', ... 'default', true); addCommand(this, 'acq_mode', ':ACQuire:MODe', ... 'format', '%s', ... 'info', ['Acquisition mode: sample, peak ' ... 'detect, high resolution, average or envelope'], ... 'value_list',{'SAMple', 'PEAKdetect', 'HIRes', ... 'AVErage', 'ENVelope'}, ... 'default', 'HIRes'); % Parametric commands for i = 1:this.channel_no i_str = num2str(i); addCommand(this,... ['cpl',i_str],[':CH',i_str,':COUP'],... 'default','DC', ... 'value_list', {'AC','DC','GND'},... 'format','%s',... 'info','Channel coupling: AC, DC or GND'); % impedances, 1MOhm or 50 Ohm addCommand(this,... ['imp', i_str], [':CH', i_str, ':IMPedance'],... 'format', '%s',... 'info', 'Channel impedance: 1 MOhm or 50 Ohm', ... 'value_list', {'FIFty','MEG'}, ... 'default', 'MEG'); % Offset addCommand(this, ... ['offset',i_str], [':CH',i_str,':OFFSet'], ... 'format', '%e', ... 'info', '(V)', ... 'default', 0); addCommand(this, ... ['scale',i_str], [':CH',i_str,':SCAle'], ... 'format', '%e', ... 'info', 'Channel y scale (V/div)', ... 'default', 1); addCommand(this,... ['enable',i_str], [':SEL:CH',i_str], ... 'format', '%b',... 'info', 'Channel enabled', ... 'default', true); end end end methods function set.knob_list(this, val) assert(iscellstr(val), ['Value must be a cell array of ' ... 'character strings.']) %#ok this.knob_list = val; end end end diff --git a/Utility functions/str2doubleHedged.m b/Utility functions/str2doubleHedged.m index 99b2fbe..027e684 100644 --- a/Utility functions/str2doubleHedged.m +++ b/Utility functions/str2doubleHedged.m @@ -1,10 +1,11 @@ -function [val,str_spec]=str2doubleHedged(str) - conv_str=str2double(str); +function [val, str_spec] = str2doubleHedged(str) + + conv_str = str2double(str); if ~isnan(conv_str) - val=conv_str; - str_spec='%e'; + val = conv_str; + str_spec = '%e'; else - val=str; - str_spec='%s'; + val = str; + str_spec = '%s'; end end \ No newline at end of file