-
Notifications
You must be signed in to change notification settings - Fork 0
/
ifaceLDC.m
125 lines (106 loc) · 3.49 KB
/
ifaceLDC.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
%% ifaceLDC.m MN 2020-06-26
% Sets state and output parameters for a variety of laser diode controllers
%
% Requirements:
% - VISA interface functions in path
% - Equipment is connected
%
% Usage: [[I; V; T], [stdI; stdV; stdT]] = ifaceLDC(ldcID[, option, value])
% Returns:
% I: Diode output current
% V: Diode output voltage
% T: TEC temperature reading
% std<I,V,T>: Standard deviation of above, if averaging requested
%
% Parameters:
% ldcID: LDC ID - see mapLDC('list') for available LDCs
%
% Options:
% 'state', %i: Turns diode output on or off
% 'current', %f: Sets output current to this if possible (amps)
% 'limit', [%f, %f]: Sets diode output current and voltage limits (amps, volts)
% 'temperature' | 'temp', %f: Changes TEC temperature setpoint to this; <0 for 'off'
% 't' | 'avg', %f: Average measurements this long
% 'reset', 1: Resets/initializes LDC to standard values first
%
% TODO:
% - Verify units
% - Test and debug
function [IVT, stdIVT] = ifaceLDC(ldcID, varargin)
%% Defaults and magic numbers
I=[]; V=[]; T=[];
avgT = 0; outI = NaN; limit = NaN; temp = NaN; reset = 0; state = NaN;
inrange = @(x, lims) (x >= min(lims)) & (x <= max(lims));
%% Argument parsing
% Accept a struct.option = value structure
if numel(varargin) > 0 && isstruct(varargin{1})
paramStruct = varargin{1}; varargin(1) = [];
varargin = [reshape([fieldnames(paramStruct) struct2cell(paramStruct)]', 1, []), varargin];
end
if mod(numel(varargin),2) % I always use "'flag', value" even for boolean commands
error('Odd number of optional inputs!');
end
% Optional alterations
for i = 1:2:length(varargin)
arg = lower(varargin{i});
argval = varargin{i+1};
switch arg
case {'t', 'avg'}
avgT = double(argval);
case 'state'
state = argval > 0;
case 'current'
outI = double(argval);
case 'limit'
limit = double(argval);
case {'temperature', 'temp'}
temp = double(argval);
case 'reset'
reset = argval > 0;
end
end
%% Look up power meter and set appropriate interface
ldc = mapLDC(ldcID);
ldcInterface = ldc.interface;
if isempty(ldcInterface)
error('Unsupported LDC type "%s" for LDC "%s"!', ldc.type, ldcID);
end
%% Set options as requested
if reset == 1
ldcInterface(ldc.visaAddr, 'reset');
pause(0.5); % Wait for reset
end
if ~isnan(temp)
ldcInterface(ldc.visaAddr, 'set', temp);
end
if ~isnan(limit)
if ~inrange(limit(1), ldc.currentlim)
error('Specified limit current %.5g out of valid range [%.5g %.5g]!', limit(1), ldc.currentlim);
end
if length(limit) > 1
if ~inrange(limit(2), ldc.voltagelim)
error('Specified compliance voltage limit %.5g out of valid range [%.5g %.5g]!', limit(2), ldc.voltagelim);
end
end
ldcInterface(ldc.visaAddr, 'limit', limit);
end
if ~isnan(outI)
if ~inrange(outI, ldc.currentlim)
error('Specified current %.5g out of valid range [%.5g %.5g]!', outI, ldc.currentlim);
end
ldcInterface(ldc.visaAddr, 'current', outI);
pause(0.1); % Wait for update
end
if ~isnan(state)
ldcInterface(ldc.visaAddr, 'state', state);
pause(0.5); % Wait for update
end
%% Read present state, with averaging if enabled
tic;
[I, V, T] = ldcInterface(ldc.visaAddr, 'read');
while toc < avgT
[I(end+1), V(end+1), T(end+1)] = ldcInterface(ldc.visaAddr, 'read');
end
IVT = mean([I; V; T], 2);
stdIVT = std([I; V; T], 0, 2);
end