Files
imdd_silas/Classes/05_Lab/OptAtten.m
Silas Labor Zizou 6570746d17 New AWG M8199A now included
ExfoLaser now uses GPIB
minor stuff
2025-03-03 09:13:16 +01:00

326 lines
15 KiB
Matlab

classdef OptAtten < handle
% 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]';
atten_state
value_state
power_state
speed_state
wavelength_state
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');
debug = 0;
if debug
disp(['Connected to Instrument: ',char(v.Vendor),' ',char(v.Model),' SerNo:',char(v.SerialNumber)]);
end
%Keysight Technologies, N7764A, MY49A00696, 1.13.1
slot = 0; %init slot number
%loop to set values for every attenuator slot
for i = 1:length(options.active)
%convert index number i into slot number
slot = 2*i - 1;
%check whether attenuator is used or unused
if ~options.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 options.active(i) == 1 %attenuation
if options.value(i) < 0
options.value(i) = 0;
hMsgBox = msgbox(['Value for attenuation out of range. Please consider minimum value. Attenuation set to ' num2str(options.value(i)) 'dB']);
uiwait(hMsgBox);
elseif options.value(i) > 45
options.value(i) = 45;
hMsgBox = msgbox(['Value for attenuation out of range. Please consider maximum value. Attenuation set to ' num2str(options.value(i)) 'dB']);
uiwait(hMsgBox);
end
writeline(v, [':OUTP' num2str(slot) ':POW:CONTR OFF']);
writeline(v, [':INP' num2str(slot) ':ATT ' num2str(options.value(i)) 'dB']);
elseif options.active(i) == 2 %constant output power
if options.value(i) < -50
options.value(i) = -50;
hMsgBox = msgbox(['Value for output power out of range. Please consider minimum value. Output power set to ' num2str(options.value(i)) 'dBm']);
uiwait(hMsgBox);
elseif options.value(i) > 20
options.value(i) = 20;
hMsgBox = msgbox(['Value for output power out of range. Please consider maximum value. Output set to ' num2str(options.value(i)) 'dBm']);
uiwait(hMsgBox);
end
writeline(v, [':OUTP' num2str(slot) ':POW:CONTR ON']);
writeline(v, [':OUTP' num2str(slot) ':POW ' num2str(options.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(options.active)
if options.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(options.active)
if options.active(i) == 2
%determine absolute difference
differ = abs(state.outputpower(i)-options.value(i));
%create msgbox when necessary
if differ >= 2
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
%create output
silent = 0;
if silent
for i = 1:length(options.active)
if options.active(i) == 2
% Output power mode:
%differ = abs(state.outputpower(i)-options.value(i));
ch_info_txt = ['OptAtten: ',num2str(i),' -> Desired: ',num2str(options.value(i)),' dBm; Cur Output: ',num2str(state.outputpower(i)),'dBm'];
disp(ch_info_txt);
else
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
%disconnect
delete(v);
obj.readvals();
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,options)
arguments
obj
options.print2console = 0;
end
try
%connect to device
v = visadev('TCPIP::134.245.243.248::INSTR');
cnt = 1;
for s = 1:2:7
writeline(v, [':OUTP' num2str(s) ':POW?']);
line = readline(v);
answer = sscanf(line,'%f');
obj.value_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');
obj.atten_state(cnt) = answer;
writeline(v, [':INP' num2str(s) ':WAV?']);
line = readline(v);
answer = sscanf(line,'%f');
obj.wavelength_state(cnt) = answer;
writeline(v, [':INP' num2str(s) ':ATT:SPE?']);
line = readline(v);
answer = sscanf(line,'%f');
obj.speed_state(cnt) = answer;
cnt = cnt+1;
end
fprintf("\n SET: CH1 %.2f dB | CH2: %.2f dB | CH3: %.2f dB | CH4: %.2f dB\n",obj.value_state(1), obj.value_state(2), obj.value_state(3), obj.value_state(4));
fprintf(" ATT: CH1 %.2f dB | CH2: %.2f dB | CH3: %.2f dB | CH4: %.2f dB\n",obj.atten_state(1), obj.atten_state(2), obj.atten_state(3), obj.atten_state(4));
fprintf(" POW: CH1 %.2f dBm | CH2: %.2f dBm | CH3: %.2f dBm | CH4: %.2f dBm \n \n",obj.power_state(1), obj.power_state(2), obj.power_state(3), obj.power_state(4));
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 [p1,p2,p3,p4]=readPower(obj, options)
arguments
obj
options.silent = 0
end
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);
if options.silent == 0
fprintf("\n CH1: %.2f dB | CH2: %.2f dB | CH3: %.2f dB | CH4: %.2f dB\n \n",p1, p2, p3, p4);
end
end
end
end