diff --git a/@MyInstrument/MyInstrument.m b/@MyInstrument/MyInstrument.m new file mode 100644 index 0000000..7daf3eb --- /dev/null +++ b/@MyInstrument/MyInstrument.m @@ -0,0 +1,161 @@ +classdef MyInstrument < handle + + properties (SetAccess=immutable) + name=''; + interface=''; + address=''; + end + + properties (SetAccess=protected, GetAccess=public) + Gui + Device + CommandList + CommandParser + end + + properties (Dependent=true) + command_names + command_no + end + + methods + function this=MyInstrument(name, interface, address, gui_str) + this.name=name; + this.interface=interface; + this.address=address; + %Loads the gui from the input gui string + this.Gui=guihandles(eval(gui_str)); + %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 + + + function delete(this) + %Removes close function from figure, prevents infinite loop + set(this.Gui.figure1,'CloseRequestFcn',''); + %Deletes the figure + delete(this.Gui.figure1); + %Removes the figure handle to prevent memory leaks + this.Gui=[]; + %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 + + %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 + + %Adds a command to the CommandList + function addCommand(this, name, command, default, attributes) + %Checks that the command is named correctly - i.e. it has the + %same name as a property of the class, specifically the one it + %is modifying + if ~isprop(this, name) + error('All commands must have a name matching the property they modify') + end + + %Adds the command to be sent to the device + this.CommandList.(name).command=command; + %Adds the default value + this.CommandList.(name).default=default; + %Adds the necessary attributes for the input to the command + this.CommandList.(name).attributes={attributes}; + 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 + error('Could not open device') + 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/@MyRsa/GuiRsa.fig b/@MyRsa/GuiRsa.fig new file mode 100644 index 0000000..a8e04e0 Binary files /dev/null and b/@MyRsa/GuiRsa.fig differ diff --git a/@MyRsa/GuiRsa.m b/@MyRsa/GuiRsa.m new file mode 100644 index 0000000..931cef0 --- /dev/null +++ b/@MyRsa/GuiRsa.m @@ -0,0 +1,464 @@ +function varargout = GuiRsa(varargin) +% GuiRsa MATLAB code for GuiRsa.fig +% GuiRsa, by itself, creates a new GuiRsa or raises the existing +% singleton*. +% +% H = GuiRsa returns the handle to a new GuiRsa or the handle to +% the existing singleton*. +% +% GuiRsa('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in GuiRsa.M with the given input arguments. +% +% GuiRsa('Property','Value',...) creates a new GuiRsa or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before GuiRsa_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to GuiRsa_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help GuiRsa + +% Last Modified by GUIDE v2.5 05-Oct-2017 19:02:20 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @GuiRsa_OpeningFcn, ... + 'gui_OutputFcn', @GuiRsa_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before GuiRsa is made visible. +function GuiRsa_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to GuiRsa (see VARARGIN) + +% Choose default command line output for GuiRsa +handles.output = hObject; + +%use TCP/IP in Matlab +buffer = 1000 * 1024; +visa_brand = 'ni'; +visa_address_rsa = 'TCPIP0::192.168.1.3::inst0::INSTR'; +vi = visa(visa_brand, visa_address_rsa, 'InputBufferSize', buffer, ... + 'OutputBufferSize', buffer); +handles.vi=vi; +set(vi,'InputBufferSize',1e6); +set(vi,'Timeout',10); +fopen(vi); + +%Read out / set initial settings +set(handles.cent_freq,'String',num2str(str2num(query(vi,['DPSA:FREQ:CENT?']))/1e6)); +set(handles.span,'String',num2str(str2num(query(vi,['DPSA:FREQ:SPAN?']))/1e6)); +set(handles.start_freq,'String',num2str(str2num(query(vi,['DPSA:FREQ:STAR?']))/1e6)); +set(handles.stop_freq,'String',num2str(str2num(query(vi,['DPSA:FREQ:STOP?']))/1e6)); +set(handles.rbw,'String',num2str(str2num(query(vi,['DPSA:band:act?']))/1e3)); +set(handles.average_no,'String','1'); +fprintf(handles.vi,'TRAC3:DPSA:AVER:COUN 1'); +set(handles.point_no,'Value',4); +fprintf(handles.vi,'DPSA:POIN:COUN P10401'); + +fclose(vi); + +% Update handles structure +guidata(hObject, handles); + +% UIWAIT makes GuiRsa wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = GuiRsa_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; + + + +function cent_freq_Callback(hObject, eventdata, handles) +% hObject handle to cent_freq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of cent_freq as text +% str2double(get(hObject,'String')) returns contents of cent_freq as a double +fopen(handles.vi); +value=get(hObject,'String'); +fprintf(handles.vi,['DPSA:FREQ:CENT ' value 'MHz']); +set(handles.start_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STAR?']))/1e6)); +set(handles.stop_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STOP?']))/1e6)); +fclose(handles.vi); + + +% --- Executes during object creation, after setting all properties. +function cent_freq_CreateFcn(hObject, eventdata, handles) +% hObject handle to cent_freq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + + +function span_Callback(hObject, eventdata, handles) +% hObject handle to span (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of span as text +% str2double(get(hObject,'String')) returns contents of span as a double +fopen(handles.vi); +value=get(hObject,'String'); +fprintf(handles.vi,['DPSA:FREQ:SPAN ' value 'MHz']); +set(handles.start_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STAR?']))/1e6)); +set(handles.stop_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STOP?']))/1e6)); +%set(handles.rbw,'String',num2str(str2num(query(vi,['DPSA:band:act?']))/1e3)); +fclose(handles.vi); + + +% --- Executes during object creation, after setting all properties. +function span_CreateFcn(hObject, eventdata, handles) +% hObject handle to span (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function start_freq_Callback(hObject, eventdata, handles) +% hObject handle to start_freq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of start_freq as text +% str2double(get(hObject,'String')) returns contents of start_freq as a double +fopen(handles.vi); +value=get(hObject,'String'); +fprintf(handles.vi,['DPSA:FREQ:STAR ' value 'MHz']); +set(handles.span,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:SPAN?']))/1e6)); +set(handles.stop_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STOP?']))/1e6)); +set(handles.cent_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:CENT?']))/1e6)); +%set(handles.rbw,'String',num2str(str2num(query(vi,['DPSA:band:act?']))/1e3)); +fclose(handles.vi); + + +% --- Executes during object creation, after setting all properties. +function start_freq_CreateFcn(hObject, eventdata, handles) +% hObject handle to start_freq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function rbw_Callback(hObject, eventdata, handles) +% hObject handle to rbw (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of rbw as text +% str2double(get(hObject,'String')) returns contents of rbw as a double +fopen(handles.vi); +value=get(hObject,'String'); +fprintf(handles.vi,['DPSA:BAND:RES ' value 'kHz']); +pause(0.1); +set(hObject,'String',num2str(str2num(query(handles.vi,['DPSA:band:act?']))/1e3)); +fclose(handles.vi); + + +% --- Executes during object creation, after setting all properties. +function rbw_CreateFcn(hObject, eventdata, handles) +% hObject handle to rbw (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function average_no_Callback(hObject, eventdata, handles) +% hObject handle to average_no (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of average_no as text +% str2double(get(hObject,'String')) returns contents of average_no as a double +if get(handles.enable_avg,'Value')==1 + fopen(handles.vi); + number=get(hObject,'String'); + fprintf(handles.vi,['TRAC3:DPSA:AVER:COUN ' number]); + fclose(handles.vi); +else + set(hObject,'String','1'); +end + + +% --- Executes during object creation, after setting all properties. +function average_no_CreateFcn(hObject, eventdata, handles) +% hObject handle to average_no (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + + +function stop_freq_Callback(hObject, eventdata, handles) +% hObject handle to stop_freq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of stop_freq as text +% str2double(get(hObject,'String')) returns contents of stop_freq as a double +fopen(handles.vi); +value=get(hObject,'String'); +fprintf(handles.vi,['DPSA:FREQ:STOP ' value 'MHz']); +set(handles.span,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:SPAN?']))/1e6)); +set(handles.start_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STAR?']))/1e6)); +set(handles.cent_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:CENT?']))/1e6)); +%set(handles.rbw,'String',num2str(str2num(query(vi,['DPSA:band:act?']))/1e3)); +fclose(handles.vi); + + +% --- Executes during object creation, after setting all properties. +function stop_freq_CreateFcn(hObject, eventdata, handles) +% hObject handle to stop_freq (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on selection change in point_no. +function point_no_Callback(hObject, eventdata, handles) +% hObject handle to point_no (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns point_no contents as cell array +% contents{get(hObject,'Value')} returns selected item from point_no +fopen(handles.vi); +contents=get(hObject,'String'); +selection=contents{get(hObject,'Value')}; +fprintf(handles.vi,['DPSA:POIN:COUN P' selection]); +fclose(handles.vi); + + +% --- Executes during object creation, after setting all properties. +function point_no_CreateFcn(hObject, eventdata, handles) +% hObject handle to point_no (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in enable_avg. +function enable_avg_Callback(hObject, eventdata, handles) +% hObject handle to enable_avg (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of enable_avg +status=get(hObject,'Value'); +fopen(handles.vi); +if status==1; + set(handles.average_no,'String','100'); + fprintf(handles.vi,'TRAC3:DPSA:AVER:COUN 100'); +else + set(handles.average_no,'String','1'); + fprintf(handles.vi,'TRAC3:DPSA:AVER:COUN 1'); +end +fclose(handles.vi); + + +% --- Executes on button press in fetch_single. +function fetch_single_Callback(hObject, eventdata, handles) +% hObject handle to fetch_single (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of fetch_single + +% Execute device object function(s). +number_points=get(handles.point_no,'Value'); +address=get(handles.vi,'rsrcname'); +RSA_Data = ReadRSA(number_points,address); + +%capturing the y data +x_data=RSA_Data.x; +%capturing the x data +y_data=RSA_Data.y; + +% Calculating the power spectrum (P/Hz) +Power_Spectrum = (10.^(y_data/10))/RSA_Data.res*50*0.001; + +% updating global variables and updating the plot + h_main_plot=getappdata(0,'h_main_plot'); + setappdata(h_main_plot,'x_data',x_data); + setappdata(h_main_plot,'y_data',Power_Spectrum); + setappdata(h_main_plot,'x_label',RSA_Data.xunit); + setappdata(h_main_plot,'y_label','V^2/Hz'); + update_axes=getappdata(h_main_plot,'update_axes'); + +set(hObject,'Value',0); +feval(update_axes); + + +% --- Executes on button press in fetch_AVT. +function fetch_AVT_Callback(hObject, eventdata, handles) +% hObject handle to fetch_AVT (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of fetch_AVT +number_points=get(handles.point_no,'Value'); +address=get(handles.vi,'rsrcname'); +RSA_Data = ReadRSA_AVT(number_points,address); + +%capturing the y data +x_data=RSA_Data.x; +%capturing the x data +y_data=RSA_Data.y; + +% Calculating the power spectrum (P/Hz) +Power_Spectrum = (10.^(y_data/10))/RSA_Data.res*50*0.001; + +% updating global variables and updating the plot + h_main_plot=getappdata(0,'h_main_plot'); + setappdata(h_main_plot,'x_data',x_data); + setappdata(h_main_plot,'y_data',Power_Spectrum); + setappdata(h_main_plot,'x_label',RSA_Data.xunit); + setappdata(h_main_plot,'y_label','V^2/Hz'); + update_axes=getappdata(h_main_plot,'update_axes'); + +set(hObject,'Value',0); +feval(update_axes); + + +% --- Executes when user attempts to close figure1. +function figure1_CloseRequestFcn(hObject, eventdata, handles) +% hObject handle to figure1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: delete(hObject) closes the figure +delete(handles.vi); +delete(hObject); + + +% --- Executes on selection change in device. +function device_Callback(hObject, eventdata, handles) +% hObject handle to device (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns device contents as cell array +% contents{get(hObject,'Value')} returns selected item from device +%use TCP/IP in Matlab +buffer = 1000 * 1024; +visa_brand = 'ni'; +delete(handles.vi); +if get(hObject,'Value')==1 + visa_address_rsa = 'TCPIP0::192.168.1.3::inst0::INSTR'; +else + visa_address_rsa = 'TCPIP0::192.168.1.5::inst0::INSTR'; +end +vi = visa(visa_brand, visa_address_rsa, 'InputBufferSize', buffer, ... + 'OutputBufferSize', buffer); +handles.vi=vi; +set(vi,'InputBufferSize',1e6); +set(vi,'Timeout',10); +fopen(vi); + +%Read out / set initial settings +set(handles.cent_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:CENT?']))/1e6)); +set(handles.span,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:SPAN?']))/1e6)); +set(handles.start_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STAR?']))/1e6)); +set(handles.stop_freq,'String',num2str(str2num(query(handles.vi,['DPSA:FREQ:STOP?']))/1e6)); +set(handles.rbw,'String',num2str(str2num(query(handles.vi,['DPSA:band:act?']))/1e3)); +set(handles.average_no,'String','1'); +fprintf(handles.vi,'TRAC3:DPSA:AVER:COUN 1'); +set(handles.point_no,'Value',4); +fprintf(handles.vi,'DPSA:POIN:COUN P10401'); + +fclose(vi); + +% Update handles structure +guidata(hObject, handles); + +% --- Executes during object creation, after setting all properties. +function device_CreateFcn(hObject, eventdata, handles) +% hObject handle to device (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in reinit. +function reinit_Callback(hObject, eventdata, handles) +% hObject handle to reinit (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of reinit +%Placeholder, callback redefined in class. diff --git a/@MyRsa/MyRsa.m b/@MyRsa/MyRsa.m new file mode 100644 index 0000000..8d3fbde --- /dev/null +++ b/@MyRsa/MyRsa.m @@ -0,0 +1,226 @@ +classdef MyRsa < MyInstrument + properties (SetAccess=protected, GetAccess=public) + rbw; + start_freq; + stop_freq; + cent_freq; + span; + average_no; + point_no; + end + + methods + function this=MyRsa(name,interface, address) + this@MyInstrument(name, interface, address,'GuiRsa'); + initGui(this); + createCommandList(this); + createCommandParser(this); + switch interface + case 'TCPIP' + createTCPIP(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 createTCPIP(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 readProperty(this, varargin) + for i=1:length(varargin) + if ~isprop(this, varargin{i}) + error('%s is not a property of the class',varargin{i}) + end + %Finds the index of the % sign which indicates where the value + %to be written is supplied + ind=strfind(this.CommandList.(varargin{i}).command,'%'); + %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 + this.(varargin{i})=str2double(this.read(read_command)); + end + end + + function readStatus(this) + openDevice(this); + readProperty(this,'rbw','cent_freq','span','start_freq','stop_freq'); + closeDevice(this); + 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.span, 'Callback',... + @(hObject, eventdata) spanCallback(this, hObject,... + eventdata)); + set(this.Gui.rbw, 'Callback',... + @(hObject, eventdata) rbwCallback(this, hObject,... + eventdata)); + end + + function initDevice(this) + for i=1:this.command_no + 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 + + function reinitCallback(this, hObject, eventdata) + openDevice(this); + readStatus(this); + initDevice(this); + write(this,'INIT:CONT ON'); + closeDevice(this); + %Turns off indicator + set(hObject,'Value',0); + end + + function point_noCallback(this, hObject, eventdata) + 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) + 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 spanCallback(this, hObject, eventdata) + this.span=str2double(get(hObject,'String'))*1e6; + openDevice(this); + writeProperty(this,'span',this.span); + readStatus(this) + closeDevice(this); + end + + function rbwCallback(this, hObject, eventdata) + this.rbw=str2double(get(hObject,'String'))*1e3; + openDevice(this); + writeProperty(this,'rbw',this.rbw); + closeDevice(this); + end + + function average_noCallback(this, hObject, eventdata) + this.average_no=str2double(get(hObject,'String')); + openDevice(this); + writeProperty(this,'average_no',this.average_no); + closeDevice(this); + end + + function createCommandList(this) + addCommand(this, 'average_no','TRAC3:DPSA:AVER:COUN %d',... + 1, {'numeric'}); + addCommand(this, 'rbw','DPSA:BAND:RES %d Hz',... + 1e3, {'numeric'}); + addCommand(this, 'span','DPSA:FREQ:SPAN %d Hz',... + 1e6, {'numeric'}); + addCommand(this, 'start_freq','DPSA:FREQ:STAR %d Hz',... + 1e6, {'numeric'}); + addCommand(this, 'stop_freq','DPSA:FREQ:STOP %d Hz',... + 2e6, {'numeric'}); + addCommand(this, 'cent_freq','DPSA:FREQ:CENT %d Hz',... + 1.5e6, {'numeric'}); + addCommand(this, 'point_no','DPSA:POIN:COUN P%d',... + 10401, {'numeric'}); + 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; + set(this.Gui.cent_freq,'String',this.cent_freq/1e6); + end + + %Set function for rbw, changes gui to show rbw in kHz + function set.rbw(this, rbw) + this.rbw=rbw; + set(this.Gui.rbw,'String',this.rbw/1e3); + end + + %Set function for span, changes gui to show span in MHz + function set.span(this, span) + this.span=span; + set(this.Gui.span,'String',this.span/1e6); + end + + + %Set function for start frequency, changes gui to show start + %frequency in MHz + function set.start_freq(this, start_freq) + this.start_freq=start_freq; + set(this.Gui.start_freq,'String',this.start_freq/1e6) + end + + %Set function for stop frequency, changes gui to show stop + %frequency in MHz + function set.stop_freq(this, stop_freq) + this.stop_freq=stop_freq; + set(this.Gui.stop_freq,'String',this.stop_freq/1e6) + end + + function set.average_no(this, average_no) + this.average_no=average_no; + set(this.Gui.average_no,'String',this.average_no); + end + + function set.point_no(this, point_no) + point_list=get(this.Gui.point_no,'String'); + ind=find(strcmp(num2str(point_no),point_list)); + if ~isempty(ind) + this.point_no=point_no; + set(this.Gui.point_no,'Value',ind); + else + error('Invalid number of points chosen for RSA') + end + end + end +end + diff --git a/@MyTrace/MyTrace.m b/@MyTrace/MyTrace.m new file mode 100644 index 0000000..1d4eb6c --- /dev/null +++ b/@MyTrace/MyTrace.m @@ -0,0 +1,158 @@ +classdef MyTrace < handle + properties + x=[]; + y=[]; + name='placeholder'; + Color='b'; + Marker='.'; + LineStyle='-' + MarkerSize=6; + Parser; + name_x='x'; + name_y='y'; + unit_x=''; + unit_y=''; + end + + properties (Dependent=true) + label_x; + label_y; + end + + methods + function this=MyTrace(name, x, y, varargin) + createParser(this); + parse(this.Parser,name,x,y,varargin{:}); + parseInputs(this); + end + + function createParser(this) + p=inputParser; + addRequired(p,'name',@ischar); + addRequired(p,'x',@validateVector); + addRequired(p,'y',@validateVector); + addParameter(p,'Color','b',@validateColor); + addParameter(p,'Marker','.',@validateMarker); + addParameter(p,'LineStyle','-',@validateLine); + addParameter(p,'MarkerSize',6,@validateSize); + addParameter(p,'unit_x','x',@ischar); + addParameter(p,'unit_y','y',@ischar); + this.Parser=p; + end + + function parseInputs(this) + for i=1:length(this.Parser.Parameters) + this.(this.Parser.Parameters{i})=... + this.Parser.Results.(this.Parser.Parameters{i}); + end + end + + function plotTrace(this,plot_axes,varargin) + if ~exist('plot_axes','var') || ... + ~isa(plot_axes,'matlab.graphics.axis.Axes') + error('Please input axes to plot in.') + end + createParser(this); + parse(this.Parser,this.name,this.x,this.y,varargin{:}) + parseInputs(this); + plot(plot_axes,this.x,this.y,'Color',this.Color,'LineStyle',... + this.LineStyle,'Marker',this.Marker,... + 'MarkerSize',this.MarkerSize) + xlabel(plot_axes,this.label_x,'Interpreter','LaTeX'); + ylabel(plot_axes,this.label_y,'Interpreter','LaTeX'); + set(plot_axes,'TickLabelInterpreter','LaTeX'); + + end + + function set.Color(this, Color) + if validateColor(Color); this.Color=Color; end + end + + function set.Marker(this, Marker) + if validateMarker(Marker); this.Marker=Marker; end + end + + function set.x(this, x) + if validateVector(x); this.x=x; end + end + + function set.y(this, y) + if validateVector(y); this.y=y; end + end + + function set.LineStyle(this, LineStyle) + if validateLine(LineStyle); this.LineStyle=LineStyle; end + end + + function set.MarkerSize(this, MarkerSize) + if validateSize(MarkerSize); this.MarkerSize=MarkerSize; end + end + + function set.name(this, name) + assert(ischar(name),'Name must be a string, not a %s',... + class(name)); + this.name=name; + end + + function set.unit_x(this, unit_x) + assert(ischar(unit_x),'Name must be a string, not a %s',... + class(unit_x)); + this.unit_x=unit_x; + end + + function set.unit_y(this, unit_y) + assert(ischar(unit_y),'Name must be a string, not a %s',... + class(unit_y)); + this.unit_y=unit_y; + end + + function set.name_x(this, name_x) + assert(ischar(name_x),'Name must be a string, not a %s',... + class(name_x)); + this.name_x=name_x; + end + + function set.name_y(this, name_y) + assert(ischar(name_y),'Name must be a string, not a %s',... + class(name_y)); + this.name_y=name_y; + end + + function label_x=get.label_x(this) + label_x=sprintf('%s (%s)', this.name_x, this.unit_x); + end + + function label_y=get.label_y(this) + label_y=sprintf('%s (%s)', this.name_y, this.unit_y); + end + + end +end + +function bool=validateVector(vector) +assert(isvector(vector) && isnumeric(vector),... + 'Data must be a vector of doubles'); +bool=true; +end + +function bool=validateColor(color) +assert(iscolor(color),... + '%s is not a valid MATLAB default color or RGB triplet',color); +bool=true; +end +function bool=validateMarker(marker) +assert(ismarker(marker),... + '%s is not a valid MATLAB MarkerStyle',marker); +bool=true; +end + +function bool=validateLine(linestyle) +assert(isline(linestyle),... + '%s is not a valid MATLAB LineStyle',linestyle); +bool=true; +end +function bool=validateSize(markersize) +assert(isnumeric(markersize) && markersize>0,... + 'MarkerSize must be a numeric value greater than zero'); +bool=true; +end \ No newline at end of file diff --git a/Utility functions/iscolor.m b/Utility functions/iscolor.m new file mode 100644 index 0000000..f1eaf04 --- /dev/null +++ b/Utility functions/iscolor.m @@ -0,0 +1,7 @@ +function bool = iscolor( color ) +%Taken from https://ch.mathworks.com/matlabcentral/answers/142087-how-do-i-check-if-a-value-is-a-correct-color +bool=(isnumeric(color) && (sum(size(color)==[1 3])==2 || ... + sum(size(color)==[3 1])==2) && sum((color<=[1 1 1] & ... + color>=[0 0 0]))==3) || sum(strcmpi({'y','m','c','r','g','b','w','k',... + 'yellow','magenta','cyan','red','green','blue','white','black'},color))>0; +end \ No newline at end of file diff --git a/Utility functions/isline.m b/Utility functions/isline.m new file mode 100644 index 0000000..b2bc601 --- /dev/null +++ b/Utility functions/isline.m @@ -0,0 +1,3 @@ +function bool=isline(linestyle) +bool=any(strcmpi({'-','--',':','-.','none'},linestyle)); +end \ No newline at end of file diff --git a/Utility functions/ismarker.m b/Utility functions/ismarker.m new file mode 100644 index 0000000..bb618c8 --- /dev/null +++ b/Utility functions/ismarker.m @@ -0,0 +1,6 @@ +function bool=ismarker(marker) + +bool=any(strcmpi({'.','o','x','+','*','s','d','v','^','<','>','p','h',... + 'square','diamond','pentagram','hexagram'}, marker)); + +end \ No newline at end of file