Files
imdd_silas/Classes/05_Lab/OptAtten.m
2024-09-26 14:50:25 +02:00

288 lines
14 KiB
Matlab

classdef OptAtten
% control optical attenuator Keysight N7764a via LAN
% set parameters of optical attenuator, e.g. attenuation, wavelength, etc. and read out output power from attenuator
properties(Access=public)
active %'Enable/Disable attenuator slots. Array position indexes detemines attenuator slot: [1->2 3->4 5->6 7->8]. Value determines mode: 0: off; 1: constant attenuation value; 2: constant output power';
value %'Set attenuation [dB] or constant output power [dBm]. Range attenuation [0, 45], range constant output power [-50, 20]';
speed %'Enter a desired speed for attenuation changes [dB/s]. Range: [0.1, 1000]';
wavelength %'Enter the wavelength of the applied light [nm]. Range: [1260, 1640]';
avgTime %'Enter a desired averaging time [ms]. Higher averaging times will increase stability of the readings but will slow down measurement speed. Range: [2, 1000]';
dbOffset %'A non-zero attenuation offset shifts the logarithmic attenuation scale. Then, the set attenuation value differs from the internally calibrated attenuation. Range [-200, 200]';
psetOffset %'A non-zero power offset shifts the logarithnic power scale. Then, the power reading and the set power (Pset) values differ from the internal power calibration. Range [-60, 60]';
end
methods (Access=public)
function obj = OptAtten(options)
arguments
options.active double = [0,0,0,0];
options.value double = [0,0,0,0];
options.speed double = [1000 1000 1000 1000];
options.wavelength double = [1550 1550 1550 1550];
options.avgTime double = [2 2 2 2];
options.dbOffset double = [0 0 0 0];
options.psetOffset double = [0 0 0 0];
end
fn = fieldnames(options);
for n = 1:numel(fn)
try
obj.(fn{n}) = options.(fn{n});
end
end
end
function success = set(obj,options)
arguments
obj
options.active = obj.active; %if not used as arg of .set('active',[0,0,0,0]) method the class values are used...
options.value = obj.value;
end
try
%connect to device
v = visadev('TCPIP::134.245.243.248::INSTR');
writeline(v, '*IDN?;');
disp(['Active atten: ' readline(v)]); %Keysight Technologies, N7764A, MY49A00696, 1.13.1
slot = 0; %init slot number
%loop to set values for every attenuator slot
for i = 1:length(obj.active)
%convert index number i into slot number
slot = 2*i - 1;
%check whether attenuator is used or unused
if ~obj.active(i) %atten slot unused
writeline(v, [':OUTP' num2str(slot) ':STAT OFF']);
else %atten slot used (attenuation/const output power)
%set attenuation or output power
if obj.active(i) == 1 %attenuation
if obj.value(i) < 0
obj.value(i) = 0;
hMsgBox = msgbox(['Value for attenuation out of range. Please consider minimum value. Attenuation set to ' num2str(obj.value(i)) 'dB']);
uiwait(hMsgBox);
elseif obj.value(i) > 45
obj.value(i) = 45;
hMsgBox = msgbox(['Value for attenuation out of range. Please consider maximum value. Attenuation set to ' num2str(obj.value(i)) 'dB']);
uiwait(hMsgBox);
end
writeline(v, [':OUTP' num2str(slot) ':POW:CONTR OFF']);
writeline(v, [':INP' num2str(slot) ':ATT ' num2str(obj.value(i)) 'dB']);
elseif obj.active(i) == 2 %constant output power
if obj.value(i) < -50
obj.value(i) = -50;
hMsgBox = msgbox(['Value for output power out of range. Please consider minimum value. Output power set to ' num2str(obj.value(i)) 'dBm']);
uiwait(hMsgBox);
elseif obj.value(i) > 20
obj.value(i) = 20;
hMsgBox = msgbox(['Value for output power out of range. Please consider maximum value. Output set to ' num2str(obj.value(i)) 'dBm']);
uiwait(hMsgBox);
end
writeline(v, [':OUTP' num2str(slot) ':POW:CONTR ON']);
writeline(v, [':OUTP' num2str(slot) ':POW ' num2str(obj.value(i))]);
end
%set value for speed
if obj.speed(i) < 0.1
obj.speed(i) = 0.1;
hMsgBox = msgbox(['Value for speed out of range. Please consider minimum value. Speed set to ' num2str(obj.speed(i)) 'dB/s']);
uiwait(hMsgBox);
elseif obj.speed(i) > 1000
obj.speed(i) = 1000;
hMsgBox = msgbox(['Value for speed out of range. Please consider maximum value. Speed set to ' num2str(obj.speed(i)) 'dB/s']);
uiwait(hMsgBox);
end
writeline(v, [':INP' num2str(slot) ':ATT:SPE ' num2str(obj.speed(i))]);
%set value for wavelength
if obj.wavelength(i) < 1260
obj.wavelength(i) = 1260;
hMsgBox = msgbox(['Value for wavelength out of range. Please consider minimum value. Wavelength set to ' num2str(obj.wavelength(i)) 'nm']);
uiwait(hMsgBox);
elseif obj.wavelength(i) > 1640
obj.wavelength(i) = 1640;
hMsgBox = msgbox(['Value for wavelength out of range. Please consider maximum value. Wavelength set to ' num2str(obj.wavelength(i)) 'nm']);
uiwait(hMsgBox);
end
wavelength_nm = obj.wavelength(i) * 1e-9;
writeline(v, [':INP' num2str(slot) ':WAV ' num2str(wavelength_nm)]);
%set value for averaging times
if obj.avgTime(i) < 2
obj.avgTime(i) = 2;
hMsgBox = msgbox(['Value for average time out of range. Please consider minimum value. Average time set to ' num2str(obj.avgTime(i)) 'ms']);
uiwait(hMsgBox);
elseif obj.avgTime(i) > 1000
obj.avgTime(i) = 1000;
hMsgBox = msgbox(['Value for average time out of range. Please consider maximum value. Average time set to ' num2str(obj.avgTime(i)) 'ms']);
uiwait(hMsgBox);
end
avgTime_sec = obj.avgTime(i) / 1000;
writeline(v, [':OUTP' num2str(slot) ':ATIM ' num2str(avgTime_sec)]);
%set value for attenuation offset and output power offset
if obj.dbOffset(i) < -200
obj.dbOffset(i) = -200;
hMsgBox = msgbox(['Value for attenuation offset out of range. Please consider minimum value. Attenuation offset set to ' num2str(obj.dbOffset(i)) 'dB']);
uiwait(hMsgBox);
elseif obj.dbOffset(i) > 200
obj.dbOffset(i) = 200;
hMsgBox = msgbox(['Value for attenuation out of range. Please consider maximum value. Attenuation offset set to ' num2str(obj.dbOffset(i)) 'dB']);
uiwait(hMsgBox);
end
writeline(v, [':INP' num2str(slot) ':OFFS ' num2str(obj.dbOffset(i)) 'dB']);
if obj.psetOffset < -60
obj.psetOffset = -60;
hMsgBox = msgbox(['Value for output power offset out of range. Please consider minimum value. Output power offset set to ' num2str(obj.psetOffset(i)) 'dBm']);
uiwait(hMsgBox);
elseif obj.psetOffset > 60
obj.psetOffset = 60;
hMsgBox = msgbox(['Value for output power offset out of range. Please consider maximum value. Output power offset set to ' num2str(obj.psetOffset(i)) 'dBm']);
uiwait(hMsgBox);
end
writeline(v, [':OUTP' num2str(slot) ':POW:OFFS ' num2str(obj.psetOffset(i))]);
%turn on attenuator slot
writeline(v, [':OUTP' num2str(slot) ':STAT ON']);
end
end
%pause 2 seconds before measuring output power
pause(2);
%read output power from attenuator and save to state.ouputpower
for i = 1:length(obj.active)
if obj.active(i)
%convert index number i into slot number
slot = 2*i - 1;
%read and save
writeline(v, [':READ' num2str(slot) ':POW?']);
state.outputpower(i) = sscanf(readline(v),'%f');
end
end
%create warning message when measured output power differs from
%set output power by 2dB.
for i = 1:length(obj.active)
if obj.active(i) == 2
%determine absolute difference
differ = abs(state.outputpower(i)-obj.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);
end
end
end
%create output
for i = 1:length(obj.active)
if obj.active(i) == 2
% Output power mode:
%differ = abs(state.outputpower(i)-obj.value(i));
ch_info_txt = ['OptAtten: ',num2str(i),' -> Desired: ',num2str(obj.value(i)),' dBm; Cur Output: ',num2str(state.outputpower(i)),'dBm'];
disp(ch_info_txt);
else
ch_info_txt = ['OptAtten: ',num2str(i),' -> Attenuated by: ',num2str(obj.value(i)),' dB; Cur Output: ',num2str(state.outputpower(i)),'dBm'];
disp(ch_info_txt);
end
end
%disconnect
delete(v);
catch error
%disconnect if error occurrs
delete(v);
hMsgBox = msgbox('An error occurred while connecting or writing to the attenuator. Please try again. Otherwise, please restart MATLAB. For more information see error message in command window.');
uiwait(hMsgBox);
rethrow(error);
end
end
function readvals(obj)
try
%connect to device
v = visadev('TCPIP::134.245.243.248::INSTR');
writeline(v, '*IDN?;');
disp(['Active atten: ' readline(v)]); %Keysight Technologies, N7764A, MY49A00696, 1.13.1
power=[];
for s = 1:2:7
writeline(v, [':OUTP' num2str(s) ':STAT?']);
line = readline(v);
answer = sscanf(line,'%f');
disp(['Slot ' num2str(s) ' enabled state: ' num2str(answer)]);
writeline(v, [':OUTP' num2str(s) ':POW?']);
line = readline(v);
answer = sscanf(line,'%f');
disp(['P_set (output power) for Slot ' num2str(s) ': ' num2str(answer) ' dBm']);
writeline(v, [':OUTP' num2str(s) ':POW:CONTR?']);
line = readline(v);
answer = sscanf(line,'%f');
disp(['Power control for Slot ' num2str(s) ': ' num2str(answer)]);
if answer == 1
writeline(v, [':READ' num2str(s) ':POW?']);
line = readline(v);
answer = sscanf(line,'%f');
disp([' -> Slot ' num2str(s) ' desired outut power: ' num2str(answer) ' dBm']);
else
writeline(v, [':INP' num2str(s) ':ATT?']);
line = readline(v);
answer = sscanf(line,'%f');
disp([' -> Alpha (fix attenuation) for slot ' num2str(s) ': ' num2str(answer) ' dB']);
end
writeline(v, [':INP' num2str(s) ':WAV?']);
line = readline(v);
answer = sscanf(line,'%f');
disp(['Wavelength for Slot ' num2str(s) ': ' num2str(answer) ' nm']);
writeline(v, [':OUTP' num2str(s) ':ATIM?']);
line = readline(v);
answer = sscanf(line,'%f');
disp(['Averaging time for Slot ' num2str(s) ': ' num2str(answer) ' s']);
fprintf('\n')
end
delete(v);
catch error
%disconnect if error occurrs
delete(v);
hMsgBox = msgbox('An error occurred while connecting or writing to the attenuator. Please try again. Otherwise, please restart MATLAB. For more information see error message in command window.');
uiwait(hMsgBox);
rethrow(error);
end
end
end
end