-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathifacePiezo.m
125 lines (107 loc) · 3.45 KB
/
ifacePiezo.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
%% ifacePiezo.m MN 2020-06-26
% Interface for piezo controllers
%
% Requirements:
% - VISA interface functions in path
% - Equipment is connected
%
% Usage: V = ifacePiezo(piezoID[, options])
% Returns:
% V: Current piezo voltage; size [<channels>, 1]
%
% Parameters:
% piezoID: LDC ID - see mapLDC('list') for available LDCs
%
% Options:
% 'vch' | 'setch', %i, %f: Set channel %i to voltage %f
% 'v' | 'voltage' | 'set', %f: Set output voltage; size(%f) = [<channels>, 1]
% or scalar to set all
% 'reset': Set all channels to half-point
% 'maxv' | 'vmax' | 'limit': Return the maximum output voltage
%
% TODO:
% - Test and debug
function V = ifacePiezo(piezoID, varargin)
%% Defaults and magic numbers
V = [];
%% Look up piezo controller and set appropriate interface and properties
piezo = mapPiezo(piezoID);
% Interface function
if isempty(piezo.interface)
error('Unsupported piezo type "%s" for piezo "%s"!', piezo.type, piezoID);
end
% Channel limits
chLim = [1 numel(piezo.channels)];
vLim = [0 piezo.interface(piezo.visaAddr, 'limit')];
%% Option parsing and execution
% Allow multiple inputs; set up ordered list of functions to execute
executeList = {};
% Allow passing of cells of options
varargin = flatten(varargin);
% Parameter parsing
while ~isempty(varargin)
arg = lower(varargin{1}); varargin(1) = [];
switch arg
case {'vch', 'setch'}
ch = validateCh(varargin{1}, chLim); varargin(1) = [];
setv = validateV(varargin{1}, vLim); varargin(1) = [];
executeList{end+1} = ...
{'set', ch, setv};
case {'v', 'voltage', 'set'}
setv = varargin{1}; varargin(1) = [];
if numel(setv) == numel(piezo.channels)
setv = arrayfun(@(v) validateV(v, vLim), setv);
elseif numel(setv) > 1
error('Neither scalar nor channel-sized (%i) voltage requested: %s', numel(piezo.channels), num2str(setv, '%f, '));
end
executeList{end+1} = ...
{'setall', setv};
case 'reset'
executeList{end+1} = ...
{'setall', max(vLim)/2};
case {'maxv', 'vmax', 'limit', 'lim'}
V = max(vLim);
otherwise
if ~isempty(arg)
warning('Unexpected option "%s", ignoring', num2str(arg));
end
end
end
%% Helper functions
function c = validateCh(ch, chLim)
if ischar(ch)
c = find(strcmpi(piezo.channels, ch));
else
c = round(ch);
end
if ~((c >= min(chLim)) && (c <= max(chLim)))
error('Channel %s not valid!', ch);
end
end
function V = validateV(V, vLim)
V = double(V);
if ~((V >= min(vLim)) && (V <= max(vLim)))
error('Set voltage %.2f not valid; system max %.2f.', V, max(vLim));
end
end
% Flatten a nested cell
function flatCell = flatten(varargin)
flatCell = {};
for j=1:numel(varargin)
if iscell(varargin{j})
flatCell = [flatCell flatten(varargin{j}{:})];
else
flatCell = [flatCell varargin(j)];
end
end
flatCell = flatCell( ~cellfun(@isempty, flatCell) );
end
%% Execute in order
for args = executeList
piezo.interface(piezo.visaAddr, args{1}{:});
end
%% Read present state
if isempty(V)
V = piezo.interface(piezo.visaAddr, 'readall');
end
end