merge?
This commit is contained in:
@@ -27,7 +27,7 @@ classdef Signal
|
||||
|
||||
[~,obj.gitSHA] = system('git rev-parse HEAD');
|
||||
[~,obj.gitStatus] = system('git status --porcelain');
|
||||
[~,obj.gitPatch] = system('git diff');
|
||||
% [~,obj.gitPatch] = system('git diff');
|
||||
|
||||
%%% Stuff for Logbook %%%
|
||||
SignalType = [];
|
||||
@@ -379,7 +379,7 @@ classdef Signal
|
||||
%xlim([-obj.fs/2 obj.fs/2].*1e-9)
|
||||
edgetick = 2^(nextpow2(obj.fs*1e-9));
|
||||
xticks([-edgetick:16:edgetick]);
|
||||
xlim([100*round( min(w.*1e-9)/100,1)-10,100*round( max(w.*1e-9)/100,1)+10])
|
||||
xlim([100*round( min(w)/100,1)-10,100*round( max(w)/100,1)+10])
|
||||
else
|
||||
xlabel("Normalized Frequency");
|
||||
xlim([-pi, pi]);
|
||||
@@ -510,7 +510,7 @@ classdef Signal
|
||||
end
|
||||
|
||||
%%
|
||||
function [obj,S] = tsynch(obj,options)
|
||||
function [obj,S,isFlipped] = tsynch(obj,options)
|
||||
% time sync and cut
|
||||
arguments
|
||||
obj Signal
|
||||
@@ -525,14 +525,16 @@ classdef Signal
|
||||
q = obj.fs/options.fs_ref;
|
||||
b = options.reference.resample("fs_in",options.fs_ref,"fs_out",obj.fs).normalize("mode","oneone").signal;
|
||||
|
||||
max_occurences = floor(length(a)/length(b));
|
||||
|
||||
%estimate delay between signals
|
||||
[co,lags] = xcorr(a,b);
|
||||
[~,pos] = max(co);
|
||||
[~,pos] = max(abs(co));
|
||||
D = lags(pos);
|
||||
|
||||
%estimate start pos of signal
|
||||
maxpeaknum = floor(length(a)/length(b));
|
||||
[pks,pkpos] = findpeaks(co./max(co),'MinPeakDistance',length(b)/2,'MinPeakHeight',0.2,'NPeaks',maxpeaknum);
|
||||
[pks,pkpos] = findpeaks(abs(co./max(co)),'MinPeakDistance',length(b)/2,'MinPeakHeight',0.2,'NPeaks',maxpeaknum);
|
||||
shifts = lags(pkpos);
|
||||
|
||||
%Cut occurences of ref signal from signal (only positive shifts)
|
||||
@@ -543,9 +545,19 @@ classdef Signal
|
||||
S{end+1,1} = sig;
|
||||
end
|
||||
|
||||
%
|
||||
isFlipped=0;
|
||||
if all(sign(co(pkpos)))
|
||||
isFlipped = 1;
|
||||
end
|
||||
|
||||
%return/keep the sinal with the highest correlation (only within positive shifts)
|
||||
[~,idx]=max(pks(shifts>0));
|
||||
obj.signal = S{idx}.signal;
|
||||
%put signal with highest corr. to first index in S array
|
||||
swap = S{1};
|
||||
S{1} = S{idx};
|
||||
S{idx} = swap;
|
||||
|
||||
for c = 1:numel(shifts(shifts>0))
|
||||
S{c}.logbook = [];
|
||||
|
||||
@@ -202,19 +202,19 @@ classdef ChannelFreqResp < handle
|
||||
function plot(obj)
|
||||
|
||||
figure(55);
|
||||
clf;
|
||||
%clf;
|
||||
|
||||
Havg = obj.H;
|
||||
|
||||
%1)
|
||||
subplot(2,1,1);hold all;box on;title('Magnitude Freq. Response');
|
||||
subplot(2,1,1);hold on;box on;title('Magnitude Freq. Response');
|
||||
plot(obj.faxis/1e9, 20*log10(abs(obj.H_all)),'linewidth',0.1,'LineStyle','-','Color','#808080') ;
|
||||
xlim([0.2 .5*max(obj.faxis)*1e-9]);
|
||||
plot(obj.faxis/1e9, 20*log10(abs(Havg)),'LineWidth',2);
|
||||
grid on;
|
||||
|
||||
%2)
|
||||
subplot(2,1,2); hold all; box on; title('Phase Freq. Response');
|
||||
subplot(2,1,2); hold on; box on; title('Phase Freq. Response');
|
||||
plot(obj.faxis/1e9, angle(obj.H_all),'linewidth',0.1,'LineStyle','-','Color','#808080') ;
|
||||
plot(obj.faxis/1e9, unwrap(angle(Havg)),'LineWidth',2) ;
|
||||
xlim([0.2 .5*max(obj.faxis)*1e-9]);
|
||||
@@ -228,7 +228,7 @@ classdef ChannelFreqResp < handle
|
||||
Havg = Havg./mean(Havg(2:10));
|
||||
|
||||
%3)
|
||||
subplot(2,1,1); hold all; box on; title('Inverse Magnitude Freq. Response');
|
||||
subplot(2,1,1); hold on; box on; title('Inverse Magnitude Freq. Response');
|
||||
plot(obj.faxis/1e9, 20*log10(abs(1./Havg)),"LineWidth",2,"Color",[0.3467 0.5360 0.6907]) ;
|
||||
xlim([0.2 .5*max(obj.faxis)*1e-9]); grid on;
|
||||
ylim([-1 15]);
|
||||
@@ -236,15 +236,17 @@ classdef ChannelFreqResp < handle
|
||||
yline(3,'LineWidth',2,'LineStyle','--');
|
||||
|
||||
%4)
|
||||
subplot(2,1,2); hold all; box on; title('Inverse Phase Freq. Response');
|
||||
subplot(2,1,2); hold on; box on; title('Inverse Phase Freq. Response');
|
||||
plot(obj.faxis/1e9, unwrap(angle(1./Havg)),"LineWidth",2,"Color",[0.3467 0.5360 0.6907]) ;
|
||||
xlim([0.2 .5*max(obj.faxis)*1e-9]); grid on;
|
||||
|
||||
%%% plot for publication
|
||||
figure(98989);hold all;box on;title('Magnitude Freq. Response');
|
||||
xlim([0.2 .5*max(obj.faxis)*1e-9]);
|
||||
ylim([-20, 2]);
|
||||
plot(obj.faxis/1e9, 20*log10(abs(Havg)),'LineWidth',2);
|
||||
figure(30);hold on;box on;title('Magnitude Freq. Response');
|
||||
% xlim([0 max(obj.faxis)*1e-9]);
|
||||
% ylim([-20, 10]);
|
||||
fax = obj.faxis - obj.f_ref/2;
|
||||
Havg = Havg ./ max(abs(Havg));
|
||||
plot(fax/1e9, 20*log10(abs(fftshift(Havg)))+7,'LineWidth',2);
|
||||
grid on;
|
||||
|
||||
|
||||
@@ -360,7 +362,7 @@ classdef ChannelFreqResp < handle
|
||||
|
||||
end
|
||||
|
||||
fprintf('Frequency response information successfully loaded from %s\n', fullFileName);
|
||||
% fprintf('Frequency response information successfully loaded from %s\n', fullFileName);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -77,9 +77,42 @@ classdef PAMsource
|
||||
bitpattern=[];
|
||||
|
||||
if obj.useprbs
|
||||
for i = 1:log2(obj.M)
|
||||
[bitpattern(:,i),seed] = prbs(O,N,seed);
|
||||
% for i = 1:log2(obj.M)
|
||||
% [bitpattern(:,i),seed] = prbs(O,N,seed);
|
||||
% end
|
||||
|
||||
%%%%% MOVE-IT PRMS %%%%
|
||||
|
||||
state = struct();
|
||||
|
||||
para = struct();
|
||||
|
||||
if obj.M == 6
|
||||
para.bl = 2^(obj.order-2);
|
||||
para.dimension = 5;
|
||||
else
|
||||
para.bl = 2^(obj.order-1);
|
||||
para.dimension = log2(obj.M); %2.5bits/sym -> 2 bit/sym
|
||||
end
|
||||
|
||||
para.rand = 0;
|
||||
|
||||
para.order = floor(obj.order / log2(obj.M));
|
||||
para.skip =0;
|
||||
para.bruijn = 0;
|
||||
para.reset_prms = 0;
|
||||
para.method = 1;
|
||||
|
||||
data_in = [];
|
||||
global loop;
|
||||
loop = 0;
|
||||
[data_out,state_] = prms(data_in, state, para);
|
||||
loop = 1;
|
||||
[data_out,state_out] = prms(data_in, state_, para);
|
||||
bitpattern = data_out';
|
||||
|
||||
%%%%% END MOVE-IT %%%%%%%
|
||||
|
||||
else
|
||||
s = RandStream('twister','Seed',obj.randkey);
|
||||
for i = 1:log2(obj.M)
|
||||
@@ -88,7 +121,7 @@ classdef PAMsource
|
||||
end
|
||||
|
||||
if obj.M == 6
|
||||
bitpattern = reshape(bitpattern,[],1);
|
||||
bitpattern = reshape(bitpattern',[],1);
|
||||
bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
|
||||
end
|
||||
|
||||
@@ -108,7 +141,7 @@ classdef PAMsource
|
||||
end
|
||||
|
||||
% figure(12);hold on;histogram(symbols.signal,'Normalization','probability');
|
||||
|
||||
|
||||
if obj.mrds_code
|
||||
symbols = MRDS_coding("blocklength",obj.mrds_blocklength).encode(symbols);
|
||||
end
|
||||
@@ -128,7 +161,7 @@ classdef PAMsource
|
||||
%%%%% Re-sample to f DAC %%%%%%
|
||||
digi_sig = digi_sig.resample("fs_in",digi_sig.fs,"fs_out",obj.fs_out,"n",10,"beta",5);
|
||||
|
||||
% digi_sig.spectrum("fignum",111,"displayname","after pulseforming");
|
||||
% digi_sig.spectrum("fignum",111,"displayname","after pulseforming");
|
||||
|
||||
%%%%% Hard clip digital signal to PAM range before DAC %%%%%%
|
||||
if obj.applyclipping
|
||||
|
||||
@@ -164,11 +164,11 @@ classdef Duobinary
|
||||
elseif I == 11
|
||||
%todo
|
||||
data = data .* sqrt(5.8);
|
||||
warning('Check if PAM16 implementation, mapping and scaling is correct!')
|
||||
warning('Check db decode implementation, mapping and scaling is correct!')
|
||||
elseif I == 15
|
||||
data = data .* sqrt(10.5);
|
||||
elseif I == 16
|
||||
warning('Check if PAM16 implementation, mapping and scaling is correct!')
|
||||
warning('Check db decode implementation, mapping and scaling is correct!')
|
||||
end
|
||||
|
||||
data = round(data);
|
||||
|
||||
@@ -7,11 +7,12 @@ classdef Awg2Scope
|
||||
Scope
|
||||
|
||||
mapping;
|
||||
waitUntilClick
|
||||
|
||||
end
|
||||
|
||||
methods (Access=public)
|
||||
function obj = Awg2Scope(Awg,Scope,mapping)
|
||||
function obj = Awg2Scope(Awg,Scope,mapping,options)
|
||||
%Simple class to call the Awg and Scope and map the signals
|
||||
%accordingly in the correct formats with correct l
|
||||
% ogbook
|
||||
@@ -21,16 +22,19 @@ classdef Awg2Scope
|
||||
Awg
|
||||
Scope
|
||||
mapping
|
||||
|
||||
options.waitUntilClick = 0;
|
||||
end
|
||||
|
||||
obj.Awg = Awg;
|
||||
obj.Scope = Scope;
|
||||
|
||||
obj.mapping = mapping; % AWG CH [1,2,3,4] -> Scope CH [0,0,0,1]
|
||||
obj.waitUntilClick = options.waitUntilClick;
|
||||
|
||||
end
|
||||
|
||||
function [S1,S2,S3,S4] = process(obj,channels)
|
||||
function [S1,S2,S3,S4] = process(obj,channels, options)
|
||||
|
||||
arguments
|
||||
obj
|
||||
@@ -41,15 +45,33 @@ classdef Awg2Scope
|
||||
channels.signal4 Informationsignal = Informationsignal([])
|
||||
|
||||
% add new optional arguments here
|
||||
options.waitUntilClick = obj.waitUntilClick;
|
||||
end
|
||||
|
||||
|
||||
|
||||
%%% UPLOAD TO AWG %%%
|
||||
|
||||
[S1,S2,S3,S4]=obj.Awg.upload("signal1",channels.signal1,...
|
||||
"signal2",channels.signal2,...
|
||||
"signal3",channels.signal3,...
|
||||
"signal4",channels.signal4...
|
||||
);
|
||||
|
||||
%%% UPLOAD TO AWG %%%
|
||||
|
||||
scpe_sig_cell = obj.Scope.read();
|
||||
|
||||
|
||||
%%% READ FROM SCOPE %%%
|
||||
|
||||
scpe_sig_cell = obj.Scope.read("waitUntilClick",options.waitUntilClick);
|
||||
|
||||
%%% READ FROM SCOPE %%%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
% Map Scope measurement to output signal
|
||||
% mapping index is the AWG chanel and mapping number is the
|
||||
|
||||
@@ -176,7 +176,11 @@ classdef AwgKeysight
|
||||
% The waveform granularity is e.g. 128. This means that the waveform length must be a multiple of this granularity. The minimum waveform length is 128 samples.
|
||||
if rem(length(signal{s}),obj.waveformGranularity) ~= 0
|
||||
signal{s} = [signal{s} signal{s}(:,1:(obj.waveformGranularity-rem(length(signal{s}),obj.waveformGranularity)))];
|
||||
warning(['data should have a length multiple of ',num2str(obj.waveformGranularity),'!']);
|
||||
|
||||
debug = 0;
|
||||
if debug
|
||||
warning(['data should have a length multiple of ',num2str(obj.waveformGranularity),'!']);
|
||||
end
|
||||
end
|
||||
|
||||
% Digitally apply skews to the signals
|
||||
|
||||
@@ -51,90 +51,90 @@ classdef DC_supply < handle
|
||||
|
||||
success = [0,0];
|
||||
|
||||
try
|
||||
% %connect to device
|
||||
% if exist('v','var')
|
||||
% %v = visadev("GPIB1::19::INSTR");
|
||||
% v = obj.connectDevice();
|
||||
% else
|
||||
%
|
||||
% end
|
||||
% %connect to device
|
||||
% if exist('v','var')
|
||||
% %v = visadev("GPIB1::19::INSTR");
|
||||
% v = obj.connectDevice();
|
||||
% else
|
||||
%
|
||||
% end
|
||||
|
||||
v = visadev("GPIB1::19::INSTR");
|
||||
v = visadev("GPIB1::19::INSTR");
|
||||
|
||||
debug = 0;
|
||||
if debug
|
||||
disp(['Connected to Instrument: ',char(v.Vendor),' ',char(v.Model),' SerNo:',char(v.SerialNumber)]);
|
||||
end
|
||||
debug = 0;
|
||||
if debug
|
||||
disp(['Connected to Instrument: ',char(v.Vendor),' ',char(v.Model),' SerNo:',char(v.SerialNumber)]);
|
||||
end
|
||||
|
||||
cmd = 'INST:SEL?';
|
||||
cmd = 'INST:SEL?';
|
||||
writeline(v, cmd);
|
||||
prev_selected_channel = readline(v);
|
||||
|
||||
for ch = 1:2
|
||||
|
||||
% choose channel
|
||||
cmd = ['INST:SEL OUT',num2str(ch)];
|
||||
writeline(v, cmd);
|
||||
prev_selected_channel = readline(v);
|
||||
|
||||
for ch = 1:2
|
||||
% get current voltage level
|
||||
cmd = 'VOLT?';
|
||||
writeline(v, cmd);
|
||||
act_volt = str2num(readline(v));
|
||||
|
||||
% choose channel
|
||||
cmd = ['INST:SEL OUT',num2str(ch)];
|
||||
writeline(v, cmd);
|
||||
% desired voltage (round to two digits after comma)
|
||||
des_volt = round(options.voltage(ch),2);
|
||||
|
||||
cnt = 0;
|
||||
while abs(act_volt-des_volt) > 0
|
||||
|
||||
selected_channel = ['OUT',num2str(ch)];
|
||||
|
||||
% get current voltage level
|
||||
cmd = 'VOLT?';
|
||||
writeline(v, cmd);
|
||||
act_volt = str2num(readline(v));
|
||||
|
||||
% desired voltage (round to two digits after comma)
|
||||
des_volt = round(options.voltage(ch),2);
|
||||
% difference
|
||||
diff_volt = act_volt-des_volt;
|
||||
|
||||
cnt = 0;
|
||||
while abs(act_volt-des_volt) > 0
|
||||
|
||||
selected_channel = ['OUT',num2str(ch)];
|
||||
|
||||
% get current voltage level
|
||||
cmd = 'VOLT?';
|
||||
writeline(v, cmd);
|
||||
act_volt = str2num(readline(v));
|
||||
|
||||
% difference
|
||||
diff_volt = act_volt-des_volt;
|
||||
|
||||
% set new voltage
|
||||
increment_voltage = -0.01* sign(diff_volt) ;
|
||||
cmd = ['VOLT ',num2str(act_volt+increment_voltage)];
|
||||
writeline(v, cmd);
|
||||
|
||||
cnt = cnt+1;
|
||||
if mod(cnt,100) == 0
|
||||
wait(1);
|
||||
end
|
||||
|
||||
% get current voltage level
|
||||
cmd = 'VOLT?';
|
||||
writeline(v, cmd);
|
||||
act_volt = str2num(readline(v));
|
||||
% set new voltage
|
||||
increment_voltage = -0.01* sign(diff_volt) ;
|
||||
cmd = ['VOLT ',num2str(act_volt+increment_voltage)];
|
||||
writeline(v, cmd);
|
||||
|
||||
cnt = cnt+1;
|
||||
if mod(cnt,100) == 0
|
||||
pause(1);
|
||||
end
|
||||
|
||||
% check if voltage is set
|
||||
if act_volt ~= des_volt
|
||||
hMsgBox = msgbox('An error occurred in dc supply module. Check if voltage is set correctly.');
|
||||
uiwait(hMsgBox);
|
||||
else
|
||||
success(ch) = 1;
|
||||
end
|
||||
% get current voltage level
|
||||
cmd = 'VOLT?';
|
||||
writeline(v, cmd);
|
||||
act_volt = str2num(readline(v));
|
||||
|
||||
end
|
||||
|
||||
% choose channel
|
||||
cmd = ['INST:SEL ',char(strtrim(prev_selected_channel))];
|
||||
writeline(v, cmd);
|
||||
% check if voltage is set
|
||||
if act_volt ~= des_volt
|
||||
hMsgBox = msgbox('An error occurred in dc supply module. Check if voltage is set correctly.');
|
||||
uiwait(hMsgBox);
|
||||
else
|
||||
success(ch) = 1;
|
||||
end
|
||||
|
||||
%disconnect
|
||||
delete(v);
|
||||
|
||||
catch
|
||||
|
||||
end
|
||||
|
||||
% choose channel
|
||||
cmd = ['INST:SEL ',char(strtrim(prev_selected_channel))];
|
||||
writeline(v, cmd);
|
||||
|
||||
%disconnect
|
||||
delete(v);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
function [voltage,current] = readVals(obj)
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
classdef Exfo_laser
|
||||
classdef Exfo_laser < handle
|
||||
|
||||
properties(Access=private)
|
||||
serialport_number
|
||||
mainframe_channel
|
||||
end
|
||||
properties(Access=public)
|
||||
wavelength
|
||||
power
|
||||
cur_state
|
||||
cur_wavelength
|
||||
cur_power
|
||||
safety_mode
|
||||
end
|
||||
|
||||
methods (Access=public)
|
||||
@@ -11,8 +17,9 @@ classdef Exfo_laser
|
||||
|
||||
|
||||
arguments
|
||||
options.wavelength = 1310; %dbm
|
||||
options.power = -10; %dbm
|
||||
options.safety_mode = 1;
|
||||
options.serialport_number = 'COM8';
|
||||
options.mainframe_channel = 1;
|
||||
end
|
||||
|
||||
%
|
||||
@@ -23,52 +30,330 @@ classdef Exfo_laser
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function success = set(obj,options)
|
||||
|
||||
|
||||
arguments
|
||||
obj
|
||||
options.wavelength = obj.wavelength; %dbm
|
||||
options.power = obj.power; %dbm
|
||||
end
|
||||
|
||||
% Connect to the laser
|
||||
o = serialport("COM8", 9600);
|
||||
configureTerminator(o, "CR"); % Set the terminator to carriage return (CR)
|
||||
o = serialport(obj.serialport_number, 9600);
|
||||
configureTerminator(o, "CR", "CR"); % Set the terminator to carriage return (CR)
|
||||
flush(o);
|
||||
writeline(o, "*IDN?");
|
||||
pause(1);
|
||||
if o.NumBytesAvailable ~= 0
|
||||
disp(['Laser Mainframe: ', readline(o)]);
|
||||
answ = readline(o);
|
||||
|
||||
if obj.safety_mode
|
||||
disp(['Yay! We can talk to Instrument: ',char(answ)]);
|
||||
end
|
||||
|
||||
% Read states the first time
|
||||
obj.cur_state = obj.getLaserStatus_(o,obj.mainframe_channel);
|
||||
obj.cur_wavelength = obj.getLaserWavelength_(o,obj.mainframe_channel);
|
||||
obj.cur_power = obj.getLaserPower_(o,obj.mainframe_channel);
|
||||
|
||||
clear o;
|
||||
|
||||
if obj.safety_mode
|
||||
warning("Safety_mode ON: Display all information. Ask when switching laser. Turn safety_mode off in class instance or during initialization Exfo_laser(...,'safety_mode',0)");
|
||||
else
|
||||
error('No connection to the mainframe');
|
||||
clear o;
|
||||
warning("safety_mode OFF: EVERYTHING IS EXECUTED WITHOUT ASKING :-) BE SURE WHAT YOU DO");
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function [isEnabled,power,lambda] = getLaserInfo(obj)
|
||||
|
||||
o = obj.connectLaser_();
|
||||
|
||||
isEnabled = obj.getLaserStatus_(o,obj.mainframe_channel);
|
||||
|
||||
power = obj.getLaserPower_(o,obj.mainframe_channel);
|
||||
|
||||
lambda = obj.getLaserWavelength_(o,obj.mainframe_channel);
|
||||
|
||||
end
|
||||
|
||||
|
||||
function success = enableLaser(obj)
|
||||
success = 0;
|
||||
o = obj.connectLaser_();
|
||||
|
||||
if obj.safety_mode
|
||||
% Prompt the user to enable the laser
|
||||
choice = questdlg('Do you want to enable the laser?', ...
|
||||
'Enable Laser', ...
|
||||
'Yes', 'No', 'No');
|
||||
else
|
||||
choice = 'Yes';
|
||||
end
|
||||
|
||||
% Handle the response
|
||||
switch choice
|
||||
case 'Yes'
|
||||
% Enable the laser on channel 1
|
||||
success = obj.enableLaser_(o,obj.mainframe_channel);
|
||||
disp('Laser enabled.');
|
||||
case 'No'
|
||||
% Abort the operation
|
||||
disp('Operation aborted. Laser remains disabled.');
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
% Function to set the wavelength of the laser
|
||||
function setLaserWavelength(~,serialObj, channel, wavelength)
|
||||
command = ['CH', num2str(channel), ':L=', num2str(wavelength)];
|
||||
writeline(serialObj, command);
|
||||
pause(0.5); % Allow time for the wavelength to change
|
||||
|
||||
function success = disableLaser(obj)
|
||||
success = 0;
|
||||
o = obj.connectLaser_();
|
||||
|
||||
if obj.safety_mode
|
||||
% Prompt the user to enable the laser
|
||||
choice = questdlg('Do you want to disable the laser?', ...
|
||||
'Enable Laser', ...
|
||||
'Yes', 'No', 'No');
|
||||
else
|
||||
choice = 'Yes';
|
||||
end
|
||||
|
||||
% Handle the response
|
||||
switch choice
|
||||
case 'Yes'
|
||||
% Enable the laser on channel 1
|
||||
success = obj.disableLaser_(o,obj.mainframe_channel);
|
||||
case 'No'
|
||||
% Abort the operation
|
||||
disp('Operation aborted. Laser remains enabled.');
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function success = setPower(obj,desiredPower)
|
||||
success = 0;
|
||||
o = obj.connectLaser_();
|
||||
|
||||
if obj.safety_mode
|
||||
% Prompt the user to enable the laser
|
||||
choice = questdlg(['Do you want to set the laser to ', num2str(desiredPower) ,' dBm?'], ...
|
||||
'SET POWER', ...
|
||||
'Yes', 'No', 'No');
|
||||
else
|
||||
choice = 'Yes';
|
||||
end
|
||||
|
||||
% Handle the response
|
||||
switch choice
|
||||
case 'Yes'
|
||||
% Enable the laser on channel 1
|
||||
success = obj.setLaserPower_(o,obj.mainframe_channel,desiredPower);
|
||||
case 'No'
|
||||
% Abort the operation
|
||||
disp('Operation aborted. Laser remains at power.');
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function success = setWavelength(obj,desriedLambda)
|
||||
success = 0;
|
||||
o = obj.connectLaser_();
|
||||
|
||||
if obj.safety_mode
|
||||
% Prompt the user to enable the laser
|
||||
choice = questdlg(['Do you want to set the laser wavelength to ', num2str(desriedLambda) ,' nm?'], ...
|
||||
'SET WAVELENGTH', ...
|
||||
'Yes', 'No', 'No');
|
||||
else
|
||||
choice = 'Yes';
|
||||
end
|
||||
|
||||
% Handle the response
|
||||
switch choice
|
||||
case 'Yes'
|
||||
% Enable the laser on channel 1
|
||||
success = obj.setLaserWavelength_(o,obj.mainframe_channel,desriedLambda);
|
||||
case 'No'
|
||||
% Abort the operation
|
||||
disp('Operation aborted. Laser remains at wavelength.');
|
||||
end
|
||||
end
|
||||
|
||||
end %public mehtods
|
||||
methods (Access=private)
|
||||
|
||||
function serialobj = connectLaser_(obj)
|
||||
% Connect to the laser
|
||||
serialobj = serialport(obj.serialport_number, 9600);
|
||||
configureTerminator(serialobj, "CR", "CR"); % Set the terminator to carriage return (CR)
|
||||
flush(serialobj);
|
||||
writeline(serialobj, "*IDN?");
|
||||
answ = readline(serialobj);
|
||||
|
||||
if obj.safety_mode
|
||||
disp(['Yay! We can talk to Instrument: ',char(answ)]);
|
||||
end
|
||||
end
|
||||
|
||||
% Function to GET the STATE of the laser
|
||||
function isEnabled = getLaserStatus_(obj,serialObj, channel)
|
||||
|
||||
writeline(serialObj, ['CH', num2str(channel), ':ENABLE?']); % Query current wavelength
|
||||
|
||||
manual_flush = 1;
|
||||
while manual_flush
|
||||
response = readline(serialObj);
|
||||
manual_flush = contains(response, {'OK'});
|
||||
end
|
||||
|
||||
isEnabled = 0;
|
||||
isEnabled = contains(response, {'ENABLED'});
|
||||
|
||||
isDisabled = 0;
|
||||
isDisabled = contains(response, {'DISABLED'});
|
||||
|
||||
if isEnabled && ~isDisabled
|
||||
obj.cur_state = isEnabled;
|
||||
elseif ~isEnabled && isDisabled
|
||||
obj.cur_state = isEnabled;
|
||||
else
|
||||
error(['Unknown Laser State ->', char(response)]);
|
||||
end
|
||||
|
||||
if obj.safety_mode
|
||||
if isEnabled
|
||||
disp(['Laser ', num2str(channel) ,' is currently ON -> ', char(response)]);
|
||||
elseif isDisabled
|
||||
disp(['Laser ', num2str(channel) ,' is currently OFF ->', char(response)]);
|
||||
else
|
||||
error(['Unknown Laser State ->', char(response)]);
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
% Function to GET the wavelength of the laser
|
||||
function current_wavelen = getLaserWavelength_(obj,serialObj, channel)
|
||||
|
||||
writeline(serialObj, ['CH', num2str(channel), ':L?']); % Query current wavelength
|
||||
current_wavelen = readline(serialObj);
|
||||
disp(['Current Wavelength: ', current_wavelen]);
|
||||
|
||||
response = readline(serialObj);
|
||||
current_wavelen = str2double(regexp(response, '\d+\.\d+', 'match', 'once'));
|
||||
|
||||
if obj.safety_mode
|
||||
disp(['Current Laser ', num2str(channel) ,' Wavelength: ', num2str(current_wavelen),' --> ',char(response)]);
|
||||
end
|
||||
|
||||
obj.cur_wavelength = current_wavelen;
|
||||
end
|
||||
|
||||
% Function to set the laser power
|
||||
function setLaserPower(~,serialObj, channel, power_dBm)
|
||||
command = ['CH', num2str(channel), ':P=', num2str(power_dBm)];
|
||||
writeline(serialObj, command);
|
||||
pause(0.2); % Allow time for power to adjust
|
||||
% Function to GET the laser power
|
||||
function powerValue = getLaserPower_(obj,serialObj, channel)
|
||||
|
||||
writeline(serialObj, ['CH', num2str(channel), ':P?']); % Query current power
|
||||
current_power = readline(serialObj);
|
||||
disp(['Current Power: ', current_power, ' dBm']);
|
||||
|
||||
response = readline(serialObj);
|
||||
|
||||
isDisabled = contains(response, 'Disabled');
|
||||
|
||||
if ~isDisabled
|
||||
powerValue = str2double(regexp(response, '\d+\.\d+', 'match', 'once'));
|
||||
else
|
||||
powerValue = -200;
|
||||
end
|
||||
|
||||
if obj.safety_mode
|
||||
disp(['Current Laser ', num2str(channel) ,' Power: ', num2str(powerValue), ' dBm --> ',char(response)]);
|
||||
end
|
||||
|
||||
obj.cur_power = powerValue;
|
||||
end
|
||||
|
||||
% Function to enable the laser
|
||||
function success = enableLaser_(obj,serialObj,channel)
|
||||
success = 0;
|
||||
isEnabled = obj.getLaserStatus_(serialObj,obj.mainframe_channel);
|
||||
|
||||
writeline(serialObj, ['CH',num2str(channel),':ENABLE']);
|
||||
response = readline(serialObj);
|
||||
isok = contains(response, {'OK'});
|
||||
|
||||
cnt=0;
|
||||
while ~isEnabled || cnt>10
|
||||
isEnabled = obj.getLaserStatus_(serialObj,obj.mainframe_channel);
|
||||
pause(0.2);
|
||||
cnt = cnt+1;
|
||||
end
|
||||
|
||||
if ~isEnabled
|
||||
error('Laser not enabled but command was send')
|
||||
else
|
||||
success = 1;
|
||||
end
|
||||
end
|
||||
|
||||
% Function to enable the laser
|
||||
function success = disableLaser_(obj,serialObj,channel)
|
||||
success = 0;
|
||||
isEnabled = obj.getLaserStatus_(serialObj,obj.mainframe_channel);
|
||||
|
||||
writeline(serialObj, ['CH',num2str(channel),':DISABLE']);
|
||||
response = readline(serialObj);
|
||||
isok = contains(response, {'OK'});
|
||||
|
||||
cnt=0;
|
||||
while isEnabled || cnt>10
|
||||
isEnabled = obj.getLaserStatus_(serialObj,obj.mainframe_channel);
|
||||
pause(0.2);
|
||||
cnt = cnt+1;
|
||||
end
|
||||
|
||||
if isEnabled
|
||||
error('Laser not enabled but command was send')
|
||||
else
|
||||
success = 1;
|
||||
end
|
||||
end
|
||||
|
||||
% Function to SET the wavelength of the laser
|
||||
function success = setLaserWavelength_(~,serialObj, channel, desiredWavelength_nm)
|
||||
success = 0;
|
||||
|
||||
writeline(serialObj, ['CH',num2str(channel),':NM?']);
|
||||
modeResponse = readline(serialObj);
|
||||
isNMMode = contains(modeResponse, ['CH',num2str(channel),':1']);
|
||||
|
||||
if ~isNMMode
|
||||
warning(['Laser is in GHz Mode, you requested to set Wavelength (nm) -> ',modeResponse])
|
||||
return
|
||||
end
|
||||
|
||||
command = ['CH', num2str(channel), ':L=', num2str(desiredWavelength_nm)];
|
||||
writeline(serialObj, command);
|
||||
|
||||
pause(0.2);
|
||||
|
||||
response = readline(serialObj);
|
||||
success = contains(response, 'OK');
|
||||
|
||||
end
|
||||
|
||||
% Function to SET the laser power
|
||||
function success = setLaserPower_(~,serialObj, channel, desiredPower_dBm)
|
||||
success = 0;
|
||||
|
||||
writeline(serialObj, ['CH',num2str(channel),':MW?']);
|
||||
modeResponse = readline(serialObj);
|
||||
isMWMode = contains(modeResponse, ['CH',num2str(channel),':1']);
|
||||
|
||||
if isMWMode
|
||||
warning('Laser is in MW Mode, you requested to set dBm power')
|
||||
return
|
||||
end
|
||||
|
||||
command = ['CH', num2str(channel), ':P=', num2str(desiredPower_dBm)];
|
||||
writeline(serialObj, command);
|
||||
|
||||
pause(0.2);
|
||||
|
||||
response = readline(serialObj);
|
||||
success = contains(response, 'OK');
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -53,8 +53,11 @@ classdef OptAtten < handle
|
||||
|
||||
try
|
||||
%connect to device
|
||||
|
||||
|
||||
v = visadev('TCPIP::134.245.243.248::INSTR');
|
||||
|
||||
|
||||
debug = 0;
|
||||
if debug
|
||||
disp(['Connected to Instrument: ',char(v.Vendor),' ',char(v.Model),' SerNo:',char(v.SerialNumber)]);
|
||||
@@ -193,8 +196,9 @@ classdef OptAtten < handle
|
||||
differ = abs(state.outputpower(i)-options.value(i));
|
||||
%create msgbox when necessary
|
||||
if differ >= 2
|
||||
hMsgBox = msgbox(['Output Power at attenuator slot ' num2str(2) ' differs by 2dB or more!']);
|
||||
uiwait(hMsgBox);
|
||||
warning(['Output Power at attenuator slot ' num2str(2) ' differs by ', num2str(differ), 'or more!'])
|
||||
% hMsgBox = msgbox(['Output Power at attenuator slot ' num2str(2) ' differs by 2dB or more!']);
|
||||
% uiwait(hMsgBox);
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -212,7 +216,7 @@ classdef OptAtten < handle
|
||||
ch_info_txt = ['OptAtten: ',num2str(i),' -> Attenuated by: ',num2str(options.value(i)),' dB; Cur Output: ',num2str(state.outputpower(i)),'dBm'];
|
||||
disp(ch_info_txt);
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -257,11 +261,6 @@ classdef OptAtten < handle
|
||||
answer = sscanf(line,'%f');
|
||||
obj.power_state(cnt) = answer;
|
||||
|
||||
writeline(v, [':READ' num2str(s) ':POW?']);
|
||||
line = readline(v);
|
||||
answer = sscanf(line,'%f');
|
||||
obj.power_state(cnt) = answer;
|
||||
|
||||
writeline(v, [':INP' num2str(s) ':ATT?']);
|
||||
line = readline(v);
|
||||
answer = sscanf(line,'%f');
|
||||
@@ -272,7 +271,7 @@ classdef OptAtten < handle
|
||||
answer = sscanf(line,'%f');
|
||||
obj.wavelength_state(cnt) = answer;
|
||||
|
||||
writeline(v, [':INP' num2str(s) ':WAV?']);
|
||||
writeline(v, [':INP' num2str(s) ':ATT:SPE?']);
|
||||
line = readline(v);
|
||||
answer = sscanf(line,'%f');
|
||||
obj.speed_state(cnt) = answer;
|
||||
@@ -293,6 +292,25 @@ classdef OptAtten < handle
|
||||
end
|
||||
end
|
||||
|
||||
function [p1,p2,p3,p4]=readPower(obj)
|
||||
|
||||
v = visadev('TCPIP::134.245.243.248::INSTR');
|
||||
cnt = 1;
|
||||
for s = 1:2:7
|
||||
writeline(v, [':READ' num2str(s) ':POW?']);
|
||||
line = readline(v);
|
||||
answer = sscanf(line,'%f');
|
||||
obj.power_state(cnt) = answer;
|
||||
|
||||
cnt = cnt+1;
|
||||
end
|
||||
p1 = obj.power_state(1);
|
||||
p2 = obj.power_state(2);
|
||||
p3 = obj.power_state(3);
|
||||
p4 = obj.power_state(4);
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -12,6 +12,8 @@ classdef ScopeKeysight
|
||||
interpolate
|
||||
recordLen
|
||||
IPaddress
|
||||
|
||||
waitUntilClick
|
||||
end
|
||||
|
||||
methods (Access=public)
|
||||
@@ -30,6 +32,7 @@ classdef ScopeKeysight
|
||||
options.interpolate logical = 0;
|
||||
options.recordLen double = 1000000;
|
||||
options.IPaddress
|
||||
options.waitUntilClick = 0;
|
||||
end
|
||||
|
||||
%
|
||||
@@ -55,6 +58,7 @@ classdef ScopeKeysight
|
||||
arguments
|
||||
obj
|
||||
options.channel logical = obj.channel
|
||||
options.waitUntilClick = obj.waitUntilClick;
|
||||
end
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
@@ -79,7 +83,7 @@ classdef ScopeKeysight
|
||||
end
|
||||
end
|
||||
|
||||
debug = 1;
|
||||
debug = 0;
|
||||
if debug
|
||||
disp(['Connected to Instrument: ',char(v.Vendor),' ',char(v.Model),' SerNo:',char(v.SerialNumber)]);
|
||||
end
|
||||
@@ -119,14 +123,48 @@ classdef ScopeKeysight
|
||||
obj.writeNcheck(v,sprintf(':CHANnel%u:DISPlay ON',n));% display captured data trace
|
||||
end
|
||||
|
||||
set(v,'Timeout',150);
|
||||
if obj.autoScale
|
||||
obj.writeNcheck(v,':AUTOscale');
|
||||
for n = 1:4
|
||||
range = str2double(obj.writeReceiveCheck(v,sprintf(':CHANnel%u:RANGe?',n)));
|
||||
obj.writeNcheck(v,sprintf(':CHANnel%u:RANGe %.3f',n,range/1.2));
|
||||
|
||||
%use this to finetune autoscaling - VERY helpful
|
||||
% higher value leads to higher scaling
|
||||
fintunefactor = 1.5; % within [1,...,2]
|
||||
obj.writeNcheck(v,sprintf(':CHANnel%u:RANGe %.3f',n,range/fintunefactor));
|
||||
end
|
||||
else
|
||||
obj.writeNcheck(v,':SINGLE');
|
||||
%obj.writeNcheck(v,':SINGLE');
|
||||
end
|
||||
|
||||
% After Autoscale, let the user adjust the scope scaling...
|
||||
% "options.waitUntilClick" was a shit name but now this is it :-)
|
||||
if options.waitUntilClick
|
||||
|
||||
if 0
|
||||
% Create a dialog box with the desired text
|
||||
d = dialog('Name', 'Scale Scope then press continue', 'Position', [300, 300, 300, 180]);
|
||||
|
||||
% Add a text label with the instruction
|
||||
uicontrol('Parent', d, ...
|
||||
'Style', 'text', ...
|
||||
'Position', [20, 100, 260, 40], ...
|
||||
'String', 'Please adjust scope scaling now, then press continue', ...
|
||||
'HorizontalAlignment', 'center');
|
||||
|
||||
% Add a button to close the dialog and resume execution
|
||||
uicontrol('Parent', d, ...
|
||||
'Style', 'pushbutton', ...
|
||||
'Position', [100, 40, 100, 40], ...
|
||||
'String', 'Continue', ...
|
||||
'Callback', 'uiresume(gcbf); delete(gcbf)');
|
||||
|
||||
% Pause execution until the dialog box is closed
|
||||
uiwait(d);
|
||||
else
|
||||
holdAndShowValue
|
||||
end
|
||||
end
|
||||
|
||||
if obj.extRef
|
||||
|
||||
309
Classes/05_Lab/Thor_PDFA.m
Normal file
309
Classes/05_Lab/Thor_PDFA.m
Normal file
@@ -0,0 +1,309 @@
|
||||
classdef Thor_PDFA < handle
|
||||
|
||||
properties(Access= public)
|
||||
serialport_number
|
||||
safety_mode
|
||||
statusInfo
|
||||
|
||||
StatusRegisterValue
|
||||
Interlock
|
||||
TEC0_temp
|
||||
TEC1_temp
|
||||
Temp_stable
|
||||
Temp_fault
|
||||
LASER
|
||||
LOS_Status
|
||||
PumpLevel
|
||||
end
|
||||
|
||||
methods (Access=public)
|
||||
function obj = Thor_PDFA(options)
|
||||
|
||||
arguments
|
||||
options.serialport_number = 'COM12'
|
||||
options.safety_mode = 1;
|
||||
end
|
||||
|
||||
%
|
||||
fn = fieldnames(options);
|
||||
for n = 1:numel(fn)
|
||||
try
|
||||
obj.(fn{n}) = options.(fn{n});
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function o = connectSerial(obj)
|
||||
|
||||
% Connect to the PDFA
|
||||
o = serialport(obj.serialport_number, 9600);
|
||||
configureTerminator(o, "CR", "CR"); % Set the terminator to carriage return (CR)
|
||||
flush(o);
|
||||
|
||||
end
|
||||
|
||||
function getStatus(obj)
|
||||
|
||||
o = obj.connectSerial();
|
||||
obj.getStatus_(o);
|
||||
if obj.safety_mode
|
||||
obj
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function enablePDFA(obj)
|
||||
|
||||
o = obj.connectSerial();
|
||||
|
||||
if obj.safety_mode
|
||||
% Prompt the user to enable
|
||||
choice = questdlg('Do you want to enable the PDFA?', ...
|
||||
'TURN ON PUMP', ...
|
||||
'PUMP IT!', 'No', 'No');
|
||||
else
|
||||
choice = 'PUMP IT!';
|
||||
end
|
||||
|
||||
% Handle the response
|
||||
switch choice
|
||||
case 'PUMP IT!'
|
||||
% Enable the pump
|
||||
success = obj.enablePump_(o);
|
||||
disp('PDFA enabled.');
|
||||
case 'No'
|
||||
% Abort the operation
|
||||
disp('Operation aborted. Laser remains disabled.');
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
function disablePDFA(obj)
|
||||
|
||||
o = obj.connectSerial();
|
||||
|
||||
if obj.safety_mode
|
||||
% Prompt the user to disable
|
||||
choice = questdlg('Do you want to disable the PDFA?', ...
|
||||
'TURN OFF PUMP', ...
|
||||
'Turn off', 'No', 'No');
|
||||
else
|
||||
choice = 'Turn off';
|
||||
end
|
||||
|
||||
% Handle the response
|
||||
switch choice
|
||||
case 'Turn off'
|
||||
% Enable
|
||||
success = obj.disablePump_(o);
|
||||
disp('PDFA enabled.');
|
||||
case 'No'
|
||||
% Abort the operation
|
||||
disp('Operation aborted. Laser remains disabled.');
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
function success = setPumpLevel(obj,desiredPump)
|
||||
success = 0;
|
||||
o = obj.connectSerial();
|
||||
|
||||
obj.setPumpLevel_(o,desiredPump);
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
function cleanedResponse = cleanResponse(~,responseToClean)
|
||||
cleanedResponse = regexprep(responseToClean, '\x1B\[[0-9;]*[a-zA-Z]', '');
|
||||
end
|
||||
end
|
||||
|
||||
methods(Access= private)
|
||||
|
||||
function pumpLevel = readPumpLevel(obj,serialObj)
|
||||
writeline(serialObj, "gloc");
|
||||
pause(0.05);
|
||||
response = read(serialObj,serialObj.NumBytesAvailable,"char");
|
||||
cleanedResponse = obj.cleanResponse(response);
|
||||
currentPercentage = regexp(cleanedResponse, '([0-9]+\.[0-9]+)%', 'tokens', 'once');
|
||||
|
||||
obj.PumpLevel = str2double(currentPercentage{1});
|
||||
|
||||
pumpLevel = obj.PumpLevel;
|
||||
|
||||
end
|
||||
|
||||
function getStatus_(obj,o)
|
||||
|
||||
|
||||
writeline(o, "stat");
|
||||
pause(0.5);
|
||||
response = read(o,o.NumBytesAvailable,"char");
|
||||
cleanedResponse = obj.cleanResponse(response);
|
||||
|
||||
% Parse and convert values
|
||||
% Convert Status Register Value (hexadecimal to decimal)
|
||||
statusValueHex = regexp(cleanedResponse, 'Status Register Value = (0x[0-9A-F]+)', 'tokens', 'once');
|
||||
obj.StatusRegisterValue = hex2dec(statusValueHex{1});
|
||||
|
||||
% Convert Interlock status to logical (Closed = true, Open = false)
|
||||
interlockStatus = regexp(cleanedResponse, 'Interlock\s*:\s*(\w+)', 'tokens', 'once');
|
||||
obj.Interlock = strcmp(interlockStatus{1}, 'Closed');
|
||||
|
||||
% Convert TEC0 and TEC1 temp to logical (Good = true, Fault = false)
|
||||
tec0Temp = regexp(cleanedResponse, 'TEC0 temp\s*:\s*(\w+)', 'tokens', 'once');
|
||||
obj.TEC0_temp = strcmp(tec0Temp{1}, 'Good');
|
||||
|
||||
tec1Temp = regexp(cleanedResponse, 'TEC1 temp\s*:\s*(\w+)', 'tokens', 'once');
|
||||
obj.TEC1_temp = strcmp(tec1Temp{1}, 'Good');
|
||||
|
||||
% Convert Temp stable status to logical (Stable = true, Unstable = false)
|
||||
tempStable = regexp(cleanedResponse, 'Temp stable\s*:\s*(\w+)', 'tokens', 'once');
|
||||
obj.Temp_stable = strcmp(tempStable{1}, 'Stable');
|
||||
|
||||
% Convert Temp fault status to logical (No Fault = false, Fault = true)
|
||||
tempFault = regexp(cleanedResponse, 'Temp fault\s*:\s*(\w+)', 'tokens', 'once');
|
||||
obj.Temp_fault = strcmp(tempFault{1}, 'Fault');
|
||||
|
||||
% Convert LASER status to logical (OFF = false, ON = true)
|
||||
laserStatus = regexp(cleanedResponse, 'LASER\s*:\s*(\w+)', 'tokens', 'once');
|
||||
obj.LASER = strcmp(laserStatus{1}, 'ON');
|
||||
|
||||
% Convert LOS Status to logical (Good = true, Faulty = false)
|
||||
losStatus = regexp(cleanedResponse, 'LOS Status\s*:\s*(\w+)', 'tokens', 'once');
|
||||
obj.LOS_Status = strcmp(losStatus{1}, 'Good');
|
||||
|
||||
|
||||
writeline(o, "gloc");
|
||||
pause(0.5);
|
||||
response = read(o,o.NumBytesAvailable,"char");
|
||||
cleanedResponse = obj.cleanResponse(response);
|
||||
|
||||
% Use a regular expression to extract the operating current value in percentage
|
||||
currentPercentage = regexp(cleanedResponse, '([0-9]+\.[0-9]+)%', 'tokens', 'once');
|
||||
|
||||
% Convert the extracted percentage to a numeric value
|
||||
obj.PumpLevel = str2double(currentPercentage{1});
|
||||
|
||||
end
|
||||
|
||||
function success = enablePump_(obj,o)
|
||||
success = 0;
|
||||
|
||||
curPump = obj.readPumpLevel(o);
|
||||
|
||||
if curPump ~= 0
|
||||
cnt = 0;
|
||||
pumpSetToZero = 0;
|
||||
while ~pumpSetToZero
|
||||
pumpZero = 0;
|
||||
pumpSetToZero = obj.setPumpLevel_(o,pumpZero);
|
||||
cnt = cnt+1;
|
||||
end
|
||||
end
|
||||
|
||||
% set pump on
|
||||
writeline(o, 'le');
|
||||
pause(0.5);
|
||||
response = read(o,o.NumBytesAvailable,"char");
|
||||
cleanedResponse = obj.cleanResponse(response);
|
||||
|
||||
isEnabled = contains(cleanedResponse, {'ENABLE LASER'});
|
||||
|
||||
pause(5);
|
||||
|
||||
obj.getStatus_(o);
|
||||
|
||||
if isEnabled && obj.LASER
|
||||
success = 1;
|
||||
else
|
||||
error('Could not enable the pump....');
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function success = disablePump_(obj,o)
|
||||
success = 0;
|
||||
|
||||
curPump = obj.readPumpLevel(o);
|
||||
|
||||
if curPump ~= 0
|
||||
cnt = 0;
|
||||
pumpSetToZero = 0;
|
||||
while ~pumpSetToZero
|
||||
pumpZero = 0;
|
||||
pumpSetToZero = obj.setPumpLevel_(o,pumpZero);
|
||||
cnt = cnt+1;
|
||||
end
|
||||
end
|
||||
|
||||
% set pump on
|
||||
writeline(o, 'ld');
|
||||
pause(0.5);
|
||||
response = read(o,o.NumBytesAvailable,"char");
|
||||
cleanedResponse = obj.cleanResponse(response);
|
||||
|
||||
isDisabled = contains(cleanedResponse, {'DISABLE LASER'});
|
||||
|
||||
pause(5);
|
||||
|
||||
obj.getStatus_(o);
|
||||
|
||||
if isDisabled && ~obj.LASER
|
||||
success = 1;
|
||||
else
|
||||
error('Could not disable the pump....');
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function success = setPumpLevel_(obj,o,desiredPump)
|
||||
|
||||
success = 0;
|
||||
|
||||
curPump = obj.readPumpLevel(o);
|
||||
|
||||
while abs(curPump-desiredPump) > 0
|
||||
|
||||
% difference
|
||||
diff_pump = curPump-desiredPump;
|
||||
|
||||
% set new pump
|
||||
increment_pump = -1 * sign(diff_pump) ;
|
||||
|
||||
% set new incr. pump
|
||||
writeline(o, ['sloc ',num2str(curPump+increment_pump)]);
|
||||
|
||||
if increment_pump < 0
|
||||
pause(0.1);
|
||||
else
|
||||
pause(0.3);
|
||||
end
|
||||
|
||||
|
||||
response = read(o,o.NumBytesAvailable,"char");
|
||||
cleanedResponse = obj.cleanResponse(response);
|
||||
curPump = str2double(regexp(cleanedResponse, '([0-9]+\.[0-9]+)%', 'tokens', 'once'));
|
||||
|
||||
end
|
||||
|
||||
curPump = obj.readPumpLevel(o);
|
||||
|
||||
if obj.PumpLevel == desiredPump
|
||||
success = 1;
|
||||
else
|
||||
warning('Pump nicht richtig?')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,246 +0,0 @@
|
||||
classdef DataStorage < handle
|
||||
%DATASTORAGE Summary of this class goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
properties
|
||||
inputParams = struct;
|
||||
parameter = struct;
|
||||
fn = [];
|
||||
dim = [];
|
||||
sto = {};
|
||||
% getPhysForIndex = struct;
|
||||
% getIndexForPhys = struct;
|
||||
end
|
||||
|
||||
methods
|
||||
|
||||
function obj = DataStorage(inputParams)
|
||||
%DATASTORAGE Construct an instance of this class
|
||||
% Detailed explanation goes here
|
||||
|
||||
% scheiß Variablenname
|
||||
obj.inputParams = inputParams;
|
||||
|
||||
% Field Names
|
||||
obj.fn = string(fieldnames(inputParams));
|
||||
|
||||
% _______________
|
||||
% Two dicts that map between physical and array index :-)
|
||||
% Dictionary: 10 km -> 3
|
||||
% obj.getIndexForPhys = obj.buildIndexDict();
|
||||
|
||||
% Dictionary: 3 -> 10Km
|
||||
% obj.getPhysForIndex = obj.buildPhysDict();
|
||||
|
||||
% _______________
|
||||
% This is the 2nd Idea -> ecery given Param will be a class
|
||||
% instance of "Parameter", therin user can access the dicts and
|
||||
% informations... Have not decided which way is best..
|
||||
obj = obj.buildParameter();
|
||||
|
||||
% get dimension of dataStorage
|
||||
% e.g. if we have L = [1,2,10,80] and D=[8, 17, 21], we would
|
||||
% need an array with dimesion [4,3].
|
||||
obj.dim = obj.getDimension();
|
||||
|
||||
% finally, create the main storage as cell array
|
||||
obj.sto = struct;
|
||||
|
||||
end
|
||||
|
||||
function save(obj,path)
|
||||
try
|
||||
save(path,"obj");
|
||||
catch
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function showInfo(obj)
|
||||
disp("Data Structure with fields:");
|
||||
fprintf('%-12s', 'Name'); fprintf('%1s', '| '); fprintf('%0s ', 'Dimension'); fprintf('%4s', '| '); fprintf('%0s ', 'Physical Values'); fprintf('\n');
|
||||
disp('----------------------------------------------------------------');
|
||||
for i = 1:numel(obj.fn)
|
||||
|
||||
fprintf('%-12s', char(obj.fn(i))); fprintf('%1s', '| '); fprintf('%8.1i ', obj.dim(i)); fprintf('%5s', '| '); fprintf('%-7s ', string(obj.parameter.(obj.fn(i)).values) ); fprintf('\n');
|
||||
|
||||
end
|
||||
disp('----------------------------------------------------------------');
|
||||
|
||||
stofn = string(fieldnames(obj.sto));
|
||||
for s = 1:numel(stofn)
|
||||
nonempty = numel(find(~cellfun(@isempty,obj.sto.(stofn(s)))));
|
||||
overall = numel(obj.sto.(stofn(s)));
|
||||
fprintf('%-8s', 'Storage '); fprintf('%-10s', char(stofn(s))); fprintf('%4s', 'filled with '); fprintf('%-5s', num2str(nonempty)); fprintf('%-1s', ' entries -> '); fprintf('%-5s', num2str(nonempty/overall*100)); fprintf('%-1s', '% filled'); fprintf('\n');
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function dim = getDimension(obj)
|
||||
dim = zeros(1,numel(obj.fn));
|
||||
for p = 1:numel(obj.fn)
|
||||
%loop all parameter names and add their length :-)
|
||||
dim(p)=obj.parameter.(obj.fn(p)).length;
|
||||
end
|
||||
end
|
||||
|
||||
function obj = buildParameter(obj)
|
||||
|
||||
for p = 1:numel(obj.fn)
|
||||
name = obj.fn(p);
|
||||
values = obj.inputParams.(name);
|
||||
obj.parameter.(name) = Parameter(name,values);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function addStorage(obj,varName)
|
||||
% add a storage
|
||||
|
||||
storage = cell(obj.dim);
|
||||
|
||||
obj.sto.(string(varName)) = storage;
|
||||
|
||||
end
|
||||
|
||||
function addValueToStorage(obj, valueToStore ,storageVarName, varargin)
|
||||
|
||||
if nargin-3 == numel(obj.fn)
|
||||
lin_idx = obj.getIndicesByPhys(varargin);
|
||||
obj.sto.(storageVarName){lin_idx} = valueToStore;
|
||||
else
|
||||
error('Specify all the indices to access the right place in storage!')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
% Access Value(s)
|
||||
function value = getStoValue(obj,storageVarName, varargin)
|
||||
|
||||
if nargin-2 == numel(obj.fn)
|
||||
%es wurden aausreichend argumente übergeben :-)
|
||||
%es gibt jedoch erstmal keinen Check ob die Reihenfolge
|
||||
%richtig ist
|
||||
value = [];
|
||||
lin_idx = obj.getIndicesByPhys(varargin);
|
||||
errcnt = 0;
|
||||
for i=1:numel(lin_idx)
|
||||
% try
|
||||
tmp = obj.sto.(storageVarName){lin_idx(i)};
|
||||
if ~isempty(tmp)
|
||||
if isa(tmp,'Signal')
|
||||
if i == 1
|
||||
value = {};
|
||||
end
|
||||
value{i} = tmp ;
|
||||
elseif isa(tmp,'cell')
|
||||
if isa(tmp{1},'Signal')
|
||||
if i == 1
|
||||
value = {};
|
||||
end
|
||||
value{i} = tmp{1} ;
|
||||
end
|
||||
else
|
||||
value(i,:) = tmp ;
|
||||
end
|
||||
else
|
||||
errcnt = errcnt+1;
|
||||
value(i,:) = NaN ;
|
||||
if errcnt < 3
|
||||
%get back the n-dimensional subiondices...
|
||||
% [sub{1:length(size(obj.sto.(storageVarName)))}] = ind2sub(size(obj.sto.(storageVarName)),lin_idx(i));
|
||||
|
||||
%get back the physical representaion
|
||||
% word = [];
|
||||
% for phys_idx = 1:numel(obj.fn)
|
||||
% parametername = obj.fn(phys_idx);
|
||||
% word = [word,char(parametername),': ', num2str(obj.parameter.(parametername).getPhysForIndex(sub{phys_idx})),' ;'];
|
||||
% end
|
||||
% warning(['Requested Data is not in Warehouse ', word]);
|
||||
elseif errcnt == 3
|
||||
% warning(['... ', word]);
|
||||
end
|
||||
|
||||
end
|
||||
if errcnt > 2
|
||||
% warning([num2str(errcnt),' requested datapoint(s) not in warehouse.']);
|
||||
end
|
||||
|
||||
% catch
|
||||
% error('Error in Datastorage: Something happened while looking up in warehouse.')
|
||||
% end
|
||||
end
|
||||
else
|
||||
error('Wrong Request using ExampleWarehouse.getStoValue(*parameter set*). Give me all the Parameters! Please!')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
% Mapping for several Indices (calls the mapping for single index)
|
||||
function lin_idx = getIndicesByPhys(obj,varargin)
|
||||
%map _all_ phys. to indices - several calls of single mapping
|
||||
|
||||
inputsz = cellfun(@size,varargin{1},'UniformOutput',false);
|
||||
inputmax = cell2mat(cellfun(@max,inputsz,'UniformOutput',false));
|
||||
|
||||
% I wrote this method for a single query, then refined it for vectorial
|
||||
% inputs (which work fine), but lastly recognized that I
|
||||
% destroyed single query... however, this if / else will fix it!
|
||||
if sum(inputmax)==length(inputmax)
|
||||
vecQuery = 1; %set any value to one
|
||||
else
|
||||
vecQuery = find(inputmax~=1); %position of vectorial queries
|
||||
end
|
||||
|
||||
q={};
|
||||
for i = 1:numel(vecQuery)
|
||||
q{i} = varargin{1,1}{vecQuery(i)}; %the two vectors
|
||||
end
|
||||
|
||||
combination = combvec(q{:}); %combine all possible combinations
|
||||
|
||||
for c = 1:length(combination)
|
||||
%loop over all possible combinations
|
||||
|
||||
indices = {};
|
||||
str = [];
|
||||
|
||||
for r = 1:numel(vecQuery)
|
||||
%replace varargin with current query (could have been renamed... however it works)
|
||||
varargin{1}{vecQuery(r)} = combination(r,c);
|
||||
end
|
||||
|
||||
for p = 1:numel(obj.fn)
|
||||
|
||||
curPhysQuery = varargin{1}{p}; %can be: a) single value // b) range
|
||||
|
||||
curParameterName = obj.fn(p);
|
||||
|
||||
indices{end+1} = obj.getIndexByPhys(curParameterName,curPhysQuery);
|
||||
|
||||
% str = [str, ',indices{', num2str(p), '}'];
|
||||
|
||||
end
|
||||
|
||||
%append to index list :-)
|
||||
fn_=fieldnames(obj.sto);
|
||||
n_ = fn_{1};
|
||||
lin_idx(c,:) = sub2ind(size(obj.sto.(n_)),indices{:});
|
||||
% lin_idx(c,:) = eval(['sub2ind(size(obj.sto.',n_,')',str,');']);
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
% Mapping for single Index
|
||||
function idx = getIndexByPhys(obj,fieldname,phys)
|
||||
%map single phys to index
|
||||
idx = obj.parameter.(fieldname).getIndexForPhys(phys);
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user