| @@ -108,23 +108,22 @@ classdef Channel | |||
| end | |||
| function data = waveform(ch) | |||
| ch.scope.clear; | |||
| ch.CHAN('TYPE HRES'); | |||
| ch.scope.write('FORM REAL'); | |||
| ch.scope.write('FORM:BORD MSBF'); | |||
| ch.CHAN('DATA:POIN DMAX'); | |||
| ch.scope.single; | |||
| ch.scope.setWaveformSettings; | |||
| 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 = ch.CHAN('DATA:XINC?'); | |||
| data.sampletime = str2double(ch.CHAN('DATA:XINC?')); | |||
| ch.scope.opc; | |||
| ch.scope.write_unsafe(['CHAN',num2str(ch.channelnumber),':DATA?']); | |||
| prefixstring = fscanf(ch.scope.tcp,'%c',2); | |||
| prefixlength = str2double(prefixstring(2)); | |||
| datalength = fscanf(ch.scope.tcp,'%c',prefixlength); | |||
| data.wave = fread(ch.scope.tcp,data.length,'float'); | |||
| data.data = fread(ch.scope.tcp,data.length,'float')'; | |||
| flushinput(ch.scope.tcp); | |||
| end | |||
| @@ -35,7 +35,9 @@ classdef Equipment < handle | |||
| function clear(ecq) | |||
| %CLEAR Sends clear command to device via '*CLS'. | |||
| %This function also clears the TCP inputbuffer; | |||
| ecq.write_unsafe('*cls'); | |||
| flushinput(ecq.tcp); | |||
| end | |||
| function reset(ecq) | |||
| @@ -47,7 +49,14 @@ classdef Equipment < handle | |||
| %OPC executes 'operation complete query' to device. | |||
| %Function holds untill device returns '1'. Must be | |||
| %used to avoid interrupting busy device. | |||
| ecq.query_unsafe('*OPC?'); | |||
| ecq.write_unsafe('*OPC?'); | |||
| for i = 1:10 | |||
| ack = ecq.read; | |||
| if strcmp(ack(1),'1') | |||
| return | |||
| end | |||
| end | |||
| error('Device is not ready'); | |||
| end | |||
| function unlock(ecq) | |||
| @@ -117,10 +126,10 @@ classdef Equipment < handle | |||
| %the function will throw a warning with all the error messages. | |||
| for i = 1:20 | |||
| output = ecq.query_unsafe('SYSTem:ERRor?'); %Query error message from device. | |||
| [msgstr, msgid] = lastwarn; | |||
| if strcmp(msgid,'instrument:fscanf:unsuccessfulRead') | |||
| error(['Lost connection with ' ecq.name]); | |||
| end | |||
| % [msgstr, msgid] = lastwarn; | |||
| % if strcmp(msgid,'instrument:fscanf:unsuccessfulRead') | |||
| % error(['Lost connection with ' ecq.name]); | |||
| % end | |||
| errorlist(i,1:(length(output))) = output; %Store the error message in the errorlist array. | |||
| %GPIB protocol states that the error code '0' means no | |||
| %error. The for loop will break if the last recieved error | |||
| @@ -20,6 +20,7 @@ classdef Oscilloscope < Equipment | |||
| % 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 | |||
| @@ -71,6 +72,27 @@ classdef Oscilloscope < Equipment | |||
| m = str2double(sc.query(['MEAS',num2str(measurement),':RES:ACT?'])); | |||
| end | |||
| function setWaveformSettings(sc) | |||
| sc.clear; | |||
| sc.write('CHAN:TYPE HRES'); | |||
| sc.write('FORM REAL'); | |||
| sc.write('FORM:BORD MSBF'); | |||
| sc.write('CHAN:DATA:POIN DEF'); | |||
| sc.single; | |||
| end | |||
| function data = waveform(sc,channels) | |||
| if nargin < 2 | |||
| channels = 1:sc.nchannels; | |||
| end | |||
| sc.setWaveformSettings | |||
| for i = channels | |||
| wave = sc.(['ch',num2str(i)]).getWaveform; | |||
| data.(['ch',num2str(i)]) = wave.data; | |||
| end | |||
| data.sampletime = wave.sampletime; | |||
| data.length = wave.length; | |||
| end | |||
| % function data = waveform(ch,cha) | |||
| @@ -5,15 +5,8 @@ wave = [wave1;wave2]; | |||
| Fs = 1/T; | |||
| n = 2^nextpow2(length); | |||
| X = fft(wave,n,2)/n; | |||
| idx = round(frequency*n/Fs) | |||
| phase = mod(angle(X(1,idx))-angle(X(2,idx))+pi,2*pi)-pi; | |||
| magnitude = X; | |||
| for i=1:2 | |||
| subplot(2,1,i) | |||
| plot(0:(Fs/n):(Fs/2-Fs/n),abs(X(i,1:n/2))) | |||
| title(['Row ',num2str(i), ' in the Frequency Domain']) | |||
| end | |||
| idx = round(frequency*n/Fs); | |||
| phase = mod(angle(mean(X(1,(-1:1)+idx)))-angle(mean(X(2,(-1:1)+idx)))+pi,2*pi)-pi; | |||
| magnitude = 10*log10(abs(X(2,idx))/abs(X(1,idx))); | |||
| end | |||
| @@ -1,24 +1,20 @@ | |||
| function data = transferFunction(oscilloscope,functiongenerator,f_start,f_stop,n_steps,amplitude) | |||
| function [data,raw] = transferFunction(oscilloscope,functiongenerator,f_start,f_stop,n_steps,amplitude) | |||
| %TRANSFERFUNCTION Summary of this function goes here | |||
| % Detailed explanation goes here | |||
| f_array = linspace(f_start,f_stop,n_steps); | |||
| f_array = 10.^linspace(log10(f_start),log10(f_stop),n_steps); | |||
| functiongenerator.voltage = amplitude; | |||
| functiongenerator.waveform = 'SINUSOID'; | |||
| oscilloscope.enable_channels; | |||
| oscilloscope.trigger.source = 'CH1'; | |||
| oscilloscope.ch1.type = 'HRES'; | |||
| oscilloscope.ch2.type = 'HRES'; | |||
| oscilloscope.setMeasurement(1,'phase'); | |||
| oscilloscope.setMeasurement(2,'peak'); | |||
| oscilloscope.setMeasurement(3,'peak','ch2'); | |||
| emptydata = zeros(n_steps,1); | |||
| data = struct('magnitude',emptydata,'phase',emptydata,'frequency',f_array); | |||
| for i = 1:n_steps | |||
| functiongenerator.frequency = f_array(i); | |||
| oscilloscope.auto; | |||
| data.phase(i) = oscilloscope.getMeasurement(1); | |||
| data.magnitude(i) = oscilloscope.getMeasurement(2)/oscilloscope.getMeasurement(3); | |||
| wavedata = oscilloscope.waveform; | |||
| raw(i) = wavedata; | |||
| [data.phase(i),data.magnitude(i)] = phamag(wavedata.ch1,wavedata.ch2,wavedata.length,f_array(i),wavedata.sampletime); | |||
| end | |||
| end | |||