| @@ -1,9 +1,9 @@ | |||
| if ~exist('theory_only','var') || theory_only == false | |||
| if ~exist('functiongenerator','var') | |||
| functiongenerator = FunctionGenerator('10.0.0.3',1234,10); | |||
| functiongenerator = FunctionGeneratorClass('10.0.0.3',1234,10); | |||
| end | |||
| if ~exist('oscilloscope','var') | |||
| oscilloscope = Oscilloscope('10.0.0.2',5025,2); | |||
| oscilloscope = OscilloscopeClass('10.0.0.2',5025,2); | |||
| end | |||
| end | |||
| @@ -1,7 +1,8 @@ | |||
| classdef ChannelClass | |||
| % CHANNEL is the class for one channel of the oscilloscope. Multiple | |||
| % CHANNELCLASS is the class for one channel of the oscilloscope. Multiple | |||
| % settings for the different channels of the oscilloscope can be changed | |||
| % via this class definition | |||
| % See also: OSCILLOSCOPECLASS | |||
| properties (Hidden, Access = private) | |||
| scope % Contains the class of the scope that is parent of this channel. | |||
| @@ -21,7 +22,7 @@ classdef ChannelClass | |||
| methods | |||
| %Constructor of class | |||
| function ch = Channel(scope,channelnumber) | |||
| function ch = ChannelClass(scope,channelnumber) | |||
| ch.channelnumber = channelnumber; | |||
| ch.scope = scope; | |||
| end | |||
| @@ -203,7 +204,7 @@ classdef ChannelClass | |||
| % visible on the screen, and DMAX returns more values than DEF. | |||
| % Only available if acquisition is stopped. | |||
| % | |||
| % See also OSCILLOSCOPE.SETWAVEFORMSETTINGS | |||
| % See also OSCILLOSCOPECLASS.SETWAVEFORMSETTINGS | |||
| ch.scope.single; | |||
| if nargin < 2 | |||
| window = 'DEF'; | |||
| @@ -1,4 +1,4 @@ | |||
| classdef Equipment < handle | |||
| classdef EquipmentClass < handle | |||
| %EQUIPMENT Summary of this class goes here | |||
| % Detailed explanation goes here | |||
| @@ -20,13 +20,13 @@ classdef Equipment < handle | |||
| end | |||
| methods | |||
| function ecq = Equipment(ipAddress,port,channel) | |||
| function ecq = EquipmentClass(ipAddress,port,channel) | |||
| %EQUIPMENT Construct an instance of this class. | |||
| % This functions opens the required TCP connection | |||
| % for this device. Channel is GPIB-channel on prologix | |||
| % converter if used, otherwise set channel to -1. | |||
| % Name is queried from device via '*IDN?' command. | |||
| ecq.tcp = Equipment.getTCP(ipAddress,port); | |||
| ecq.tcp = EquipmentClass.getTCP(ipAddress,port); | |||
| ecq.locked = false; | |||
| ecq.channel = channel; | |||
| ecq.name = ecq.idn(); | |||
| @@ -74,8 +74,10 @@ classdef Equipment < handle | |||
| ecq.write_unsafe('*OPC?'); | |||
| for i = 1:10 | |||
| ack = ecq.read; | |||
| if strcmp(ack(1),'1') | |||
| return | |||
| if ~isempty(ack) | |||
| if strcmp(ack(1),'1') | |||
| return | |||
| end | |||
| end | |||
| end | |||
| error('Device is not ready'); | |||
| @@ -180,7 +182,7 @@ classdef Equipment < handle | |||
| %The function will pull all errors from the device error stack. | |||
| %This is up to a maximum of 20 errors. If errors have occured | |||
| %the function will throw a warning with all the error messages. | |||
| for i = 1:20 | |||
| for i = 1:1 | |||
| output = ecq.query_unsafe('SYSTem:ERRor?'); %Query error message from device. | |||
| % [msgstr, msgid] = lastwarn; | |||
| % if strcmp(msgid,'instrument:fscanf:unsuccessfulRead') | |||
| @@ -261,12 +263,14 @@ classdef Equipment < handle | |||
| %SETPROLOGIX Set the correct default settings | |||
| ecq.write_unsafe('++mode 1'); %set device in controller mode | |||
| ecq.write_unsafe('++auto 0'); %disable automatic datapull. this avoids errors on equipment. | |||
| ecq.write_unsafe('++eoi 1'); %enable end of line character | |||
| ecq.write_unsafe('++eos 0'); %Set end of line character | |||
| end | |||
| function delete(ecq) | |||
| %DELETE Destructs the current object. | |||
| ecq.unlock; | |||
| Equipment.getTCP(ecq.tcp.RemoteHost,-ecq.tcp.RemotePort); | |||
| EquipmentClass.getTCP(ecq.tcp.RemoteHost,-ecq.tcp.RemotePort); | |||
| end | |||
| end | |||
| @@ -288,7 +292,7 @@ classdef Equipment < handle | |||
| %call) make a struct in the variable. | |||
| tcpconnection = struct; | |||
| end | |||
| [ipname,ipAddress] = Equipment.ip2structname(ipAddress,abs(port)); %Get a structname and a cleaned ipaddress. | |||
| [ipname,ipAddress] = EquipmentClass.ip2structname(ipAddress,abs(port)); %Get a structname and a cleaned ipaddress. | |||
| if port > 0 %if port number is positive a connection is made. | |||
| @@ -330,7 +334,7 @@ classdef Equipment < handle | |||
| function num = forceNum(input) | |||
| %FORCENUM Throws an error if the input is not numeric. | |||
| if ~Equipment.isnum(input) | |||
| if ~EquipmentClass.isnum(input) | |||
| error('Input should be a (single) number.'); | |||
| end | |||
| num = input; | |||
| @@ -360,8 +364,13 @@ classdef Equipment < handle | |||
| %structname to store stuff in struct (especially for GETTCP). | |||
| %cleanip is a shortened ip without leading zeros. | |||
| cleanip = regexprep(ipAddress,'(?:(?<=\.)|^)(?:0+)(?=\d)',''); | |||
| Equipment.iptest(cleanip); | |||
| EquipmentClass.iptest(cleanip); | |||
| structname = matlab.lang.makeValidName(['ip',cleanip,'_',num2str(port)]); | |||
| end | |||
| function equipmentstruct = discover() | |||
| end | |||
| end | |||
| end | |||
| @@ -1,41 +1,39 @@ | |||
| classdef FunctionGenerator < Equipment | |||
| % FUNCTION_GENERATOR Control a function generator. | |||
| % fg = FUNCTION_GENERATOR('IP', PORT, GPIB_CHAN) connects | |||
| classdef FunctionGeneratorClass < EquipmentClass | |||
| % FUNCTIONGENERATORCLASS Control a function generator. | |||
| % fg = FUNCTIONGENERATORCLASS('IP', PORT, GPIB_CHAN) connects | |||
| % to a function generator on IPv4 address 'IP', on port | |||
| % 'PORT' and GPIO channel 'GPIB_CHAN', using the Equipment | |||
| % class. | |||
| % | |||
| % See also EQUIPMENT, OSCILLOSCOPE, DIGITALMULTIMETER. | |||
| % See also EQUIPMENTCLASS, OSCILLOSCOPECLASS, DIGITALMULTIMETERCLASS. | |||
| properties (Dependent) | |||
| %Dependent properties; stored on function generator, | |||
| % read from or written to function generator when required. | |||
| waveform | |||
| frequency | |||
| voltage | |||
| unit | |||
| offset | |||
| load | |||
| output | |||
| waveform %Waveform shape | |||
| frequency %Frequency setting in hertz | |||
| voltage %Amplitude setting as defined by FUNCTIONGENERATORCLASS.UNIT | |||
| unit %unit of amplitude: VPP|VRMS|DBM|DEFault | |||
| offset %Offset setting in volt | |||
| load %output impedence setting 50|inf | |||
| output %output enable setting. Only available on 332xx and newer. | |||
| end | |||
| methods | |||
| function fg = FunctionGenerator(ipAddress,port,channel) | |||
| % FUNCTION_GENERATOR Control a function generator. | |||
| % fg = FUNCTION_GENERATOR('IP', PORT, GPIB_CHAN) connects | |||
| function fg = FunctionGeneratorClass(ipAddress,port,channel) | |||
| % FUNCTIONGENERATORCLASS Control a function generator. | |||
| % fg = FUNCTIONGENERATORCLASS('IP', PORT, GPIB_CHAN) connects | |||
| % to a function generator on IPv4 address 'IP', on port | |||
| % 'PORT' and GPIO channel 'GPIB_CHAN', using the Equipment | |||
| % class. | |||
| % | |||
| % See also EQUIPMENT, OSCILLOSCOPE, DIGITALMULTIMETER. | |||
| fg@Equipment(ipAddress,port,channel); | |||
| % See also EQUIPMENTCLASS, OSCILLOSCOPECLASS, DIGITALMULTIMETERCLASS. | |||
| fg@EquipmentClass(ipAddress,port,channel); | |||
| end | |||
| function w = get.waveform(fg) | |||
| %Get the function generator waveform setting on waveform | |||
| % variable access, using the corresponding SCPI command. | |||
| w = FunctionGenerator.getWave(fg.query('FUNCtion:SHAPe?')); | |||
| w = FunctionGeneratorClass.getWave(fg.query('FUNCtion:SHAPe?')); | |||
| end | |||
| function f = get.frequency(fg) | |||
| @@ -53,7 +51,7 @@ classdef FunctionGenerator < Equipment | |||
| function u = get.unit(fg) | |||
| %Get function generator output voltage unit setting on offset | |||
| % variable access, using the corresponding SCPI command. | |||
| u = FunctionGenerator.getUnit(fg.query('VOLTage:UNIT?')); | |||
| u = FunctionGeneratorClass.getUnit(fg.query('VOLTage:UNIT?')); | |||
| end | |||
| function o = get.offset(fg) | |||
| @@ -65,7 +63,7 @@ classdef FunctionGenerator < Equipment | |||
| function l = get.load(fg) | |||
| %Get function generator load setting on load variable | |||
| % access, using the corresponding SCPI command. | |||
| l = FunctionGenerator.getLoad(fg.query('OUTPut:LOAD?')); | |||
| l = FunctionGeneratorClass.getLoad(fg.query('OUTPut:LOAD?')); | |||
| end | |||
| function out = get.output(fg) | |||
| @@ -79,7 +77,7 @@ classdef FunctionGenerator < Equipment | |||
| function fg = set.waveform(fg,w) | |||
| %Set function generator waveform setting on waveform variable | |||
| % access, using the corresponding SCPI command. | |||
| fg.write(['FUNCtion:SHAPe ' FunctionGenerator.getWave(w)]); | |||
| fg.write(['FUNCtion:SHAPe ' FunctionGeneratorClass.getWave(w)]); | |||
| end | |||
| function fg = set.frequency(fg,f) | |||
| @@ -99,7 +97,7 @@ classdef FunctionGenerator < Equipment | |||
| function fg = set.unit(fg,u) | |||
| %Set function generator output voltage unit setting on unit | |||
| % variable access, using the corresponding SCPI command. | |||
| fg.write(['VOLTage:UNIT ' FunctionGenerator.getUnit(u)]); | |||
| fg.write(['VOLTage:UNIT ' FunctionGeneratorClass.getUnit(u)]); | |||
| end | |||
| function fg = set.offset(fg,o) | |||
| @@ -112,16 +110,37 @@ classdef FunctionGenerator < Equipment | |||
| function fg = set.load(fg,l) | |||
| %Set function generator load setting on load variable access, | |||
| % using the corresponding SCPI command. | |||
| fg.write(['OUTPut:LOAD ' FunctionGenerator.getLoad(l)]); | |||
| fg.write(['OUTPut:LOAD ' FunctionGeneratorClass.getLoad(l)]); | |||
| end | |||
| function fg = set.output(fg,out) | |||
| if strcmp(fg.model(1:3),'335') || strcmp(fg.model(1:3),'332') | |||
| fg.write(['OUTP ' Equipment.optionnum2str(out)]) | |||
| fg.write(['OUTP ' EquipmentClass.optionnum2str(out)]) | |||
| end | |||
| end | |||
| function downloadwaveform(fg,waveform,name) | |||
| switch fg.model | |||
| case '33120A' | |||
| downloadwaveform_legacy(fg,waveform,name); | |||
| otherwise | |||
| downloadwaveform_new(fg,waveform,name); | |||
| end | |||
| end | |||
| function downloadwaveform_legacy(fg,waveform,name) | |||
| name_trunc = name(1:min(length(name),8)); | |||
| fg.opc; | |||
| fg.write_noerror(['data volatile' num2str(waveform,',%0.4f')]); | |||
| fg.opc; | |||
| fg.error; | |||
| fg.write_noerror(['data:copy ' name_trunc]); | |||
| fg.opc; | |||
| fg.error; | |||
| fg.write(['func:user' name_trunc]); | |||
| end | |||
| function downloadwaveform_new(fg,waveform,name) | |||
| fg.disableEOI; | |||
| fg.write_unsafe(['data:arb ' name ',']); | |||
| fg.enableEOI; | |||
| @@ -136,7 +155,6 @@ classdef FunctionGenerator < Equipment | |||
| x = linspace(-periods*pi,periods*pi,1600); | |||
| y = exp(-abs(x./6)).*sin(x)./0.8; | |||
| fg.downloadwaveform(y,'scintilla'); | |||
| end | |||
| end | |||
| @@ -1,4 +1,4 @@ | |||
| classdef Oscilloscope < Equipment | |||
| classdef OscilloscopeClass < EquipmentClass | |||
| %OSCILLOSCOPE is the classdef for a Oscilloscope | |||
| % This oscilloscope object can contain multiple channels and trigger | |||
| % settings. | |||
| @@ -21,11 +21,11 @@ classdef Oscilloscope < Equipment | |||
| end | |||
| methods | |||
| function sc = Oscilloscope(ipAddress,port,nchannels) | |||
| function sc = OscilloscopeClass(ipAddress,port,nchannels) | |||
| %OSCILLOSCOPE Construct an instance of this class | |||
| % This constructor creates a new scope object. | |||
| sc@Equipment(ipAddress,port,-1); %make this object a child of the EQUIPMENT class | |||
| sc.trigger = Trigger(sc); %create a trigger object | |||
| sc@EquipmentClass(ipAddress,port,-1); %make this object a child of the EQUIPMENT class | |||
| sc.trigger = TriggerClass(sc); %create a trigger object | |||
| sc.nchannels = min(nchannels,4); %Set number of channels with a maximum of 4. | |||
| %more channels is possible but this requires more properties. | |||
| for i = 1:nchannels %create a channel object for each channel | |||
| @@ -1,4 +1,4 @@ | |||
| classdef Trigger | |||
| classdef TriggerClass | |||
| %TRIGGER Summary of this class goes here | |||
| % Detailed explanation goes here | |||
| @@ -17,7 +17,7 @@ classdef Trigger | |||
| end | |||
| methods | |||
| function tr = Trigger(scope) | |||
| function tr = TriggerClass(scope) | |||
| tr.scope = scope; | |||
| end | |||