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