| @@ -0,0 +1,23 @@ | |||||
| Aantallen zijn per kastje. D = verkrijgbaar bij Digi-Key; M = verkrijgbaar bij Mouser. | |||||
| Condensatoren (4x): 100nF 2.5% Siemens MKP Axiaal 14x19mm | |||||
| M Vervanger: Vishay MKP1839410163 | |||||
| Weerstanden (4x): 20kOhm 1% 50ppm/k 2.5x6.2mm | |||||
| D/M Vervanger: Vishay RN55C2002FB14 | |||||
| Spoelen (4x): | |||||
| D Kern, onderhelft: B65701T1000A48 (levertijd één maand) | |||||
| - Kern, bovenhelft: B65701D1000A48 (slecht verkrijgbaar; mogelijkkan de schroefdraad die in de B65701T1000A48 geplakt zit verwijderd worden om een B65701D1000A48 te maken. B65701T1000A48 lijkt bij Digi-Key beide helften te bevatten.) | |||||
| D/M Stelschroef: B65679E0002X022 (B65679E0003X022 bestaat ook, maar het kernmateriaal hierop is iets dunner. De air-gap kan dan dus niet volledig gesloten worden, en aangezien de originele spoel met 485 windingen een zelfinductie van maximaal 237mH heeft, moet deze, met een kern met een A_L van 1000nH, wel volledig gesloten kunnen worden.) | |||||
| D(/M) Mount: B65705B0003X000 (Momenteel niet op voorraad bij Mouser.) | |||||
| D/M Draadhouder: B65702B0000T001 | |||||
| Draad: | |||||
| D 0.25mm (31m): Vergelijkbaar met CNC Tech 600232 (3.5km, AWG32) | |||||
| D 0.35mm (16m): Vergelijkbaar met CNC Tech 600228 (1.4km, AWG28) | |||||
| D 0.45mm (11m): Vergelijkbaar met CNC Tech 600226 (0.9km, AWG26) | |||||
| D 0.60mm (7m): CNC Tech 600224 (0.5km, AWG24) | |||||
| BNC-Connector (2x): | |||||
| D/M Vergelijkbaar met Amphenol 031-5431-10RFX | |||||
| Schakelaars (4x): | |||||
| D/M Vergelijkbaar met C&K 7101MD9ABE | |||||
| Behuizing (1x): Niet meer te vinden | |||||
| M Vervanger: Hammond 1402B of 1402BV (voorraad beperkt, levertijd daarna drie weken) | |||||
| @@ -25,6 +25,7 @@ remote_port = 3040; | |||||
| %% setup dsp to send and recieve udp packets. | %% setup dsp to send and recieve udp packets. | ||||
| udpconnection = udp('255.255.255.255',3040); | udpconnection = udp('255.255.255.255',3040); | ||||
| udpconnection.LocalHost = '10.0.0.10'; | |||||
| %hudpr = dsp.UDPReceiver('LocalIPPort',local_port); | %hudpr = dsp.UDPReceiver('LocalIPPort',local_port); | ||||
| % hudps = dsp.UDPSender('RemoteIPAddress','255.255.255.255','RemoteIPPort',remote_port,'LocalIPPortSource','Property','LocalIPPort',local_port); | % hudps = dsp.UDPSender('RemoteIPAddress','255.255.255.255','RemoteIPPort',remote_port,'LocalIPPortSource','Property','LocalIPPort',local_port); | ||||
| % start recieving udp packets | % start recieving udp packets | ||||
| @@ -0,0 +1,39 @@ | |||||
| %% Transfer function of a RC-network | |||||
| % This script will run automated measurements for you. Note that all frequencies | |||||
| % are given in Hertz. | |||||
| %% Component Values | |||||
| % Fill in the measured values in the following code box. | |||||
| %% | |||||
| R = 3.2942e3; %Ohm | |||||
| C = 315.82e-9;%Farad | |||||
| %% | |||||
| % Give the desired begin and end frequency as well as number of steps: | |||||
| f_start = 10; %Hz | |||||
| f_stop = 1e3; %Hz | |||||
| %% | |||||
| % Do not edit the following code box. | |||||
| f = 10.^linspace(log10(f_start),log10(f_stop),500); | |||||
| %% Theoratical Curves | |||||
| % Give the equations for the magnitude: | |||||
| %% | |||||
| A = -10*log10(1+(2*pi*f*R*C).^2); | |||||
| %% | |||||
| % For the phase: | |||||
| P = -atan(2*pi*f*R*C); | |||||
| %% | |||||
| % For the cut-off frequency: | |||||
| Fc = 1/(2*pi*R*C); | |||||
| %% | |||||
| % And both asymptotes where $f >> f_c$ and $f << f_c$: | |||||
| S_smaller = 0*f; %smaller than cut-off frequency | |||||
| S_larger = -20*log10(2*pi*f*R*C); %larger than cut-off frequency | |||||
| %% Running the Measurement | |||||
| %% | |||||
| n_steps = 5; | |||||
| amplitude = 10; | |||||
| RC_TransferFunction_script; | |||||
| @@ -0,0 +1,17 @@ | |||||
| ipPrefix='10.0.0'; | |||||
| ipPrefixRegex = '10\.0\.0'; | |||||
| if ispc() | |||||
| system(['for /L %a in (1,1,254) do @start /b ping ' ipPrefix '.%a -w 100 -n 2 >nul']); | |||||
| [~,arptable] = system('arp -a'); | |||||
| ipaddresses = regexp(arptable,[ipPrefixRegex '\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])(?=[-a-f0-9\s]*?dynamic)'],'match'); | |||||
| elseif isunix() | |||||
| [~,ipaddresses] = system(['echo $(seq 254) | xargs -P255 -I% -d" " ping -W 1 -c 1 ' ipPrefix '.% | grep -P -o "[0-1].*?(?=:)"']); | |||||
| elseif ismac() | |||||
| [~,ipaddresses] = system(['seq 254 | xargs -n1 -P255 -I% -- sh -c "ping -W1 -c1 ' ipPrefix '.% &>/dev/null && echo ' ipPrefix '.%"']); | |||||
| else | |||||
| end | |||||
| %% find prologix | |||||
| @@ -0,0 +1,57 @@ | |||||
| for i = 1:5e6:15e6 | |||||
| fg.write_unsafe(['apply:sin ', num2str(i)]) | |||||
| fg.opc | |||||
| fg.write_unsafe('func:shape ramp') | |||||
| fg.opc | |||||
| end | |||||
| fg.error | |||||
| %% | |||||
| % plot y=11*exp(-|x/6|)*sin(x) from x= -12.5 to x=9.4 | |||||
| x = linspace(-10*pi,10*pi,8000); | |||||
| y = 11.*exp(-abs(x./6)).*sin(x); | |||||
| plot(x,y,x+20*pi,y) | |||||
| %% | |||||
| tic | |||||
| fg.frequency = 2000; | |||||
| fg.waveform = 'sinus'; | |||||
| fg.unit = 'Vrms'; | |||||
| fg.frequency = 1e6; | |||||
| toc | |||||
| %% | |||||
| a=-10*log(1+(2*pi*f*r*c)^2); | |||||
| s=step(2*pi*f-1/(r*c))*(-20*log(2*pi*f*r*c)); | |||||
| p=-atan(2*pi*f*r*c); | |||||
| %% | |||||
| f1=100; | |||||
| phase_diff1 = 0.5; | |||||
| tp=((1:1000)./1000); | |||||
| tp2=tp-((phase_diff1*1000/(f1*360))./1000); | |||||
| % normalizing - 360 is 1 complete phase shift | |||||
| x=0.8*exp(2*pi*i*signal_freq*tp)+0.4*exp(2*pi*i*20*tp); | |||||
| y=0.8*exp(2*pi*i*signal_freq*tp2)+0.4*exp(2*pi*i*20*tp); | |||||
| %% | |||||
| Fs = (wave1.stop-wave1.start)/wave1.length; | |||||
| p1=(fft(real(wave1.waveform),1024)); | |||||
| p2=(fft(real(wave2.waveform),1024)); | |||||
| phase_diff=(angle(p1(f1)))-(angle(p2(f1))); | |||||
| %% | |||||
| tic | |||||
| [data,raw] = transferFunction(sc,fg,500,5000,50,10); | |||||
| figure; | |||||
| subplot(2,1,1) | |||||
| semilogx(data.frequency,data.magnitude) | |||||
| subplot(2,1,2) | |||||
| semilogx(data.frequency,data.phase); | |||||
| toc | |||||
| @@ -1,9 +1,9 @@ | |||||
| if ~exist('theory_only','var') || theory_only == false | if ~exist('theory_only','var') || theory_only == false | ||||
| if ~exist('functiongenerator','var') | if ~exist('functiongenerator','var') | ||||
| functiongenerator = FunctionGenerator('10.0.0.3',1234,10); | |||||
| functiongenerator = FunctionGeneratorClass('10.0.0.3',1234,10); | |||||
| end | end | ||||
| if ~exist('oscilloscope','var') | if ~exist('oscilloscope','var') | ||||
| oscilloscope = Oscilloscope('10.0.0.2',5025,2); | |||||
| oscilloscope = OscilloscopeClass('10.0.0.2',5025,2); | |||||
| end | end | ||||
| end | end | ||||
| @@ -0,0 +1,268 @@ | |||||
| classdef ChannelClass | |||||
| % 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. | |||||
| channelnumber % is the number of the channel on the scope. | |||||
| end | |||||
| properties (Dependent) | |||||
| state %is channel enabled or not | |||||
| coupling %DC or AC | |||||
| bandwidth %inputfilter bandwidth | |||||
| scale %Voltage scale in volt/div | |||||
| offset %DC offset | |||||
| probe %probesetting | |||||
| label %name for channel on scope | |||||
| type %set decimation mode | |||||
| probeunit %Define current or voltage probe | |||||
| end | |||||
| methods | |||||
| %Constructor of class | |||||
| function ch = ChannelClass(scope,channelnumber) | |||||
| ch.channelnumber = channelnumber; | |||||
| ch.scope = scope; | |||||
| end | |||||
| %% Get.function section | |||||
| %all get functions pull information from equipment to update | |||||
| %properties. | |||||
| function s = get.state(ch) | |||||
| s = ch.CHAN('state?'); | |||||
| end | |||||
| function out = get.coupling(ch) | |||||
| out = ch.CHAN('coup?'); | |||||
| end | |||||
| function out = get.bandwidth(ch) | |||||
| out = ch.CHAN('band?'); | |||||
| end | |||||
| function out = get.offset(ch) | |||||
| out = ch.CHAN('offs?'); | |||||
| end | |||||
| function out = get.scale(ch) | |||||
| out = ch.CHAN('scal?'); | |||||
| end | |||||
| function out = get.label(ch) | |||||
| out = ch.CHAN('lab?'); | |||||
| end | |||||
| function out = get.type(ch) | |||||
| out = ch.CHAN('type?'); | |||||
| end | |||||
| function out = get.probeunit(ch) | |||||
| out = ch.scope.query(['PROB',num2str(ch.channelnumber),':SET:ATT:UNIT?']); | |||||
| end | |||||
| function out = get.probe(ch) | |||||
| out = ch.scope.query(['PROB',num2str(ch.channelnumber),':SET:ATT:MAN?']); | |||||
| end | |||||
| %% Set.function section | |||||
| % This section contains all functions to change settings of a | |||||
| % channel | |||||
| function ch = set.state(ch,in) | |||||
| %STATE Set the channel on or off. | |||||
| %Options: ON | OFF | |||||
| ch.CHAN('state',in); | |||||
| end | |||||
| function ch = set.coupling(ch,in) | |||||
| %COUPLING Set coupling to one of the following settings: | |||||
| %Options: DCLimit | ACLimit | GND | |||||
| ch.CHAN('coup',in); | |||||
| end | |||||
| function ch = set.bandwidth(ch,in) | |||||
| %BANDWIDTH Set bandwidthlimit. Enable lowpass 20MHz filter | |||||
| %Options: FULL|B20 | |||||
| ch.CHAN('band',in); | |||||
| end | |||||
| function ch = set.offset(ch,in) | |||||
| %OFFSET Sets the DC offset for channel | |||||
| %Range: Depend on vertical scale and probe attenuation. | |||||
| %Increment: Depends on vertical scale and probe attenuation. | |||||
| %On reset: 0 | |||||
| %Default unit: V | |||||
| ch.CHAN('offs',in); | |||||
| end | |||||
| function ch = set.scale(ch,in) | |||||
| %SCALE Sets the scale for the channel | |||||
| % Scale value, given in Volts per division. | |||||
| % Range: 1e-3 to 10 (without probe attenuation) | |||||
| % *RST: 5e-3 | |||||
| % Default unit: V/div | |||||
| ch.CHAN('scal',in); | |||||
| end | |||||
| function ch = set.label(ch,in) | |||||
| %LABEL Sets label of the channel on the scope | |||||
| ch.CHAN('lab',in); | |||||
| end | |||||
| function ch = set.type(ch,in) | |||||
| %Sets the type of the channel | |||||
| ch.CHAN('type',in); | |||||
| end | |||||
| function ch = set.probeunit(ch,unit) | |||||
| ch.scope.write(['PROB',num2str(ch.channelnumber),':SET:ATT:UNIT ', unit]); | |||||
| end | |||||
| function ch = set.probe(ch,man) | |||||
| ch.scope.write(['PROB',num2str(ch.channelnumber),':SET:ATT:MAN ', double2str(man)]); | |||||
| end | |||||
| %% not set or get function | |||||
| function enable(ch) | |||||
| %ENABLE channel | |||||
| ch.state('ON'); | |||||
| end | |||||
| function disable(ch) | |||||
| %DISABLE channel | |||||
| ch.state('OFF'); | |||||
| end | |||||
| function out = frequency(ch) | |||||
| %FREQUENCY gets the measured frequency of current signal. | |||||
| %Equal to one over the period. | |||||
| % See also PERIOD | |||||
| out = str2double(ch.MEAS('freq')); | |||||
| end | |||||
| function out = peak2peak(ch) | |||||
| %PEAK2PEAK gets the peak2peak value of current signal. | |||||
| %Equal to AMPLITUDE times two. | |||||
| out = str2double(ch.MEAS('peak')); | |||||
| end | |||||
| function out = period(ch) | |||||
| %PERIOD Gets the period of the current signal. | |||||
| %Equal to one over the frequency. | |||||
| out = str2double(ch.MEAS('per')); | |||||
| end | |||||
| function out = amplitude(ch) | |||||
| %AMPLITUDE Gets the amplitude of the current signal. | |||||
| %Equal to half the PEAK2PEAK value. | |||||
| %See also PEAK2PEAK | |||||
| out = str2double(ch.MEAS('ampl')); | |||||
| end | |||||
| function out = mean(ch) | |||||
| %MEAN Gets the mean value of the current signal. | |||||
| out = str2double(ch.MEAS('mean')); | |||||
| end | |||||
| function out = rms(ch) | |||||
| %RMS Gets the rms value of the current signal. | |||||
| out = str2double(ch.MEAS('rms')); | |||||
| end | |||||
| function out = phase(ch) | |||||
| %PHASE gets the phase shift between two signals. | |||||
| %Cannot be done on a single channel. | |||||
| out = str2double(ch.MEAS('phas')); | |||||
| end | |||||
| function data = waveform(ch,window) | |||||
| %WAVEFORM allows for the waveform to be downloaded to matlab | |||||
| % data = WAVEFORM(ch,window) gets the waveform from the scope and | |||||
| % returns a array of the waveform. | |||||
| % | |||||
| % WINDOW can be one of the following options: | |||||
| % | |||||
| %*DEFault* (Default option) | |||||
| % Waveform points that are visible on the screen. At maximum | |||||
| % waveform rate, the instrument stores more samples than visible | |||||
| % on the screen, and DEF returns less values than acquired. | |||||
| % | |||||
| %*MAXimum* | |||||
| % All waveform samples that are stored in the memory. Only available | |||||
| % if acquisition is stopped. | |||||
| % | |||||
| %*DMAXimum* | |||||
| % Display maximum: Waveform samples stored in the current | |||||
| % waveform record but only for the displayed time range. At maximum | |||||
| % waveform rate, the instrument stores more samples than | |||||
| % visible on the screen, and DMAX returns more values than DEF. | |||||
| % Only available if acquisition is stopped. | |||||
| % | |||||
| % See also OSCILLOSCOPECLASS.SETWAVEFORMSETTINGS | |||||
| ch.scope.single; | |||||
| if nargin < 2 | |||||
| window = 'DEF'; | |||||
| end | |||||
| ch.scope.setWaveformSettings(window,'REAL') | |||||
| data = ch.getWaveform; | |||||
| end | |||||
| end | |||||
| methods (Hidden, Access = private) | |||||
| function c = CHAN(ch,string,in) | |||||
| % CHAN checks if the string corresponds with a query or write | |||||
| % c = CHAN(ch, string, in) Where 'ch' is the channel-object, | |||||
| % 'string' is a part of the SCPI-command and 'in' is the actual | |||||
| % value is to be set. 'in' is optional. | |||||
| if nargin == 2 %If only ch and string are given it can be a query | |||||
| if strcmp(string(end),'?') %If the string ends with a '?' then it is a query. | |||||
| c = ch.scope.query(['CHAN',num2str(ch.channelnumber),':',string]); | |||||
| else %Without 'in' and no string it is a event. | |||||
| ch.scope.write(['CHAN',num2str(ch.channelnumber),':',string]); | |||||
| end | |||||
| else %If there is a third argument then the setting should be uploaded to the scope. | |||||
| ch.scope.write(['CHAN',num2str(ch.channelnumber),':',string,' ',in]); | |||||
| end | |||||
| end | |||||
| end | |||||
| methods (Hidden) | |||||
| function data = getWaveform(ch) | |||||
| %GETWAVEFORM Downloads and processes the waveform from scope. | |||||
| header = str2double(ch.CHAN('DATA:HEAD?')); %downloads the dataheader of the waveform that is stored on the scope. | |||||
| data.start = header(1); %First position in header is starttime in seconds | |||||
| data.stop = header(2); %Second position in header is stoptime in seconds | |||||
| data.length = header(3); %Thirth position in header is record length of the waveform in samples. | |||||
| data.sampletime = str2double(ch.CHAN('DATA:XINC?')); %Sample time is downloaded from scope. | |||||
| ch.scope.opc; %Wait for scope. | |||||
| ch.scope.write_unsafe(['CHAN',num2str(ch.channelnumber),':DATA?']); %Send command to download the data. | |||||
| %NOTE! Must be done with write_unsafe. Normal WRITE would also | |||||
| %check if there are errors but this will interfere with the | |||||
| %datastream. | |||||
| data.data = ch.scope.readWaveform(data.length); %Read data from buffer. | |||||
| end | |||||
| function c = MEAS(ch,string) | |||||
| %MEAS makes all the measurement-functions easier. | |||||
| %Most of the measurements queries start with | |||||
| %MEAS<m>:RESult:ACT? Thus goes automatic right now. | |||||
| c = ch.scope.query(['MEAS',num2str(ch.channelnumber),':RES:ACT?',string]); | |||||
| end | |||||
| % function c = CHANsend(ch,string,in) | |||||
| % c = ['CHAN',num2str(ch.channelnumber),':',string,' ',in]; | |||||
| % end | |||||
| end | |||||
| end | |||||
| @@ -1,12 +1,12 @@ | |||||
| classdef Equipment < handle | |||||
| classdef EquipmentClass < handle | |||||
| %EQUIPMENT Summary of this class goes here | %EQUIPMENT Summary of this class goes here | ||||
| % Detailed explanation goes here | % Detailed explanation goes here | ||||
| properties (SetAccess=protected) | properties (SetAccess=protected) | ||||
| name | |||||
| tcp | |||||
| channel | |||||
| locked | |||||
| name %name of equipment | |||||
| tcp %TCP-object with connection to equipment | |||||
| channel %GPIB-channel if equipment is connected via prologix | |||||
| locked %lock frontpanel | |||||
| manufacturer | manufacturer | ||||
| model | model | ||||
| serialnumber | serialnumber | ||||
| @@ -20,13 +20,13 @@ classdef Equipment < handle | |||||
| end | end | ||||
| methods | methods | ||||
| function ecq = Equipment(ipAddress,port,channel) | |||||
| function ecq = EquipmentClass(ipAddress,port,channel) | |||||
| %EQUIPMENT Construct an instance of this class. | %EQUIPMENT Construct an instance of this class. | ||||
| % This functions opens the required TCP connection | % This functions opens the required TCP connection | ||||
| % for this device. Channel is GPIB-channel on prologix | % for this device. Channel is GPIB-channel on prologix | ||||
| % converter if used, otherwise set channel to -1. | % converter if used, otherwise set channel to -1. | ||||
| % Name is queried from device via '*IDN?' command. | % Name is queried from device via '*IDN?' command. | ||||
| ecq.tcp = Equipment.getTCP(ipAddress,port); | |||||
| ecq.tcp = EquipmentClass.getTCP(ipAddress,port); | |||||
| ecq.locked = false; | ecq.locked = false; | ||||
| ecq.channel = channel; | ecq.channel = channel; | ||||
| ecq.name = ecq.idn(); | ecq.name = ecq.idn(); | ||||
| @@ -74,8 +74,10 @@ classdef Equipment < handle | |||||
| ecq.write_unsafe('*OPC?'); | ecq.write_unsafe('*OPC?'); | ||||
| for i = 1:10 | for i = 1:10 | ||||
| ack = ecq.read; | ack = ecq.read; | ||||
| if strcmp(ack(1),'1') | |||||
| return | |||||
| if ~isempty(ack) | |||||
| if strcmp(ack(1),'1') | |||||
| return | |||||
| end | |||||
| end | end | ||||
| end | end | ||||
| error('Device is not ready'); | error('Device is not ready'); | ||||
| @@ -180,7 +182,7 @@ classdef Equipment < handle | |||||
| %The function will pull all errors from the device error stack. | %The function will pull all errors from the device error stack. | ||||
| %This is up to a maximum of 20 errors. If errors have occured | %This is up to a maximum of 20 errors. If errors have occured | ||||
| %the function will throw a warning with all the error messages. | %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. | output = ecq.query_unsafe('SYSTem:ERRor?'); %Query error message from device. | ||||
| % [msgstr, msgid] = lastwarn; | % [msgstr, msgid] = lastwarn; | ||||
| % if strcmp(msgid,'instrument:fscanf:unsuccessfulRead') | % if strcmp(msgid,'instrument:fscanf:unsuccessfulRead') | ||||
| @@ -258,14 +260,17 @@ classdef Equipment < handle | |||||
| methods (Access = protected, Hidden) | methods (Access = protected, Hidden) | ||||
| function setPrologix(ecq) | function setPrologix(ecq) | ||||
| %SETPROLOGIX Set the correct default settings | |||||
| ecq.write_unsafe('++mode 1'); %set device in controller mode | 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('++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 | end | ||||
| function delete(ecq) | function delete(ecq) | ||||
| %DELETE Destructs the current object. | %DELETE Destructs the current object. | ||||
| ecq.unlock; | ecq.unlock; | ||||
| Equipment.getTCP(ecq.tcp.RemoteHost,-ecq.tcp.RemotePort); | |||||
| EquipmentClass.getTCP(ecq.tcp.RemoteHost,-ecq.tcp.RemotePort); | |||||
| end | end | ||||
| end | end | ||||
| @@ -287,7 +292,7 @@ classdef Equipment < handle | |||||
| %call) make a struct in the variable. | %call) make a struct in the variable. | ||||
| tcpconnection = struct; | tcpconnection = struct; | ||||
| end | 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. | if port > 0 %if port number is positive a connection is made. | ||||
| @@ -329,7 +334,7 @@ classdef Equipment < handle | |||||
| function num = forceNum(input) | function num = forceNum(input) | ||||
| %FORCENUM Throws an error if the input is not numeric. | %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.'); | error('Input should be a (single) number.'); | ||||
| end | end | ||||
| num = input; | num = input; | ||||
| @@ -344,10 +349,13 @@ classdef Equipment < handle | |||||
| end | end | ||||
| function output = optionnum2str(input) | function output = optionnum2str(input) | ||||
| %OPTIONNUM2STR Change numeric or string input to string output | |||||
| if isnum(input) | if isnum(input) | ||||
| output = num2str(input); | |||||
| else | |||||
| output = num2str(real(input)); | |||||
| elseif ischar(input) | |||||
| output = input; | output = input; | ||||
| else | |||||
| error("Expected a character array or numeric value as input"); | |||||
| end | end | ||||
| end | end | ||||
| @@ -356,8 +364,71 @@ classdef Equipment < handle | |||||
| %structname to store stuff in struct (especially for GETTCP). | %structname to store stuff in struct (especially for GETTCP). | ||||
| %cleanip is a shortened ip without leading zeros. | %cleanip is a shortened ip without leading zeros. | ||||
| cleanip = regexprep(ipAddress,'(?:(?<=\.)|^)(?:0+)(?=\d)',''); | cleanip = regexprep(ipAddress,'(?:(?<=\.)|^)(?:0+)(?=\d)',''); | ||||
| Equipment.iptest(cleanip); | |||||
| EquipmentClass.iptest(cleanip); | |||||
| structname = matlab.lang.makeValidName(['ip',cleanip,'_',num2str(port)]); | structname = matlab.lang.makeValidName(['ip',cleanip,'_',num2str(port)]); | ||||
| end | end | ||||
| function ipaddress = getInterfaceIP() | |||||
| %GETINTERFACEIP gets the local ipaddresses on this machine. | |||||
| if ispc | |||||
| % Code to run on Windows plaform | |||||
| [status,result]=system('ipconfig'); | |||||
| if ~(status == 0) | |||||
| error('Failed to find local IP address'); | |||||
| end | |||||
| ipaddress = regexp(result,'(?<=\n IPv4 Address[ \.]*: )([0-9]{1,3}\.?){4}','match'); | |||||
| elseif ismac | |||||
| % Code to run on Mac platform | |||||
| [status,result]=system('ifconfig'); | |||||
| if ~(status == 0) | |||||
| error('Failed to find local IP address'); | |||||
| end | |||||
| ipaddress = regexp(result,'(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])(?=\/)','match'); | |||||
| elseif isunix | |||||
| % Code to run on Unix platform | |||||
| [status,result]=system('ip addr show'); | |||||
| if ~(status == 0) | |||||
| error('Failed to find local IP address'); | |||||
| end | |||||
| ipaddress = regexp(result,'(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])(?=\/)','match'); | |||||
| else | |||||
| error('Platform not supported'); | |||||
| end | |||||
| end | |||||
| function prologixIP = discoverPrologix() | |||||
| %DISCOVERPROLOGIX attemts to find the prologix on the network. | |||||
| %It will broadcast on all interfaces and return the ipaddress | |||||
| %of the prologix. Not build for multiple prologixs on a single | |||||
| %network. | |||||
| persistent storedipaddress; %store the ipaddress of the prologix | |||||
| if ~isempty(storedipaddress) | |||||
| prologixIP = storedipaddress; | |||||
| return | |||||
| end | |||||
| remotehost = '255.255.255.255'; %set broadcast address | |||||
| remoteport = 3040; %set remoteport that is used for the prologix discoverprotocol | |||||
| timeout = 1; %set timeout on package. | |||||
| % magic string to request ipaddress from prologix: ['5a' '00' '5b' 'db' 'ff' 'ff' 'ff' 'ff' 'ff' 'ff' '00' '00'] | |||||
| magic_msg = uint8([90 0 91 219 255 255 255 255 255 255 00 00]); | |||||
| ipaddress = EquipmentClass.getInterfaceIP(); %get all interface addresses from getInterfaceIP. | |||||
| %create an UDPconnection-object for each interface. | |||||
| udpconnection = cellfun(@(ip) udp(remotehost,remoteport,'LocalHost',ip,'Timeout',timeout),ipaddress,'UniformOutput',0); | |||||
| cellfun(@fopen,udpconnection); %open all udpconnections | |||||
| cellfun(@(udpconnection) fwrite(udpconnection,magic_msg),udpconnection); %broadcast the magic_msg via all udpconnections | |||||
| for i = 1:10 | |||||
| answer = cellfun(@fread,udpconnection,'UniformOutput',0); %read all udpInputBuffers for response from prologix | |||||
| ack = ~cellfun(@isempty,answer); %check if prologix responded on one of the interfaces. | |||||
| if sum(ack) > 0 %true if recieved response | |||||
| msg = answer{ack}; %put message from answer cell in to msg variable | |||||
| prologixIP = num2str(msg(21:24)','%d.%d.%d.%d'); %get ipaddress from msg. | |||||
| cellfun(@fclose,udpconnection); %close all connections | |||||
| storedipaddress = prologixIP; %store ip-address for next functioncall | |||||
| return | |||||
| end | |||||
| end | |||||
| cellfun(@fclose,udpconnection); %close all connections | |||||
| prologixIP = ''; %nothing found, return empty chararray. | |||||
| end | |||||
| end | 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 | % to a function generator on IPv4 address 'IP', on port | ||||
| % 'PORT' and GPIO channel 'GPIB_CHAN', using the Equipment | % 'PORT' and GPIO channel 'GPIB_CHAN', using the Equipment | ||||
| % class. | % class. | ||||
| % | % | ||||
| % See also EQUIPMENT, OSCILLOSCOPE, DIGITALMULTIMETER. | |||||
| % See also EQUIPMENTCLASS, OSCILLOSCOPECLASS, DIGITALMULTIMETERCLASS. | |||||
| properties (Dependent) | 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 | end | ||||
| methods | 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 | % to a function generator on IPv4 address 'IP', on port | ||||
| % 'PORT' and GPIO channel 'GPIB_CHAN', using the Equipment | % 'PORT' and GPIO channel 'GPIB_CHAN', using the Equipment | ||||
| % class. | % class. | ||||
| % | % | ||||
| % See also EQUIPMENT, OSCILLOSCOPE, DIGITALMULTIMETER. | |||||
| fg@Equipment(ipAddress,port,channel); | |||||
| % See also EQUIPMENTCLASS, OSCILLOSCOPECLASS, DIGITALMULTIMETERCLASS. | |||||
| fg@EquipmentClass(ipAddress,port,channel); | |||||
| end | end | ||||
| function w = get.waveform(fg) | function w = get.waveform(fg) | ||||
| %Get the function generator waveform setting on waveform | %Get the function generator waveform setting on waveform | ||||
| % variable access, using the corresponding SCPI command. | % variable access, using the corresponding SCPI command. | ||||
| w = FunctionGenerator.getWave(fg.query('FUNCtion:SHAPe?')); | |||||
| w = FunctionGeneratorClass.getWave(fg.query('FUNCtion:SHAPe?')); | |||||
| end | end | ||||
| function f = get.frequency(fg) | function f = get.frequency(fg) | ||||
| @@ -53,7 +51,7 @@ classdef FunctionGenerator < Equipment | |||||
| function u = get.unit(fg) | function u = get.unit(fg) | ||||
| %Get function generator output voltage unit setting on offset | %Get function generator output voltage unit setting on offset | ||||
| % variable access, using the corresponding SCPI command. | % variable access, using the corresponding SCPI command. | ||||
| u = FunctionGenerator.getUnit(fg.query('VOLTage:UNIT?')); | |||||
| u = FunctionGeneratorClass.getUnit(fg.query('VOLTage:UNIT?')); | |||||
| end | end | ||||
| function o = get.offset(fg) | function o = get.offset(fg) | ||||
| @@ -65,7 +63,7 @@ classdef FunctionGenerator < Equipment | |||||
| function l = get.load(fg) | function l = get.load(fg) | ||||
| %Get function generator load setting on load variable | %Get function generator load setting on load variable | ||||
| % access, using the corresponding SCPI command. | % access, using the corresponding SCPI command. | ||||
| l = FunctionGenerator.getLoad(fg.query('OUTPut:LOAD?')); | |||||
| l = FunctionGeneratorClass.getLoad(fg.query('OUTPut:LOAD?')); | |||||
| end | end | ||||
| function out = get.output(fg) | function out = get.output(fg) | ||||
| @@ -79,7 +77,7 @@ classdef FunctionGenerator < Equipment | |||||
| function fg = set.waveform(fg,w) | function fg = set.waveform(fg,w) | ||||
| %Set function generator waveform setting on waveform variable | %Set function generator waveform setting on waveform variable | ||||
| % access, using the corresponding SCPI command. | % access, using the corresponding SCPI command. | ||||
| fg.write(['FUNCtion:SHAPe ' FunctionGenerator.getWave(w)]); | |||||
| fg.write(['FUNCtion:SHAPe ' FunctionGeneratorClass.getWave(w)]); | |||||
| end | end | ||||
| function fg = set.frequency(fg,f) | function fg = set.frequency(fg,f) | ||||
| @@ -99,7 +97,7 @@ classdef FunctionGenerator < Equipment | |||||
| function fg = set.unit(fg,u) | function fg = set.unit(fg,u) | ||||
| %Set function generator output voltage unit setting on unit | %Set function generator output voltage unit setting on unit | ||||
| % variable access, using the corresponding SCPI command. | % variable access, using the corresponding SCPI command. | ||||
| fg.write(['VOLTage:UNIT ' FunctionGenerator.getUnit(u)]); | |||||
| fg.write(['VOLTage:UNIT ' FunctionGeneratorClass.getUnit(u)]); | |||||
| end | end | ||||
| function fg = set.offset(fg,o) | function fg = set.offset(fg,o) | ||||
| @@ -112,16 +110,37 @@ classdef FunctionGenerator < Equipment | |||||
| function fg = set.load(fg,l) | function fg = set.load(fg,l) | ||||
| %Set function generator load setting on load variable access, | %Set function generator load setting on load variable access, | ||||
| % using the corresponding SCPI command. | % using the corresponding SCPI command. | ||||
| fg.write(['OUTPut:LOAD ' FunctionGenerator.getLoad(l)]); | |||||
| fg.write(['OUTPut:LOAD ' FunctionGeneratorClass.getLoad(l)]); | |||||
| end | end | ||||
| function fg = set.output(fg,out) | function fg = set.output(fg,out) | ||||
| if strcmp(fg.model(1:3),'335') || strcmp(fg.model(1:3),'332') | 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 | ||||
| end | end | ||||
| function downloadwaveform(fg,waveform,name) | 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.disableEOI; | ||||
| fg.write_unsafe(['data:arb ' name ',']); | fg.write_unsafe(['data:arb ' name ',']); | ||||
| fg.enableEOI; | fg.enableEOI; | ||||
| @@ -136,7 +155,6 @@ classdef FunctionGenerator < Equipment | |||||
| x = linspace(-periods*pi,periods*pi,1600); | x = linspace(-periods*pi,periods*pi,1600); | ||||
| y = exp(-abs(x./6)).*sin(x)./0.8; | y = exp(-abs(x./6)).*sin(x)./0.8; | ||||
| fg.downloadwaveform(y,'scintilla'); | fg.downloadwaveform(y,'scintilla'); | ||||
| end | end | ||||
| end | end | ||||
| @@ -1,161 +0,0 @@ | |||||
| classdef Oscilloscope < Equipment | |||||
| %OSCILLOSCOPE Summary of this class goes here | |||||
| % Detailed explanation goes here | |||||
| properties | |||||
| nchannels | |||||
| horizontalPosition | |||||
| timescale | |||||
| ch1 | |||||
| ch2 | |||||
| ch3 | |||||
| ch4 | |||||
| trigger | |||||
| acquisition | |||||
| end | |||||
| methods | |||||
| function sc = Oscilloscope(ipAddress,port,nchannels) | |||||
| %OSCILLOSCOPE Construct an instance of this class | |||||
| % Detailed explanation goes here | |||||
| sc@Equipment(ipAddress,port,-1); | |||||
| sc.trigger = Trigger(sc); | |||||
| sc.nchannels = nchannels; | |||||
| for i = 1:nchannels | |||||
| sc.(['ch',num2str(i)]) = Channel(sc,i); | |||||
| end | |||||
| end | |||||
| function clear(sc) | |||||
| sc.messageclose; | |||||
| sc.write_unsafe('*cls'); | |||||
| flushinput(sc.tcp); | |||||
| end | |||||
| function s = get.acquisition(sc) | |||||
| s = sc.query('ACQ:STAT?'); | |||||
| end | |||||
| function run(sc) | |||||
| sc.write_noerror('RUN'); | |||||
| end | |||||
| function single(sc) | |||||
| sc.write_noerror('SING'); | |||||
| end | |||||
| function stop(sc) | |||||
| sc.write_noerror('STOP'); | |||||
| end | |||||
| function auto(sc) | |||||
| sc.write_noerror('AUT'); | |||||
| end | |||||
| function enable_channels(sc) | |||||
| sc.write('CHAN:AON') | |||||
| end | |||||
| function disable_channels(sc) | |||||
| sc.write('CHAN:AOFF') | |||||
| end | |||||
| function setMeasurement(sc,measurement,type,source1,source2) | |||||
| prefix = ['MEAS',num2str(measurement),':']; | |||||
| fprintf(num2str(nargin)) | |||||
| if nargin < 5 | |||||
| source2 = 'CH2'; | |||||
| if nargin < 4 | |||||
| source1 = 'CH1'; | |||||
| end | |||||
| end | |||||
| source = [source1,', ',source2]; | |||||
| sc.write([prefix,'SOUR ',source]); | |||||
| sc.write([prefix,'MAIN ',type]); | |||||
| end | |||||
| function m = getMeasurement(sc,measurement) | |||||
| m = str2double(sc.query(['MEAS',num2str(measurement),':RES:ACT?'])); | |||||
| end | |||||
| function setWaveformSettings(sc,window,format,type) | |||||
| if nargin < 4 | |||||
| type = 'HRES'; | |||||
| if nargin < 3 | |||||
| format = 'REAL'; | |||||
| if nargin < 2 | |||||
| window = 'DEF'; | |||||
| end | |||||
| end | |||||
| end | |||||
| sc.clear; | |||||
| sc.write(['CHAN:TYPE ',type]); | |||||
| sc.write(['FORM ',format]); | |||||
| sc.write('FORM:BORD MSBF'); | |||||
| sc.write(['CHAN:DATA:POIN ',window]); | |||||
| sc.single; | |||||
| end | |||||
| function data = readWaveform(sc,datalength) | |||||
| prefixstring = fscanf(sc.tcp,'%c',2); | |||||
| prefixlength = str2double(prefixstring(2)); | |||||
| fscanf(sc.tcp,'%c',prefixlength); | |||||
| data = sc.bin_read_float(datalength); | |||||
| flushinput(sc.tcp); | |||||
| end | |||||
| function data = waveform(sc,channels,window,type) | |||||
| if nargin < 4 | |||||
| type = 'HRES'; | |||||
| if nargin < 3 | |||||
| window = 'DEF'; | |||||
| if nargin < 2 | |||||
| channels = 1:sc.nchannels; | |||||
| end | |||||
| end | |||||
| end | |||||
| sc.enable_channels; | |||||
| sc.setWaveformSettings(window,'REAL',type); | |||||
| for i = channels | |||||
| curcha = ['ch',num2str(i)]; | |||||
| wave = sc.(curcha).getWaveform; | |||||
| data.(curcha) = wave.data; | |||||
| end | |||||
| data.sampletime = wave.sampletime; | |||||
| data.length = wave.length; | |||||
| end | |||||
| function message(sc,msg) | |||||
| sc.messageclose; | |||||
| sc.write(['DISP:DIAL:MESS ''',msg,'''']) | |||||
| end | |||||
| function messageclose(sc) | |||||
| sc.opc; | |||||
| sc.write_unsafe('DISP:DIAL:CLOS'); | |||||
| end | |||||
| % function data = waveform(ch,cha) | |||||
| % ch.scope.clear; | |||||
| % ch.scope.write('CHAN1:TYPE HRES'); | |||||
| % ch.scope.write('FORM REAL'); | |||||
| % ch.scope.write('FORM:BORD MSBF'); | |||||
| % ch.scope.write('CHAN1:DATA:POIN DEF'); | |||||
| % ch.scope.write('SING'); | |||||
| % header = str2num(ch.scope.query('CHAN1:DATA:HEAD?')); | |||||
| % ch.scope.write_unsafe('CHAN1:DATA?'); | |||||
| % prefixstring = fscanf(ch.scope.tcp,'%c',2); | |||||
| % prefixlength = str2double(prefixstring(2)); | |||||
| % datalength = fscanf(ch.scope.tcp,'%c',prefixlength); | |||||
| % data = fread(ch.scope.tcp,header(3),'float'); | |||||
| % flushinput(ch.scope.tcp); | |||||
| % end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,238 @@ | |||||
| classdef OscilloscopeClass < EquipmentClass | |||||
| %OSCILLOSCOPE is the classdef for a Oscilloscope | |||||
| % This oscilloscope object can contain multiple channels and trigger | |||||
| % settings. | |||||
| % EQUIPMENT is the parent class of OSCILLOSCOPE | |||||
| % This class contains objects for each channel and the trigger. | |||||
| % See also: TRIGGER, CHANNEL | |||||
| properties | |||||
| nchannels %number of channels the scope has | |||||
| horizontalPosition %horizontal position in seconds | |||||
| timescale %horizontal scale in seconds/div | |||||
| ch1 %channel 1 object | |||||
| ch2 %channel 2 object (empty if NCHANNELS < 2) | |||||
| ch3 %channel 3 object (empty if NCHANNELS < 3) | |||||
| ch4 %channel 4 object (empty if NCHANNELS < 4) | |||||
| trigger %trigger object | |||||
| end | |||||
| properties (Dependent) | |||||
| acquisition %acquisition setting (stop|run|single) | |||||
| end | |||||
| methods | |||||
| function sc = OscilloscopeClass(ipAddress,port,nchannels) | |||||
| %OSCILLOSCOPE Construct an instance of this class | |||||
| % This constructor creates a new scope 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 | |||||
| sc.(['ch',num2str(i)]) = ChannelClass(sc,i); | |||||
| end | |||||
| end | |||||
| function clear(sc) | |||||
| %CLEAR is used to clear the oscilloscope. | |||||
| % closes the message on screen | |||||
| % sends the clear command to the scope and flushes the | |||||
| % TCP-buffer. | |||||
| sc.messageclose; | |||||
| sc.write_unsafe('*cls'); | |||||
| flushinput(sc.tcp); | |||||
| end | |||||
| function s = get.acquisition(sc) | |||||
| %ACQUISITION returns the acquisition state from the scope. | |||||
| s = sc.query('ACQ:STAT?'); | |||||
| end | |||||
| function run(sc) | |||||
| %RUN sets the ACQUISITION state to run. | |||||
| sc.write_noerror('RUN'); | |||||
| end | |||||
| function single(sc) | |||||
| %SINGLE sets the ACQUISITION state to single | |||||
| %After running a single acquisition the scope will go to STOP | |||||
| sc.write_noerror('SING'); | |||||
| end | |||||
| function stop(sc) | |||||
| %STOP sets the ACQUISITION state to stop. | |||||
| %Stops the signal acquisition imidiatly. Use SINGLE to run one | |||||
| %single waveform acquisition before stopping. | |||||
| %See also RUN, SINGLE | |||||
| sc.write_noerror('STOP'); | |||||
| end | |||||
| function auto(sc) | |||||
| %AUTO sends the autoset command to the scope. | |||||
| %It should be noted that this function can result in aliassing | |||||
| %of the wave acquisition. | |||||
| sc.write_noerror('AUT'); | |||||
| end | |||||
| function enable_channels(sc,channels) | |||||
| %ENABLE_CHANNELS enables all available channels on scope. | |||||
| if nargin < 2 | |||||
| sc.write('CHAN:AON'); | |||||
| else | |||||
| for i = channels | |||||
| sc.(['ch' num2str(i)]).enable; | |||||
| end | |||||
| end | |||||
| end | |||||
| function disable_channels(sc,channels) | |||||
| %DISABLE_CHANNELS disables all available channels on scope. | |||||
| if nargin < 2 | |||||
| sc.write('CHAN:AOFF'); | |||||
| else | |||||
| for i = channels | |||||
| sc.(['ch' num2str(i)]).disable; | |||||
| end | |||||
| end | |||||
| end | |||||
| function setMeasurement(sc,measurement,type,source1,source2) | |||||
| %SETMEASUREMENT sets the measurement slots on the scope. | |||||
| %SETMEASUREMENT(sc, measurement, type, source1 [,source2]); | |||||
| %sets one of the measurement place with 'measurement', this can | |||||
| %be a value in the range 1 till 4. 'source1' and 'source2' give | |||||
| %on what channel the measurement should be applied. This should | |||||
| %be done in de form of 'CH<m>' where <m> = 1..4. The default | |||||
| %settings are: source1 = 'CH1' and source2 = 'CH2' | |||||
| %With 'type' a measurement type can be selected. Some of the | |||||
| %measurements require at least 2 channels. | |||||
| % | |||||
| %SINGLE CHANNEL: | |||||
| % FREQuency | PERiod | PEAK | UPEakvalue | LPEakvalue | | |||||
| % PPCount | NPCount | RECount | FECount | HIGH | LOW | | |||||
| % AMPLitude | MEAN | RMS | RTIMe | FTIMe | PDCYcle | | |||||
| % NDCYcle | PPWidth | NPWidth | CYCMean | CYCRms | | |||||
| % STDDev | CYCStddev | BWIDth | POVershoot | NOVershoot | |||||
| % | |||||
| %DOUBLE CHANNEL: | |||||
| % DELay | PHASe | |||||
| prefix = ['MEAS',num2str(measurement),':']; %define the prefix for the SCPI command. | |||||
| %fprintf(num2str(nargin)) | |||||
| %set the default values. | |||||
| if nargin < 5 | |||||
| source2 = 'CH2'; | |||||
| if nargin < 4 | |||||
| source1 = 'CH1'; | |||||
| end | |||||
| end | |||||
| source = [source1,', ',source2]; %set the sources suffix | |||||
| sc.write([prefix,'SOUR ',source]); %set the sources for the measurementposition | |||||
| sc.write([prefix,'MAIN ',type]); %set the measurementtype for the measurementposition | |||||
| end | |||||
| function m = getMeasurement(sc,measurement) | |||||
| %GETMEASUREMENT pulls the value from measurementposition. | |||||
| %m = GETMEASUREMENT(sc,measurement) will return the value that | |||||
| %was acquired from the measurementslot (given as | |||||
| %'measurement') as a double. | |||||
| m = str2double(sc.query(['MEAS',num2str(measurement),':RES:ACT?'])); | |||||
| end | |||||
| function setWaveformSettings(sc,window,format,type) | |||||
| %SETWAVEFORMSETTINGS sets the settings to acquire the waveform | |||||
| %Before the waveform can be downloaded the aquisition settings | |||||
| %for the channels and/or scope must be set: | |||||
| %SETWAVEFORMSETTINGS(sc,window,format,type) where: | |||||
| %'window' | |||||
| % Set the acquisition window of the waveform. Possible settings | |||||
| % are: DEF (default option) | MAX | DMAX | |||||
| % See also CHANNELCLASS.WAVEFORM | |||||
| % | |||||
| %'format' | |||||
| % Set the dataformat of the data. ASCii|REAL (default option)|UINTeger | |||||
| % | |||||
| %'type' | |||||
| % Set resolution mode. SAMPle (default option)| PDETect | HRESolution | |||||
| if nargin < 4 | |||||
| type = 'HRES'; | |||||
| if nargin < 3 | |||||
| format = 'REAL'; | |||||
| if nargin < 2 | |||||
| window = 'DEF'; | |||||
| end | |||||
| end | |||||
| end | |||||
| sc.clear; | |||||
| sc.write(['CHAN:TYPE ',type]); %set resolution | |||||
| sc.write(['FORM ',format]); %set dataformat | |||||
| sc.write('FORM:BORD MSBF'); %set bitorder to Most Significant Bit First | |||||
| sc.write(['CHAN:DATA:POIN ',window]); %set window length | |||||
| sc.single; %run sigle acquisition | |||||
| end | |||||
| function data = readWaveform(sc,datalength) | |||||
| %READWAVEFORM download waveform from oscilloscope | |||||
| %Downloads the data from oscilloscope with BIN_READ_FLOAT. | |||||
| %Datastream is constructed as follows: | |||||
| % #41024<value1><value2>…<value n> | |||||
| %#4 = number of digits of the following number (= 4 in the example) | |||||
| %in the code these two are stored as 'prefixstring'. | |||||
| %1024 = number of following data bytes. | |||||
| %This breaks if there the TCP-buffer was not cleared before the | |||||
| %SCPI-command 'CHAN:DATA?' was send. | |||||
| prefixstring = fscanf(sc.tcp,'%c',2);%read the first 2 characters of the tcp-buffer and store in prefixstring. | |||||
| prefixlength = str2double(prefixstring(2));%change the second character of prefixstring to double. (this leaves the # behind) | |||||
| fscanf(sc.tcp,'%c',prefixlength);%read the number of characters equal to the number from the prefixlength. | |||||
| data = sc.bin_read_float(datalength); %run the function from the EQUIPMENTCLASS to download all the data. | |||||
| flushinput(sc.tcp);%after the download make sure that nothing is left behind in the tcpbuffer. | |||||
| end | |||||
| function data = waveform(sc,channels,window,type) | |||||
| %WAVEFORM downloads waveform of one or more channels. | |||||
| %data = WAVEFORM(sc,channels,window,type) returns a struct with | |||||
| %all waveformdata from the scope. This includes the sampletime | |||||
| %and data length. | |||||
| %'channels' is an array of all the channels that the function | |||||
| %should acquire. | |||||
| %'window' is the width of the data acquisition. | |||||
| %'type' is the resolution mode. | |||||
| %See also: SETWAVEFORMSETTINGS | |||||
| if nargin < 4 | |||||
| type = 'HRES'; %default resolution is high resolution | |||||
| if nargin < 3 | |||||
| window = 'DEF'; %default windowsize is DEFault | |||||
| if nargin < 2 | |||||
| channels = 1:sc.nchannels; %default selection channels is all channels | |||||
| end | |||||
| end | |||||
| end | |||||
| sc.enable_channels(channels);%enable the channels for the acquisition | |||||
| sc.setWaveformSettings(window,'REAL',type);%Set the correct settings | |||||
| for i = channels | |||||
| curcha = ['ch',num2str(i)]; %make string for current channel | |||||
| wave = sc.(curcha).getWaveform; %get waveformdata from current channel | |||||
| data.(curcha) = wave.data; %store wavefromdata from wave-struct into data-struct. | |||||
| end | |||||
| data.sampletime = wave.sampletime; %together with the waveforms add sampletime and datalength to data-struct. | |||||
| data.length = wave.length; | |||||
| end | |||||
| function message(sc,msg) | |||||
| %MESSAGE Print message on screen of oscilloscope. | |||||
| sc.messageclose; | |||||
| sc.write(['DISP:DIAL:MESS ''',msg,''''])%send message | |||||
| end | |||||
| function messageclose(sc) | |||||
| %MESSAGECLOSE Close message on the screen of oscillscope. | |||||
| sc.opc; %wait on ready from scope. | |||||
| sc.write_unsafe('DISP:DIAL:CLOS'); %clear message | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,4 +1,4 @@ | |||||
| classdef Trigger | |||||
| classdef TriggerClass | |||||
| %TRIGGER Summary of this class goes here | %TRIGGER Summary of this class goes here | ||||
| % Detailed explanation goes here | % Detailed explanation goes here | ||||
| @@ -17,7 +17,7 @@ classdef Trigger | |||||
| end | end | ||||
| methods | methods | ||||
| function tr = Trigger(scope) | |||||
| function tr = TriggerClass(scope) | |||||
| tr.scope = scope; | tr.scope = scope; | ||||
| end | end | ||||
| @@ -0,0 +1,418 @@ | |||||
| <!DOCTYPE html | |||||
| PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |||||
| <html><head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |||||
| <!-- | |||||
| This HTML was auto-generated from MATLAB code. | |||||
| To make changes, update the MATLAB code and republish this document. | |||||
| --><title>Channel</title><meta name="generator" content="MATLAB 9.4"><link rel="schema.DC" href="http://purl.org/dc/elements/1.1/"><meta name="DC.date" content="2018-03-24"><meta name="DC.source" content="Channel.m"><style type="text/css"> | |||||
| html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outine:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0} | |||||
| html { min-height:100%; margin-bottom:1px; } | |||||
| html body { height:100%; margin:0px; font-family:Arial, Helvetica, sans-serif; font-size:10px; color:#000; line-height:140%; background:#fff none; overflow-y:scroll; } | |||||
| html body td { vertical-align:top; text-align:left; } | |||||
| h1 { padding:0px; margin:0px 0px 25px; font-family:Arial, Helvetica, sans-serif; font-size:1.5em; color:#d55000; line-height:100%; font-weight:normal; } | |||||
| h2 { padding:0px; margin:0px 0px 8px; font-family:Arial, Helvetica, sans-serif; font-size:1.2em; color:#000; font-weight:bold; line-height:140%; border-bottom:1px solid #d6d4d4; display:block; } | |||||
| h3 { padding:0px; margin:0px 0px 5px; font-family:Arial, Helvetica, sans-serif; font-size:1.1em; color:#000; font-weight:bold; line-height:140%; } | |||||
| a { color:#005fce; text-decoration:none; } | |||||
| a:hover { color:#005fce; text-decoration:underline; } | |||||
| a:visited { color:#004aa0; text-decoration:none; } | |||||
| p { padding:0px; margin:0px 0px 20px; } | |||||
| img { padding:0px; margin:0px 0px 20px; border:none; } | |||||
| p img, pre img, tt img, li img, h1 img, h2 img { margin-bottom:0px; } | |||||
| ul { padding:0px; margin:0px 0px 20px 23px; list-style:square; } | |||||
| ul li { padding:0px; margin:0px 0px 7px 0px; } | |||||
| ul li ul { padding:5px 0px 0px; margin:0px 0px 7px 23px; } | |||||
| ul li ol li { list-style:decimal; } | |||||
| ol { padding:0px; margin:0px 0px 20px 0px; list-style:decimal; } | |||||
| ol li { padding:0px; margin:0px 0px 7px 23px; list-style-type:decimal; } | |||||
| ol li ol { padding:5px 0px 0px; margin:0px 0px 7px 0px; } | |||||
| ol li ol li { list-style-type:lower-alpha; } | |||||
| ol li ul { padding-top:7px; } | |||||
| ol li ul li { list-style:square; } | |||||
| .content { font-size:1.2em; line-height:140%; padding: 20px; } | |||||
| pre, code { font-size:12px; } | |||||
| tt { font-size: 1.2em; } | |||||
| pre { margin:0px 0px 20px; } | |||||
| pre.codeinput { padding:10px; border:1px solid #d3d3d3; background:#f7f7f7; } | |||||
| pre.codeoutput { padding:10px 11px; margin:0px 0px 20px; color:#4c4c4c; } | |||||
| pre.error { color:red; } | |||||
| @media print { pre.codeinput, pre.codeoutput { word-wrap:break-word; width:100%; } } | |||||
| span.keyword { color:#0000FF } | |||||
| span.comment { color:#228B22 } | |||||
| span.string { color:#A020F0 } | |||||
| span.untermstring { color:#B20000 } | |||||
| span.syscmd { color:#B28C00 } | |||||
| .footer { width:auto; padding:10px 0px; margin:25px 0px 0px; border-top:1px dotted #878787; font-size:0.8em; line-height:140%; font-style:italic; color:#878787; text-align:left; float:none; } | |||||
| .footer p { margin:0px; } | |||||
| .footer a { color:#878787; } | |||||
| .footer a:hover { color:#878787; text-decoration:underline; } | |||||
| .footer a:visited { color:#878787; } | |||||
| table th { padding:7px 5px; text-align:left; vertical-align:middle; border: 1px solid #d6d4d4; font-weight:bold; } | |||||
| table td { padding:7px 5px; text-align:left; vertical-align:top; border:1px solid #d6d4d4; } | |||||
| </style></head><body><div class="content"><pre class="codeinput"><span class="keyword">classdef</span> Channel | |||||
| <span class="comment">% CHANNEL is the class for one channel of the oscilloscope. Multiple</span> | |||||
| <span class="comment">% settings for the different channels of the oscilloscope can be changed</span> | |||||
| <span class="comment">% via this class definition</span> | |||||
| <span class="keyword">properties</span> (Hidden, Access = private) | |||||
| scope <span class="comment">% Contains the class of the scope that is parent of this channel.</span> | |||||
| channelnumber <span class="comment">% is the number of the channel on the scope.</span> | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">properties</span> (Dependent) | |||||
| state | |||||
| coupling | |||||
| bandwidth | |||||
| scale | |||||
| offset | |||||
| probe | |||||
| label | |||||
| type | |||||
| probeunit | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">methods</span> | |||||
| <span class="keyword">function</span> ch = Channel(scope,channelnumber) | |||||
| ch.channelnumber = channelnumber; | |||||
| ch.scope = scope; | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> s = get.state(ch) | |||||
| s = ch.CHAN(<span class="string">'state?'</span>); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.coupling(ch) | |||||
| out = ch.CHAN(<span class="string">'coup?'</span>); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.bandwidth(ch) | |||||
| out = ch.CHAN(<span class="string">'band?'</span>); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.offset(ch) | |||||
| out = ch.CHAN(<span class="string">'offs?'</span>); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.scale(ch) | |||||
| out = ch.CHAN(<span class="string">'scal?'</span>); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.label(ch) | |||||
| out = ch.CHAN(<span class="string">'lab?'</span>); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.type(ch) | |||||
| out = ch.CHAN(<span class="string">'type?'</span>); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.probeunit(ch) | |||||
| out = ch.scope.query([<span class="string">'PROB'</span>,num2str(ch.channelnumber),<span class="string">':SET:ATT:UNIT?'</span>]); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = get.probe(ch) | |||||
| out = ch.scope.query([<span class="string">'PROB'</span>,num2str(ch.channelnumber),<span class="string">':SET:ATT:MAN?'</span>]); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.state(ch,in) | |||||
| ch.CHAN(<span class="string">'state'</span>,in); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.coupling(ch,in) | |||||
| ch.CHAN(<span class="string">'coup'</span>,in); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.bandwidth(ch,in) | |||||
| ch.CHAN(<span class="string">'band'</span>,in); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.offset(ch,in) | |||||
| ch.CHAN(<span class="string">'offs'</span>,in); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.scale(ch,in) | |||||
| ch.CHAN(<span class="string">'scal'</span>,in); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.label(ch,in) | |||||
| ch.CHAN(<span class="string">'lab'</span>,in); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.type(ch,in) | |||||
| ch.CHAN(<span class="string">'type'</span>,in); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = frequency(ch) | |||||
| out = str2double(ch.MEAS(<span class="string">'freq'</span>)); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = peak2peak(ch) | |||||
| out = str2double(ch.MEAS(<span class="string">'peak'</span>)); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = period(ch) | |||||
| out = str2double(ch.MEAS(<span class="string">'per'</span>)); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = amplitude(ch) | |||||
| out = str2double(ch.MEAS(<span class="string">'ampl'</span>)); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = mean(ch) | |||||
| out = str2double(ch.MEAS(<span class="string">'mean'</span>)); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = rms(ch) | |||||
| out = str2double(ch.MEAS(<span class="string">'rms'</span>)); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> out = phase(ch) | |||||
| out = str2double(ch.MEAS(<span class="string">'phas'</span>)); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.probeunit(ch,unit) | |||||
| ch.scope.write([<span class="string">'PROB'</span>,num2str(ch.channelnumber),<span class="string">':SET:ATT:UNIT '</span>, unit]); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> ch = set.probe(ch,man) | |||||
| ch.scope.write([<span class="string">'PROB'</span>,num2str(ch.channelnumber),<span class="string">':SET:ATT:MAN '</span>, man]); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> data = waveform(ch,window) | |||||
| ch.scope.single; | |||||
| <span class="keyword">if</span> nargin < 2 | |||||
| window = <span class="string">'DEF'</span>; | |||||
| <span class="keyword">end</span> | |||||
| ch.scope.setWaveformSettings(window,<span class="string">'REAL'</span>) | |||||
| data = ch.getWaveform; | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> data = getWaveform(ch) | |||||
| header = str2num(ch.CHAN(<span class="string">'DATA:HEAD?'</span>)); | |||||
| data.length = header(3); | |||||
| data.start = header(1); | |||||
| data.stop = header(2); | |||||
| data.sampletime = str2double(ch.CHAN(<span class="string">'DATA:XINC?'</span>)); | |||||
| ch.scope.opc; | |||||
| ch.scope.write_unsafe([<span class="string">'CHAN'</span>,num2str(ch.channelnumber),<span class="string">':DATA?'</span>]); | |||||
| data.data = ch.scope.readWaveform(data.length); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">methods</span> (Hidden, Access = private) | |||||
| <span class="keyword">function</span> c = CHAN(ch,string,in) | |||||
| <span class="keyword">if</span> nargin == 2 | |||||
| <span class="keyword">if</span> strcmp(string(end),<span class="string">'?'</span>) | |||||
| c = ch.scope.query([<span class="string">'CHAN'</span>,num2str(ch.channelnumber),<span class="string">':'</span>,string]); | |||||
| <span class="keyword">else</span> | |||||
| ch.scope.write([<span class="string">'CHAN'</span>,num2str(ch.channelnumber),<span class="string">':'</span>,string]); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">else</span> | |||||
| ch.scope.write([<span class="string">'CHAN'</span>,num2str(ch.channelnumber),<span class="string">':'</span>,string,<span class="string">' '</span>,in]); | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">function</span> c = MEAS(ch,string) | |||||
| c = ch.scope.query([<span class="string">'MEAS'</span>,num2str(ch.channelnumber),<span class="string">':RES:ACT?'</span>,string]); | |||||
| <span class="keyword">end</span> | |||||
| <span class="comment">% function c = CHANsend(ch,string,in)</span> | |||||
| <span class="comment">% c = ['CHAN',num2str(ch.channelnumber),':',string,' ',in];</span> | |||||
| <span class="comment">% end</span> | |||||
| <span class="keyword">end</span> | |||||
| <span class="keyword">end</span> | |||||
| </pre><pre class="codeoutput error">Not enough input arguments. | |||||
| Error in Channel (line 24) | |||||
| ch.channelnumber = channelnumber; | |||||
| </pre><p class="footer"><br><a href="https://www.mathworks.com/products/matlab/">Published with MATLAB® R2018a</a><br></p></div><!-- | |||||
| ##### SOURCE BEGIN ##### | |||||
| classdef Channel | |||||
| % CHANNEL 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 | |||||
| properties (Hidden, Access = private) | |||||
| scope % Contains the class of the scope that is parent of this channel. | |||||
| channelnumber % is the number of the channel on the scope. | |||||
| end | |||||
| properties (Dependent) | |||||
| state | |||||
| coupling | |||||
| bandwidth | |||||
| scale | |||||
| offset | |||||
| probe | |||||
| label | |||||
| type | |||||
| probeunit | |||||
| end | |||||
| methods | |||||
| function ch = Channel(scope,channelnumber) | |||||
| ch.channelnumber = channelnumber; | |||||
| ch.scope = scope; | |||||
| end | |||||
| function s = get.state(ch) | |||||
| s = ch.CHAN('state?'); | |||||
| end | |||||
| function out = get.coupling(ch) | |||||
| out = ch.CHAN('coup?'); | |||||
| end | |||||
| function out = get.bandwidth(ch) | |||||
| out = ch.CHAN('band?'); | |||||
| end | |||||
| function out = get.offset(ch) | |||||
| out = ch.CHAN('offs?'); | |||||
| end | |||||
| function out = get.scale(ch) | |||||
| out = ch.CHAN('scal?'); | |||||
| end | |||||
| function out = get.label(ch) | |||||
| out = ch.CHAN('lab?'); | |||||
| end | |||||
| function out = get.type(ch) | |||||
| out = ch.CHAN('type?'); | |||||
| end | |||||
| function out = get.probeunit(ch) | |||||
| out = ch.scope.query(['PROB',num2str(ch.channelnumber),':SET:ATT:UNIT?']); | |||||
| end | |||||
| function out = get.probe(ch) | |||||
| out = ch.scope.query(['PROB',num2str(ch.channelnumber),':SET:ATT:MAN?']); | |||||
| end | |||||
| function ch = set.state(ch,in) | |||||
| ch.CHAN('state',in); | |||||
| end | |||||
| function ch = set.coupling(ch,in) | |||||
| ch.CHAN('coup',in); | |||||
| end | |||||
| function ch = set.bandwidth(ch,in) | |||||
| ch.CHAN('band',in); | |||||
| end | |||||
| function ch = set.offset(ch,in) | |||||
| ch.CHAN('offs',in); | |||||
| end | |||||
| function ch = set.scale(ch,in) | |||||
| ch.CHAN('scal',in); | |||||
| end | |||||
| function ch = set.label(ch,in) | |||||
| ch.CHAN('lab',in); | |||||
| end | |||||
| function ch = set.type(ch,in) | |||||
| ch.CHAN('type',in); | |||||
| end | |||||
| function out = frequency(ch) | |||||
| out = str2double(ch.MEAS('freq')); | |||||
| end | |||||
| function out = peak2peak(ch) | |||||
| out = str2double(ch.MEAS('peak')); | |||||
| end | |||||
| function out = period(ch) | |||||
| out = str2double(ch.MEAS('per')); | |||||
| end | |||||
| function out = amplitude(ch) | |||||
| out = str2double(ch.MEAS('ampl')); | |||||
| end | |||||
| function out = mean(ch) | |||||
| out = str2double(ch.MEAS('mean')); | |||||
| end | |||||
| function out = rms(ch) | |||||
| out = str2double(ch.MEAS('rms')); | |||||
| end | |||||
| function out = phase(ch) | |||||
| out = str2double(ch.MEAS('phas')); | |||||
| end | |||||
| function ch = set.probeunit(ch,unit) | |||||
| ch.scope.write(['PROB',num2str(ch.channelnumber),':SET:ATT:UNIT ', unit]); | |||||
| end | |||||
| function ch = set.probe(ch,man) | |||||
| ch.scope.write(['PROB',num2str(ch.channelnumber),':SET:ATT:MAN ', man]); | |||||
| end | |||||
| function data = waveform(ch,window) | |||||
| ch.scope.single; | |||||
| if nargin < 2 | |||||
| window = 'DEF'; | |||||
| end | |||||
| ch.scope.setWaveformSettings(window,'REAL') | |||||
| data = ch.getWaveform; | |||||
| end | |||||
| function data = getWaveform(ch) | |||||
| header = str2num(ch.CHAN('DATA:HEAD?')); | |||||
| data.length = header(3); | |||||
| data.start = header(1); | |||||
| data.stop = header(2); | |||||
| data.sampletime = str2double(ch.CHAN('DATA:XINC?')); | |||||
| ch.scope.opc; | |||||
| ch.scope.write_unsafe(['CHAN',num2str(ch.channelnumber),':DATA?']); | |||||
| data.data = ch.scope.readWaveform(data.length); | |||||
| end | |||||
| end | |||||
| methods (Hidden, Access = private) | |||||
| function c = CHAN(ch,string,in) | |||||
| if nargin == 2 | |||||
| if strcmp(string(end),'?') | |||||
| c = ch.scope.query(['CHAN',num2str(ch.channelnumber),':',string]); | |||||
| else | |||||
| ch.scope.write(['CHAN',num2str(ch.channelnumber),':',string]); | |||||
| end | |||||
| else | |||||
| ch.scope.write(['CHAN',num2str(ch.channelnumber),':',string,' ',in]); | |||||
| end | |||||
| end | |||||
| function c = MEAS(ch,string) | |||||
| c = ch.scope.query(['MEAS',num2str(ch.channelnumber),':RES:ACT?',string]); | |||||
| end | |||||
| % function c = CHANsend(ch,string,in) | |||||
| % c = ['CHAN',num2str(ch.channelnumber),':',string,' ',in]; | |||||
| % end | |||||
| end | |||||
| end | |||||
| ##### SOURCE END ##### | |||||
| --></body></html> | |||||