Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F98341583
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Jan 12, 06:51
Size
44 KB
Mime Type
text/x-diff
Expires
Tue, Jan 14, 06:51 (1 d, 20 h)
Engine
blob
Format
Raw Data
Handle
23564919
Attached To
rINSTCONTROL Instrument Control
View Options
diff --git a/@MyFit/MyFit.m b/@MyFit/MyFit.m
index 71df620..234f57d 100644
--- a/@MyFit/MyFit.m
+++ b/@MyFit/MyFit.m
@@ -1,277 +1,286 @@
classdef MyFit < handle
properties
Gui
Data;
Fit;
Parser;
fit_name='linear'
init_params=[];
scale_init=[];
lim_lower;
lim_upper;
FitStruct;
Fitdata;
coeffs;
enable_gui=1;
enable_plot;
plot_handle;
hline_init;
end
properties (Dependent=true)
fit_function;
fit_tex;
fit_params;
fit_param_names;
valid_fit_names;
n_params;
scaled_params;
init_param_fun;
end
+ events
+ PerformedFit;
+ end
+
methods
function this=MyFit(varargin)
createFitStruct(this);
createParser(this);
parse(this.Parser,varargin{:});
parseInputs(this);
if ismember('Data',this.Parser.UsingDefaults) &&...
~ismember('x',this.Parser.UsingDefaults) &&...
~ismember('y',this.Parser.UsingDefaults)
this.Data.x=this.Parser.Results.x;
this.Data.y=this.Parser.Results.y;
end
if ~isempty(this.Data.x) || ~isempty(this.Data.y)
genInitParams(this);
else
this.init_params=ones(1,this.n_params);
end
this.scale_init=ones(1,this.n_params);
if this.enable_gui
createGui(this);
end
end
%Creates the GUI of MyFit
createGui(this);
function delete(this)
if this.enable_gui
set(this.Gui.Window,'CloseRequestFcn','');
%Deletes the figure
delete(this.Gui.Window);
%Removes the figure handle to prevent memory leaks
this.Gui=[];
end
end
-
+
%Close figure callback simply calls delete function for class
function closeFigure(this,~,~)
delete(this);
end
function createParser(this)
p=inputParser;
addParameter(p,'fit_name','linear',@ischar)
addParameter(p,'Data',MyTrace());
addParameter(p,'Fit',MyTrace());
addParameter(p,'x',[]);
addParameter(p,'y',[]);
addParameter(p,'enable_gui',1);
addParameter(p,'enable_plot',0);
addParameter(p,'plot_handle',[]);
this.Parser=p;
end
%Sets the class variables to the inputs from the inputParser.
function parseInputs(this)
for i=1:length(this.Parser.Parameters)
%Takes the value from the inputParser to the appropriate
%property.
if isprop(this,this.Parser.Parameters{i})
this.(this.Parser.Parameters{i})=...
this.Parser.Results.(this.Parser.Parameters{i});
end
end
end
function fitTrace(this)
this.Fit.x=linspace(min(this.Data.x),max(this.Data.x),1e3);
switch this.fit_name
case 'linear'
this.coeffs=polyfit(this.Data.x,this.Data.y,1);
this.Fit.y=polyval(this.coeffs,this.Fit.x);
case 'quadratic'
this.coeffs=polyfit(this.Data.x,this.Data.y,2);
this.Fit.y=polyval(this.coeffs,this.Fit.x);
case {'exponential','gaussian','lorentzian'}
- this.doFit
+ doFit(this);
this.coeffs=coeffvalues(this.Fitdata);
this.Fit.y=this.Fitdata(this.Fit.x);
otherwise
- this.doFit;
+ doFit(this);
this.Fit.y=this.Fitdata(this.Fit.x);
this.coeffs=coeffvalues(this.Fitdata);
end
this.init_params=this.coeffs;
this.scale_init=ones(1,this.n_params);
+ triggerPerformedFit(this);
if this.enable_gui; updateGui(this); end
if this.enable_plot; plotFit(this); end
end
function doFit(this)
this.Fitdata=fit(this.Data.x,this.Data.y,this.fit_function,...
'Lower',this.lim_lower,'Upper',this.lim_upper,...
'StartPoint',this.init_params);
end
+ function triggerPerformedFit(this)
+ notify(this,'PerformedFit');
+ end
+
function plotFit(this)
plot(this.plot_handle,this.Fit.x,this.Fit.y);
end
function createFitStruct(this)
%Adds fits
addFit(this,'linear','a*x+b','$$ax+b$$',{'a','b'},...
{'Gradient','Offset'})
addFit(this,'quadratic','a*x^2+b*x+c','$$ax^2+bx+c$$',...
{'a','b','c'},{'Quadratic coeff.','Linear coeff.','Offset'});
addFit(this,'gaussian','a*exp(-((x-c)/b)^2/2)+d',...
'$$ae^{-\frac{(x-c)^2}{2b^2}}+d$$',{'a','b','c','d'},...
{'Amplitude','Width','Center','Offset'});
addFit(this,'lorentzian','a/(pi)*(b/2/((x-c)^2+(b/2)^2))+d',...
'$$\frac{a}{1+\frac{b/2}{(x-c)^2+(b/2)^2}}+d$$',{'a','b','c','d'},...
{'Amplitude','Width','Center','Offset'});
addFit(this,'exponential','a*exp(b*x)+c',...
'$$ae^{bx}+c$$',{'a','b','c'},...
{'Amplitude','Rate','Offset'});
end
function updateGui(this)
%Converts the scale variable to the value between 0 and 100
%necessary for the slider
slider_vals=25*log10(this.scale_init)+50;
for i=1:this.n_params
set(this.Gui.(sprintf('edit_%s',this.fit_params{i})),...
'String',sprintf('%3.3e',this.scaled_params(i)));
set(this.Gui.(sprintf('slider_%s',this.fit_params{i})),...
'Value',slider_vals(i));
end
end
%Adds a fit to the list of fits
function addFit(this,fit_name,fit_function,fit_tex,fit_params,...
fit_param_names)
this.FitStruct.(fit_name).fit_function=fit_function;
this.FitStruct.(fit_name).fit_tex=fit_tex;
this.FitStruct.(fit_name).fit_params=fit_params;
this.FitStruct.(fit_name).fit_param_names=fit_param_names;
%Generates the anonymous fit function from the above
args=['@(x,', strjoin(fit_params,','),')'];
anon_fit_fun=str2func(vectorize([args,fit_function]));
this.FitStruct.(fit_name).anon_fit_fun=anon_fit_fun;
end
function genInitParams(this)
switch this.fit_name
case 'exponential'
[this.init_params,this.lim_lower,this.lim_upper]=...
initParamExponential(this.Data.x,this.Data.y);
case 'gaussian'
[this.init_params,this.lim_lower,this.lim_upper]=...
initParamGaussian(this.Data.x,this.Data.y);
case 'lorentzian'
[this.init_params,this.lim_lower,this.lim_upper]=...
initParamLorentzian(this.Data.x,this.Data.y);
otherwise
this.init_params=ones(1,this.n_params);
end
end
function slider_Callback(this, param_ind, hObject, ~)
%Gets the value from the slider
scale=get(hObject,'Value');
%Updates the scale with a new value
this.scale_init(param_ind)=10^((scale-50)/25);
%Updates the edit box with the new value from the slider
set(this.Gui.(sprintf('edit_%s',this.fit_params{param_ind})),...
'String',sprintf('%3.3e',this.scaled_params(param_ind)));
if this.enable_plot; plotInitFun(this); end
end
function edit_Callback(this, hObject, ~)
init_param=str2double(get(hObject,'String'));
tag=get(hObject,'Tag');
%Finds the index where the fit_param name begins (convention is
%after the underscore)
fit_param=tag((strfind(tag,'_')+1):end);
param_ind=strcmp(fit_param,this.fit_params);
%Updates the slider to be such that the scaling is 1
set(this.Gui.(sprintf('slider_%s',fit_param)),...
'Value',50);
%Updates the correct initial parameter
this.init_params(param_ind)=init_param;
if this.enable_plot; plotInitFun(this); end
end
function plotInitFun(this)
%Substantially faster than any alternative - generating
%anonymous functions is very cpu intensive.
x_vec=linspace(min(this.Data.x),max(this.Data.x),1000);
input_cell=num2cell(this.scaled_params);
y_vec=feval(this.FitStruct.(this.fit_name).anon_fit_fun,x_vec,...
input_cell{:});
if isempty(this.hline_init)
this.hline_init=plot(this.plot_handle,x_vec,y_vec);
else
set(this.hline_init,'XData',x_vec,'YData',y_vec);
end
end
function set.fit_name(this,fit_name)
assert(ischar(fit_name),'The fit name must be a string');
this.fit_name=lower(fit_name);
end
function valid_fit_names=get.valid_fit_names(this)
valid_fit_names=fieldnames(this.FitStruct);
end
function fit_function=get.fit_function(this)
assert(ismember(this.fit_name,this.valid_fit_names),...
'%s is not a supported fit name',this.fit_name);
fit_function=this.FitStruct.(this.fit_name).fit_function;
end
function fit_tex=get.fit_tex(this)
assert(ismember(this.fit_name,this.valid_fit_names),...
'%s is not a supported fit name',this.fit_name);
fit_tex=this.FitStruct.(this.fit_name).fit_tex;
end
function fit_params=get.fit_params(this)
assert(ismember(this.fit_name,this.valid_fit_names),...
'%s is not a supported fit name',this.fit_name);
fit_params=this.FitStruct.(this.fit_name).fit_params;
end
function fit_param_names=get.fit_param_names(this)
assert(ismember(this.fit_name,this.valid_fit_names),...
'%s is not a supported fit name',this.fit_name);
fit_param_names=this.FitStruct.(this.fit_name).fit_param_names;
end
function scaled_params=get.scaled_params(this)
scaled_params=this.scale_init.*this.init_params;
end
function n_params=get.n_params(this)
n_params=length(this.fit_params);
end
end
end
\ No newline at end of file
diff --git a/@MyInstrument/MyInstrument.m b/@MyInstrument/MyInstrument.m
index 62009b4..956a949 100644
--- a/@MyInstrument/MyInstrument.m
+++ b/@MyInstrument/MyInstrument.m
@@ -1,242 +1,251 @@
classdef MyInstrument < handle
properties (SetAccess=protected, GetAccess=public)
name='';
interface='';
address='';
axes_handle=[];
%Logical for whether gui is enabled
enable_gui=false;
%Contains the GUI handles
Gui;
%Contains the device object
Device;
%Input parser for class constructor
Parser;
%Contains a list of the commands available for the instrument as
%well as the default values and input requirements
CommandList;
%Parses commands using an inputParser object
CommandParser;
end
properties (Dependent=true)
command_names;
command_no;
end
+ events
+ AcquiredData;
+ end
+
methods
function this=MyInstrument(name, interface, address, varargin)
createParser(this);
parse(this.Parser,name,interface,address,varargin{:});
%Loads parsed variables into class properties
this.name=this.Parser.Results.name;
this.interface=this.Parser.Results.interface;
this.address=this.Parser.Results.address;
this.enable_gui=~ismember('gui',this.Parser.UsingDefaults);
this.axes_handle=this.Parser.Results.axes_handle;
try
openDevice(this);
closeDevice(this);
catch
error(['Failed to open communications with device.',...
' Check that the address and interface is correct'])
end
%If a gui input is given, load the gui
if this.enable_gui
%Loads the gui from the input gui string
this.Gui=guihandles(eval(this.Parser.Results.gui));
%Sets figure close function such that class will know when
%figure is closed
set(this.Gui.figure1, 'CloseRequestFcn',...
@(hObject,eventdata) closeFigure(this, hObject, ...
eventdata));
end
end
+ %Triggers event for acquired data
+ function triggerAcquiredData(this)
+ notify(this,'AcquiredData')
+ end
+
function delete(this)
%Removes close function from figure, prevents infinite loop
if this.enable_gui
set(this.Gui.figure1,'CloseRequestFcn','');
%Deletes the figure
delete(this.Gui.figure1);
%Removes the figure handle to prevent memory leaks
this.Gui=[];
end
%Closes the connection to the device
closeDevice(this);
%Deletes the device object
delete(this.Device);
clear('this.Device');
end
end
methods
%Checks if the connection to the device is open
function bool=isopen(this)
bool=strcmp(this.Device.Status, 'open');
end
function createParser(this)
p=inputParser;
addRequired(p,'name',@ischar);
addRequired(p,'interface',@ischar);
addRequired(p,'address',@ischar);
addParameter(p,'gui','placeholder',@ischar);
addParameter(p,'axes_handle',[]);
this.Parser=p;
end
%Sends a read command to the device
function result=read(this,command)
result=query(this.Device, command);
end
%Writes to the device
function write(this, command)
fprintf(this.Device, command);
end
function writeProperty(this, varargin)
%Parses the inputs using the CommandParser
parse(this.CommandParser, varargin{:});
%Finds the commands that are supplied by the user
ind=~ismember(this.CommandParser.Parameters,...
this.CommandParser.UsingDefaults);
%Creates a list of commands to be executed
exec=this.CommandParser.Parameters(ind);
for i=1:length(exec)
command=sprintf(this.CommandList.(exec{i}).command,...
this.CommandParser.Results.(exec{i}));
write(this, command);
end
end
function result=readProperty(this, varargin)
result=struct();
for i=1:length(varargin)
%Finds the index of the % sign which indicates where the value
%to be written is supplied
ind=strfind(this.CommandList.(varargin{i}).command,'%');
if ~any(ind)
error('%s is not a valid tag for a command in %s',...
varargin{i},class(this));
end
%Creates the correct read command
read_command=...
[this.CommandList.(varargin{i}).command(1:(ind-2)),'?'];
%Reads the property from the device and stores it in the
%correct place
result.(varargin{i})=str2double(this.read(read_command));
end
end
%Adds a command to the CommandList
function addCommand(this, tag, command, varargin)
p=inputParser;
addRequired(p,'tag',@ischar);
addRequired(p,'command',@ischar);
addParameter(p,'default','placeholder');
addParameter(p,'attributes','placeholder',@iscell)
%If the write flag is on, it means this command can be used to
%write a parameter to the device
addParameter(p,'write_flag',false,@islogical)
parse(p,tag,command,varargin{:});
if ~isprop(this, tag) && p.Results.write_flag
error('All commands must have a tag matching the property they modify')
end
%Adds the command to be sent to the device
this.CommandList.(tag).command=command;
this.CommandList.(tag).write_flag=p.Results.write_flag;
%Adds a default value and the attributes the inputs must have
if p.Results.write_flag
%Adds the default value
this.CommandList.(tag).default=p.Results.default;
%Adds the necessary attributes for the input to the command
this.CommandList.(tag).attributes=p.Results.attributes;
end
end
%Creates inputParser using the command list
function createCommandParser(this)
%Use input parser
%Requires input of the appropriate class
p=inputParser;
p.StructExpand=0;
for i=1:this.command_no
%Adds optional inputs for each command, with the
%appropriate default value from the command list and the
%required attributes for the command input.
addParameter(p, this.command_names{i},...
this.CommandList.(this.command_names{i}).default),...
@(x) validateattributes(x,...
this.CommandList.(this.command_names{i}).attributes{1:end});
end
this.CommandParser=p;
end
%Connects to the device if it is not connected
function openDevice(this)
if ~isopen(this)
try
fopen(this.Device);
catch
try
instr_list=instrfind('RemoteHost',this.address);
fclose(instr_list);
fopen(this.Device);
warning('Multiple instrument objects of address %s exist',...
this.address);
catch
error('Could not open device')
end
end
end
end
%Closes the connection to the device
function closeDevice(this)
if isopen(this)
try
fclose(this.Device);
catch
error('Could not close device')
end
end
end
%Close figure callback simply calls delete function for class
function closeFigure(this,~,~)
delete(this);
end
function command_names=get.command_names(this)
command_names=fieldnames(this.CommandList);
end
function command_no=get.command_no(this)
command_no=length(this.command_names);
end
end
end
\ No newline at end of file
diff --git a/@MyNa/MyNa.m b/@MyNa/MyNa.m
index 1b80c26..733896a 100644
--- a/@MyNa/MyNa.m
+++ b/@MyNa/MyNa.m
@@ -1,112 +1,113 @@
classdef MyNa < MyInstrument
properties (SetAccess=protected, GetAccess=public)
ifbw;
start_freq;
stop_freq;
cent_freq;
span;
power;
Trace;
end
+
methods
function this=MyNa(name, interface, address, varargin)
this@MyInstrument(name, interface, address,varargin{:});
createCommandList(this);
createCommandParser(this);
if this.enable_gui; initGui(this); end
end
function createCommandList(this)
addCommand(this,'cent_freq','SENS:FREQ:CENT %d',...
'default',1.5e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this,'start_freq','SENS:FREQ:START %d',...
'default',1e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this,'stop_freq','SENS:FREQ:STOP %d',...
'default',2e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this,'span','SENS:FREQ:SPAN %d',...
'default',1e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this,'power','SOUR:POW:LEV:IMM:AMPL %d',...
'default',1,'attributes',{{'numeric'}},'write_flag',true);
end
function initGui(this)
set(this.Gui.reinit, 'Callback',...
@(hObject, eventdata) reinitCallback(this, hObject,...
eventdata));
set(this.Gui.start_freq, 'Callback',...
@(hObject, eventdata) start_freqCallback(this, hObject,...
eventdata));
set(this.Gui.stop_freq, 'Callback',...
@(hObject, eventdata) stop_freqCallback(this, hObject,...
eventdata));
set(this.Gui.cent_freq, 'Callback',...
@(hObject, eventdata) cent_freqCallback(this, hObject,...
eventdata));
set(this.Gui.span, 'Callback',...
@(hObject, eventdata) spanCallback(this, hObject,...
eventdata));
set(this.Gui.ifbw, 'Callback',...
@(hObject, eventdata) rbwCallback(this, hObject,...
eventdata));
set(this.Gui.fetch_single, 'Callback',...
@(hObject, eventdata) fetchCallback(this, hObject,...
eventdata));
set(this.Gui.average_no, 'Callback',...
@(hObject, eventdata) average_noCallback(this, hObject,...
eventdata));
set(this.Gui.enable_avg, 'Callback',...
@(hObject, eventdata) enable_avgCallback(this, hObject,...
eventdata));
end
function start_freqCallback(this, hObject, eventdata)
this.start_freq=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'start_freq',this.start_freq);
readStatus(this);
closeDevice(this);
end
function stop_freqCallback(this, hObject, eventdata)
this.stop_freq=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'stop_freq',this.stop_freq);
readStatus(this);
closeDevice(this);
end
function cent_freqCallback(this, hObject, eventdata)
this.cent_freq=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'cent_freq',this.cent_freq);
readStatus(this);
closeDevice(this);
end
function spanCallback(this, hObject, eventdata)
this.span=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'span',this.span);
readStatus(this)
closeDevice(this);
end
function ifbwCallback(this, hObject, eventdata)
this.ifbw=str2double(get(hObject,'String'))*1e3;
openDevice(this);
writeProperty(this,'ifbw',this.ifbw);
closeDevice(this);
end
function average_noCallback(this, hObject, eventdata)
this.average_no=str2double(get(hObject,'String'));
%Writes the average_no to the device only if averaging is
%enabled
openDevice(this);
writeProperty(this,'average_no',this.average_no);
closeDevice(this);
end
end
end
diff --git a/@MyRsa/MyRsa.m b/@MyRsa/MyRsa.m
index 80c9554..2881c96 100644
--- a/@MyRsa/MyRsa.m
+++ b/@MyRsa/MyRsa.m
@@ -1,346 +1,346 @@
classdef MyRsa < MyInstrument
properties (SetAccess=protected, GetAccess=public)
rbw;
start_freq;
stop_freq;
cent_freq;
span;
average_no;
point_no;
enable_avg;
read_cont;
Trace;
valid_points;
end
properties (Dependent=true)
freq_vec;
end
methods
function this=MyRsa(name,interface, address,varargin)
this@MyInstrument(name, interface, address,varargin{:});
- if this.enable_gui; initGui(this); end;
+ if this.enable_gui; initGui(this); end
%Valid point numbers for Tektronix 5103 and 5106.
%Depends on the RSA. Remove this in the future.
this.valid_points=[801,2401,4001,10401];
createCommandList(this);
createCommandParser(this);
switch interface
case 'TCPIP'
connectTCPIP(this);
end
%Opens communications
openDevice(this);
%Finds the current status of the device
readStatus(this);
%Initializes the device
initDevice(this);
closeDevice(this);
end
end
methods
function connectTCPIP(this)
buffer = 1000 * 1024;
visa_brand = 'ni';
visa_address_rsa = sprintf('TCPIP0::%s::inst0::INSTR',...
this.address);
this.Device=visa(visa_brand, visa_address_rsa,...
'InputBufferSize', buffer,...
'OutputBufferSize', buffer);
set(this.Device,'InputBufferSize',1e6);
set(this.Device,'Timeout',10);
end
function readStatus(this)
result=readProperty(this,'rbw','cent_freq','span','start_freq',...
'stop_freq','enable_avg');
res_names=fieldnames(result);
for i=1:length(res_names)
this.(res_names{i})=result.(res_names{i});
end
end
function initGui(this)
set(this.Gui.reinit, 'Callback',...
@(hObject, eventdata) reinitCallback(this, hObject,...
eventdata));
set(this.Gui.point_no, 'Callback',...
@(hObject, eventdata) point_noCallback(this, hObject,...
eventdata));
set(this.Gui.start_freq, 'Callback',...
@(hObject, eventdata) start_freqCallback(this, hObject,...
eventdata));
set(this.Gui.stop_freq, 'Callback',...
@(hObject, eventdata) stop_freqCallback(this, hObject,...
eventdata));
set(this.Gui.cent_freq, 'Callback',...
@(hObject, eventdata) cent_freqCallback(this, hObject,...
eventdata));
set(this.Gui.span, 'Callback',...
@(hObject, eventdata) spanCallback(this, hObject,...
eventdata));
set(this.Gui.rbw, 'Callback',...
@(hObject, eventdata) rbwCallback(this, hObject,...
eventdata));
set(this.Gui.fetch_single, 'Callback',...
@(hObject, eventdata) fetchCallback(this, hObject,...
eventdata));
set(this.Gui.average_no, 'Callback',...
@(hObject, eventdata) average_noCallback(this, hObject,...
eventdata));
set(this.Gui.enable_avg, 'Callback',...
@(hObject, eventdata) enable_avgCallback(this, hObject,...
eventdata));
end
function initDevice(this)
for i=1:this.command_no
if this.CommandList.(this.command_names{i}).write_flag
write(this, ...
sprintf(this.CommandList.(this.command_names{i}).command,...
this.CommandList.(this.command_names{i}).default));
this.(this.command_names{i})=...
this.CommandList.(this.command_names{i}).default;
end
end
end
- function reinitCallback(this, hObject, eventdata)
+ function reinitCallback(this, hObject, ~)
reinitDevice(this);
%Turns off indicator
set(hObject,'Value',0);
end
function reinitDevice(this)
openDevice(this);
readStatus(this);
initDevice(this);
writeProperty(this, 'read_cont','on')
closeDevice(this);
end
- function point_noCallback(this, hObject, eventdata)
+ function point_noCallback(this, hObject, ~)
value_list=get(hObject,'String');
this.point_no=str2double(value_list{get(hObject,'Value')});
openDevice(this);
writeProperty(this,'point_no',this.point_no);
readStatus(this);
closeDevice(this);
end
- function start_freqCallback(this, hObject, eventdata)
+ function start_freqCallback(this, hObject, ~)
this.start_freq=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'start_freq',this.start_freq);
readStatus(this);
closeDevice(this);
end
- function stop_freqCallback(this, hObject, eventdata)
+ function stop_freqCallback(this, hObject, ~)
this.stop_freq=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'stop_freq',this.stop_freq);
readStatus(this);
closeDevice(this);
end
- function cent_freqCallback(this, hObject, eventdata)
+ function cent_freqCallback(this, hObject, ~)
this.cent_freq=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'cent_freq',this.cent_freq);
readStatus(this);
closeDevice(this);
end
- function spanCallback(this, hObject, eventdata)
+ function spanCallback(this, hObject, ~)
this.span=str2double(get(hObject,'String'))*1e6;
openDevice(this);
writeProperty(this,'span',this.span);
readStatus(this)
closeDevice(this);
end
- function rbwCallback(this, hObject, eventdata)
+ function rbwCallback(this, hObject, ~)
this.rbw=str2double(get(hObject,'String'))*1e3;
openDevice(this);
writeProperty(this,'rbw',this.rbw);
closeDevice(this);
end
- function average_noCallback(this, hObject, eventdata)
+ function average_noCallback(this, hObject, ~)
this.average_no=str2double(get(hObject,'String'));
%Writes the average_no to the device only if averaging is
%enabled
openDevice(this);
writeProperty(this,'average_no',this.average_no);
closeDevice(this);
end
function createCommandList(this)
addCommand(this,'average_no','TRAC3:DPSA:AVER:COUN %d',...
'default',1,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this, 'rbw','DPSA:BAND:RES %d Hz',...
'default',1e3,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this, 'span', 'DPSA:FREQ:SPAN %d Hz',...
'default',1e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this, 'start_freq','DPSA:FREQ:STAR %d Hz',...
'default',1e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this, 'stop_freq','DPSA:FREQ:STOP %d Hz',...
'default',2e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this, 'cent_freq','DPSA:FREQ:CENT %d Hz',...
'default',1.5e6,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this, 'point_no','DPSA:POIN:COUN P%d',...
'default',10401,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this,'enable_avg','TRAC3:DPSA:COUN:ENABLE %d',...
'default',0,'attributes',{{'numeric'}},'write_flag',true);
addCommand(this,'read_cont','INIT:CONT %s','default','on',...
'attributes',{{'char'}},'write_flag',true);
end
- function fetchCallback(this, hObject, eventdata)
+ function fetchCallback(this, hObject, ~)
%Fetches the data using the settings given. This function can
%in principle be used in the future to add further fetch
%functionality.
switch get(hObject,'Tag')
case 'fetch_single'
readSingle(this)
-
end
set(this.Gui.fetch_single,'Value',0);
end
- function enable_avgCallback(this, hObject, eventdata)
+ function enable_avgCallback(this, hObject, ~)
this.enable_avg=get(hObject,'Value');
openDevice(this)
writeProperty(this,'enable_avg',this.enable_avg);
closeDevice(this);
end
function readSingle(this)
openDevice(this);
readStatus(this);
fwrite(this.Device, 'fetch:dpsa:res:trace3?');
data = binblockread(this.Device,'float');
closeDevice(this);
x=this.freq_vec/1e6;
unit_x='MHz';
name_x='Frequency';
%Calculates the power spectrum from the data, which is in dBm.
%Output is in V^2/Hz
power_spectrum = (10.^(data/10))/this.rbw*50*0.001;
-
%Trace object is created containing the data and its units
this.Trace=MyTrace('name','RsaData','x',x,'y',power_spectrum,'unit_y',...
'$\mathrm{V}^2/\mathrm{Hz}$','name_y','Power','unit_x',...
unit_x,'name_x',name_x);
+ %Trigger acquired data event (inherited from MyInstrument)
+ triggerAcquiredData(this);
%Plotting for test purposes - to be removed in the future
figure
this.Trace.plotTrace(gca);
end
end
methods
%Set function for central frequency, changes gui to show central
%frequency in MHz
function set.cent_freq(this, cent_freq)
this.cent_freq=cent_freq;
if this.enable_gui
set(this.Gui.cent_freq,'String',this.cent_freq/1e6);
end
end
%Set function for rbw, changes gui to show rbw in kHz
function set.rbw(this, rbw)
assert(isnumeric(rbw) && rbw>0,'RBW must be a positive double');
this.rbw=rbw;
if this.enable_gui
set(this.Gui.rbw,'String',this.rbw/1e3);
end
end
%Set function for enable_avg, changes gui
function set.enable_avg(this, enable_avg)
assert(isnumeric(enable_avg),...
'Flag for averaging must be a number')
assert(enable_avg==1 || enable_avg==0,...
'Flag for averaging must be 0 or 1')
this.enable_avg=enable_avg;
if this.enable_gui
set(this.Gui.enable_avg,'Value',this.enable_avg)
end
end
%Set function for span, changes gui to show span in MHz
function set.span(this, span)
assert(isnumeric(span) && span>0,...
'Span must be a positive number');
this.span=span;
if this.enable_gui
set(this.Gui.span,'String',this.span/1e6);
end
end
%Set function for start frequency, changes gui to show start
%frequency in MHz
function set.start_freq(this, start_freq)
assert(isnumeric(start_freq),'Start frequency must be a number');
this.start_freq=start_freq;
if this.enable_gui
set(this.Gui.start_freq,'String',this.start_freq/1e6);
end
end
%Set function for stop frequency, changes gui to show stop
%frequency in MHz
function set.stop_freq(this, stop_freq)
assert(isnumeric(stop_freq),...
'Stop frequency must be a number');
this.stop_freq=stop_freq;
if this.enable_gui
set(this.Gui.stop_freq,'String',this.stop_freq/1e6)
end
end
%Set function for average number, also changes GUI
function set.average_no(this, average_no)
assert(isnumeric(average_no),'Number of averages must be a number')
assert(logical(mod(average_no,1))==0 && average_no>0,...
'Number of averages must be a positive integer')
this.average_no=average_no;
if this.enable_gui
set(this.Gui.average_no,'String',this.average_no);
end
end
%Set function for point number, checks it is valid and changes GUI
function set.point_no(this, point_no)
bool=ismember(point_no,this.valid_points);
if bool
this.point_no=point_no;
if this.enable_gui
ind=strcmp(get(this.Gui.point_no,'String'),...
num2str(point_no));
set(this.Gui.point_no,'Value',find(ind));
end
else
error('Invalid number of points chosen for RSA')
end
end
end
methods
%Generates a vector of frequencies between the start and stop
%frequency of length equal to the point number
function freq_vec=get.freq_vec(this)
freq_vec=linspace(this.start_freq,this.stop_freq,...
this.point_no) ;
end
end
end
diff --git a/@MyScope/MyScope.m b/@MyScope/MyScope.m
index f5251ab..65ddca9 100644
--- a/@MyScope/MyScope.m
+++ b/@MyScope/MyScope.m
@@ -1,110 +1,117 @@
classdef MyScope <MyInstrument
properties
Trace;
channel;
end
+ events
+ AcquiredTrace;
+ end
+
methods
function this=MyScope(name, interface, address, varargin)
this@MyInstrument(name, interface, address, varargin{:});
if this.enable_gui; initGui(this); end
createCommandList(this);
createCommandParser(this);
switch interface
case 'TCPIP'
connectTCPIP(this);
case 'USB'
connectUSB(this);
end
end
function connectTCPIP(this)
this.Device= visa('ni',...
sprintf('TCPIP0::%s::inst0::INSTR',this.address));
set(this.Device,'InputBufferSize',1e6);
set(this.Device,'Timeout',2);
end
function connectUSB(this)
this.Device=visa('ni',sprintf('USB0::%s::INSTR',this.address));
set(this.Device,'InputBufferSize',1e6);
set(this.Device,'Timeout',2);
end
-
+
function initGui(this)
set(this.Gui.channel_select, 'Callback',...
@(hObject, eventdata) channel_selectCallback(this, ...
hObject,eventdata));
set(this.Gui.fetch_single, 'Callback',...
@(hObject, eventdata) fetch_singleCallback(this, ...
hObject,eventdata));
set(this.Gui.cont_read, 'Callback',...
@(hObject, eventdata) cont_readCallback(this, ...
hObject,eventdata));
end
function channel_selectCallback(this, hObject, eventdata)
this.channel=get(hObject,'Value');
end
function fetch_singleCallback(this,hObject,eventdata)
readTrace(this);
end
function cont_readCallback(this, hObject, eventdata)
while get(hObject,'Value')
readTrace(this)
end
end
function createCommandList(this)
addCommand(this,'channel','DATa:SOUrce CH%d','default',1,...
'attributes',{{'numeric'}},'write_flag',true);
end
end
methods
function set.channel(this, channel)
if any(channel==1:4)
this.channel=channel;
else
this.channel=1;
warning('Select a channel from 1 to 4')
end
%Sets the gui if the gui is enabled
if this.enable_gui
set(this.Gui.channel_select,'Value',this.channel);
end
end
function readTrace(this)
openDevice(this);
%Sets the channel to be read
writeProperty(this,'channel',this.channel);
%Sets the encoding of the data
fprintf(this.Device,'DATa:ENCdg ASCIi');
% Reading the units of x and y
unit_y = strtrim(query(this.Device,'WFMOutpre:YUNit?'));
unit_x = strtrim(query(this.Device,'WFMOutpre:XUNit?'));
% Reading the vertical spacing between points
step_y = str2num(query(this.Device,'WFMOutpre:YMUlt?'));
% Reading the y axis data
y= str2num(query(this.Device,'CURVe?'))*step_y;
n_points=length(y);
% Reading the horizontal spacing between points
x_step=str2num(query(this.Device,'WFMOutpre:XINcr?'));
%Reads where the zero of the x-axis is
x_zero=str2num(query(this.Device,'WFMOutpre:XZEro?'));
- % calculating the x axis
+ % Calculating the x axis
x=linspace(x_zero,x_zero+x_step*(n_points-1),n_points);
closeDevice(this)
this.Trace=MyTrace('name','ScopeTrace','x',x,'y',y,'unit_x',unit_x(2),...
'unit_y',unit_y(2),'name_x','Time','name_y','Voltage');
+ %Triggers the event for acquired data
+ triggerAcquiredData(this);
+
this.Trace.plotTrace(this.plot_handle);
end
end
end
\ No newline at end of file
Event Timeline
Log In to Comment