Files
imdd_silas/Classes/05_Lab/OptPowerMeter8153A.m
2025-12-18 09:56:52 +01:00

169 lines
5.3 KiB
Matlab

classdef OptPowerMeter8153A < handle
% Code for HEWLETT-PACKARD 8153A Optical Power Meter (2-channel).
% https://www.artisantg.com/info/Agilent_8153A_Manual.pdf?srsltid=AfmBOoqTe38sbGRNHUFXjw5uO6Br7I7aSfgAdRpx-hVvM4sTIhFYyD5x
% PAGE 166++
% Typical usage:
% pm = HPPowerMeter8153A( ...
% 'active', [false true], ...
% 'wavelength_nm', [1550 1310] );
%
% pm.setWavelength([1550 1310]); % only CH2 is modified
% p = pm.readPower(); % reads only active channels
properties (Access = public)
active logical = [true true] % channel enable
wavelength_nm double = [1550 1550] % per-channel wavelength [nm]
power_dBm double = [NaN NaN] % last read power
offset_dB double = [0 0] % per-channel power offset [dB]
avgTime_s double = [0.2 0.2];
end
properties (Constant)
avgTime_min_s = 0.02 % 20 ms
avgTime_max_s = 3600 % 1 hour
end
properties (Access = protected)
visaAddress string = "GPIB1::22::INSTR"
numChannels double = 2
end
methods
function obj = OptPowerMeter8153A(options)
arguments
options.visaAddress string = "GPIB1::22::INSTR"
options.active logical = [true true]
options.wavelength_nm double = [1550 1550]
end
fn = fieldnames(options);
for k = 1:numel(fn)
obj.(fn{k}) = options.(fn{k});
end
assert(numel(obj.active)==obj.numChannels)
assert(numel(obj.wavelength_nm)==obj.numChannels)
v = obj.connect();
writeline(v,"*IDN?");
disp(readline(v));
pause(0.1);
delete(v);
pause(0.1);
obj.setWavelength(obj.wavelength_nm);
end
function setWavelength(obj, lambda_nm)
if nargin > 1
obj.wavelength_nm = lambda_nm;
end
v = obj.connect();
for ch = 1:obj.numChannels
if obj.active(ch)
writeline(v, ...
sprintf("SENS%d:POW:WAVE %gNM", ch, obj.wavelength_nm(ch)));
end
end
pause(0.1);
delete(v);
pause(0.1);
end
function p = readPower(obj)
v = obj.connect();
for ch = 1:obj.numChannels
if obj.active(ch)
writeline(v, sprintf("READ%d:POW?", ch));
obj.power_dBm(ch) = str2double(readline(v));
else
obj.power_dBm(ch) = NaN;
end
end
delete(v);
p = obj.power_dBm;
end
function setOffsetCorrection(obj, offset_dB)
obj.offset_dB = offset_dB;
v = obj.connect();
for ch = 1:obj.numChannels
if obj.active(ch)
writeline(v, ...
sprintf("SENS%d:CORR:LOSS:INP:MAGN %gDB", ch, obj.offset_dB(ch)));
end
end
delete(v);
end
function offset_dB = getOffsetCorrection(obj)
v = obj.connect();
offset_dB = NaN(1,obj.numChannels);
for ch = 1:obj.numChannels
if obj.active(ch)
writeline(v, sprintf("SENS%d:CORR:LOSS:INP:MAGN?", ch));
offset_dB(ch) = str2double(readline(v));
end
end
delete(v);
obj.offset_dB = offset_dB;
end
function setAvgTime(obj, avgTime_s)
if any(avgTime_s < obj.avgTime_min_s) || any(avgTime_s > obj.avgTime_max_s)
oldv = avgTime_s;
avgTime_s = max(avgTime_s, obj.avgTime_min_s);
avgTime_s = min(avgTime_s, obj.avgTime_max_s);
fprintf('[HPPowerMeter8153A] Averaging time clipped:\n');
for ch = 1:obj.numChannels
if oldv(ch) ~= avgTime_s(ch)
fprintf(' CH%d: %.3g s → %.3g s (allowed %.3g … %.3g s)\n', ...
ch, oldv(ch), avgTime_s(ch), ...
obj.avgTime_min_s, obj.avgTime_max_s);
end
end
end
obj.avgTime_s = avgTime_s;
v = obj.connect();
for ch = 1:obj.numChannels
if obj.active(ch) && ~isnan(obj.avgTime_s(ch))
writeline(v, ...
sprintf("SENS%d:POW:ATIME %g", ch, obj.avgTime_s(ch)));
end
end
delete(v);
end
function avgTime_s = getAvgTime(obj)
v = obj.connect();
avgTime_s = NaN(1,obj.numChannels);
for ch = 1:obj.numChannels
if obj.active(ch)
writeline(v, sprintf("SENS%d:POW:ATIME?", ch));
avgTime_s(ch) = str2double(readline(v));
end
end
delete(v);
obj.avgTime_s = avgTime_s;
end
end
methods (Access = protected)
function v = connect(obj)
v = visadev(obj.visaAddress);
end
end
end