1 | function [AM, tout, DataTime, ErrorFlag] = getpvonline(ChannelNames, varargin) |
---|
2 | %GETPVONLINE - Gets the online value |
---|
3 | % |
---|
4 | % For DateType = 'Double' or 'Scalar' |
---|
5 | % [AM, tout, DataTime, ErrorFlag] = getpvonline(ChannelNames, t) |
---|
6 | % |
---|
7 | % For DateType = 'String', 'Vector', 'Matrix' |
---|
8 | % [AM, tout, DataTime, ErrorFlag] = getpvonline(ChannelNames, DataType, N) |
---|
9 | % |
---|
10 | % In general: |
---|
11 | % [AM, tout, DataTime, ErrorFlag] = getpvonline(ChannelNames, DataType, N, t) |
---|
12 | % |
---|
13 | % INPUTS |
---|
14 | % 1. ChannelNames |
---|
15 | % 2. DataType - 'Double', 'String', 'Vector' or 'Waveform', 'Matrix' {Default: 'Double'} |
---|
16 | % Matlab works in Strings and Doubles (for the most part), so EPICS data types |
---|
17 | % like SCA_SHORT, SCA_FLOAT, SCA_SHORT, SCA_LONG all map to a double. |
---|
18 | % 'Vector', 'Waveform', and 'Matrix' return a vector or matrix of doubles. |
---|
19 | % 3. N - Number of data points to return {Default: 1} |
---|
20 | % (only used for 'Vector', 'Waveform', and 'Matrix' DataTypes) |
---|
21 | % 4. t - time vector of when to start a read [seconds] |
---|
22 | % |
---|
23 | % OUTPUTS |
---|
24 | % 1. AM - Value |
---|
25 | % 2. tout - Local computer time on finish of data read |
---|
26 | % 3. DataTime = time (in seconds) since 00:00:00, Jan 1, 1970 |
---|
27 | % (seconds + nanoseconds * i) |
---|
28 | % 4. ErrorFlag (Presently not functional. All errors will cause a Matlab error.) |
---|
29 | % |
---|
30 | % Written by Greg Portmann |
---|
31 | |
---|
32 | |
---|
33 | % To do |
---|
34 | % 1. NAvg, AvgPeriod |
---|
35 | |
---|
36 | |
---|
37 | ErrorFlag = 0; |
---|
38 | |
---|
39 | |
---|
40 | % Function start time |
---|
41 | t0 = clock; |
---|
42 | |
---|
43 | |
---|
44 | if nargin < 1 |
---|
45 | error('Must have at least a channel name input'); |
---|
46 | end |
---|
47 | |
---|
48 | |
---|
49 | % Input parsing |
---|
50 | DataType = 'Double'; |
---|
51 | N = 0; |
---|
52 | t = 0; |
---|
53 | NAvg = 1; |
---|
54 | AvgPeriod = 0; |
---|
55 | if length(varargin) >= 1 |
---|
56 | if ischar(varargin{1}) |
---|
57 | DataType = varargin{1}; |
---|
58 | varargin(1) = []; |
---|
59 | if length(varargin) >= 1 |
---|
60 | N = varargin{1}; |
---|
61 | varargin(1) = []; |
---|
62 | end |
---|
63 | end |
---|
64 | if length(varargin) >= 1 |
---|
65 | t = varargin{1}; |
---|
66 | if length(varargin) >= 2 |
---|
67 | NAvg = varargin{2}; |
---|
68 | if length(varargin) >= 3 |
---|
69 | AvgPeriod = varargin{3}; |
---|
70 | if length(varargin) >= 4 |
---|
71 | FreshDataFlag = varargin{4}; |
---|
72 | end |
---|
73 | end |
---|
74 | end |
---|
75 | end |
---|
76 | end |
---|
77 | |
---|
78 | % Scalars |
---|
79 | N = N(1); |
---|
80 | NAvg = NAvg(1); |
---|
81 | AvgPeriod = AvgPeriod(1); |
---|
82 | |
---|
83 | % t must be a row vector |
---|
84 | t = t(:)'; |
---|
85 | |
---|
86 | |
---|
87 | % Vectorized Get |
---|
88 | % There can be multiple channel names due to "ganged" power supplies (or redundent user input) |
---|
89 | [ChannelNames, i, j] = unique(ChannelNames, 'rows'); |
---|
90 | |
---|
91 | |
---|
92 | % Remove ' ' and fill with NaN latter (' ' should always be the first row) |
---|
93 | if isempty(deblank(ChannelNames(1,:))) |
---|
94 | iblank = 1; |
---|
95 | ChannelNames(1,:) = []; |
---|
96 | else |
---|
97 | iblank = []; |
---|
98 | end |
---|
99 | |
---|
100 | |
---|
101 | if size(ChannelNames,1) > 0 |
---|
102 | |
---|
103 | % Build MCA handle |
---|
104 | for ii = 1:size(ChannelNames,1) |
---|
105 | ChanName = deblank(ChannelNames(ii,:)); |
---|
106 | |
---|
107 | % Get handle and/or open connection |
---|
108 | hh = mcaisopen(ChanName); |
---|
109 | h(ii,1) = hh(1); |
---|
110 | if ~h(ii,1) |
---|
111 | h(ii,1) = mcaopen(ChanName); |
---|
112 | end |
---|
113 | |
---|
114 | if h(ii,1) == 0 |
---|
115 | error(sprintf('mcaopen error on channel name %s', ChanName)); |
---|
116 | end |
---|
117 | end |
---|
118 | |
---|
119 | |
---|
120 | if strcmpi(DataType, 'String') |
---|
121 | |
---|
122 | error('MCA does not return strings at the moment.'); |
---|
123 | |
---|
124 | if length(t) > 1 |
---|
125 | fprintf(' t vector must be scalar for ''String'' inputs, hence ignored.\n'); |
---|
126 | end |
---|
127 | |
---|
128 | % Only the first sample delay is recognized |
---|
129 | T = t(1) - etime(clock, t0); |
---|
130 | if T > 0 |
---|
131 | pause(T); |
---|
132 | end |
---|
133 | |
---|
134 | % Get the data |
---|
135 | AM = []; |
---|
136 | for k = 1:size(h, 1) |
---|
137 | tmp = mcaget(h(k)); |
---|
138 | |
---|
139 | % MCA timestamps are a separate call |
---|
140 | if nargout >= 3 |
---|
141 | DateNumber = 726834; %datenum('1-Jan-1990'); |
---|
142 | for k = 1:length(h) |
---|
143 | result{1} = mca(60,h(k)); |
---|
144 | day = result{1}(1,1); % Days in seconds |
---|
145 | nsec = result{1}(1,2); % nanoseconds |
---|
146 | |
---|
147 | % The EPICS epoch is 1-Jan-1990 |
---|
148 | DataTime(k,1) = 24*3600*DateNumber + day + sqrt(-1)*nsec; |
---|
149 | end |
---|
150 | end |
---|
151 | AM = strvcat(AM, tmp); |
---|
152 | end |
---|
153 | tout = etime(clock, t0); |
---|
154 | |
---|
155 | |
---|
156 | % Expand the blank channel names |
---|
157 | if ~isempty(iblank) |
---|
158 | AM = strvcat(' ', AM); |
---|
159 | if nargout >= 3 |
---|
160 | DataTime = [NaN+NaN*sqrt(-1); DataTime(iblank:end)]; |
---|
161 | end |
---|
162 | end |
---|
163 | |
---|
164 | % Expand multiple channelnames back to multiple devices |
---|
165 | AM = AM(j,:); |
---|
166 | if nargout >= 3 |
---|
167 | DataTime = DataTime(j,:); |
---|
168 | end |
---|
169 | |
---|
170 | return; |
---|
171 | |
---|
172 | elseif strcmpi(DataType, 'Vector') |
---|
173 | |
---|
174 | % Get data |
---|
175 | AM = mcaget(h); |
---|
176 | AM = AM(:); |
---|
177 | if N > 0 |
---|
178 | AM = AM(1:N); |
---|
179 | end |
---|
180 | tout = etime(clock, t0); |
---|
181 | |
---|
182 | % MCA timestamps are a separate call |
---|
183 | if nargout >= 3 |
---|
184 | DateNumber = 726834; %datenum('1-Jan-1990'); |
---|
185 | result{1} = mca(60,h); |
---|
186 | day = result{1}(1,1); % Days in seconds |
---|
187 | nsec = result{1}(1,2); % nanoseconds |
---|
188 | |
---|
189 | % The EPICS epoch is 1-Jan-1990 |
---|
190 | DataTime = 24*3600*DateNumber + day + sqrt(-1)*nsec; |
---|
191 | end |
---|
192 | |
---|
193 | elseif any(strcmpi(DataType, {'Matrix','Waveform'})) |
---|
194 | |
---|
195 | % Get data |
---|
196 | for k = 1:size(ChannelNames,1) |
---|
197 | tmp = mcaget(h); |
---|
198 | if N > 0 |
---|
199 | tmp = tmp(1:N); |
---|
200 | end |
---|
201 | |
---|
202 | AM(k,:) = tmp(:)'; |
---|
203 | |
---|
204 | % MCA timestamps are a separate call |
---|
205 | if nargout >= 3 |
---|
206 | DateNumber = 726834; %datenum('1-Jan-1990'); |
---|
207 | result{1} = mca(60,h(k)); |
---|
208 | day = result{1}(1,1); % Days in seconds |
---|
209 | nsec = result{1}(1,2); % nanoseconds |
---|
210 | |
---|
211 | % The EPICS epoch is 1-Jan-1990 |
---|
212 | DataTime(k,1) = 24*3600*DateNumber + day + sqrt(-1)*nsec; |
---|
213 | end |
---|
214 | end |
---|
215 | tout = etime(clock, t0); |
---|
216 | |
---|
217 | else |
---|
218 | |
---|
219 | % Get data |
---|
220 | AM = []; |
---|
221 | ExtraTimeDelay = etime(clock, t0); |
---|
222 | t = t - ExtraTimeDelay; |
---|
223 | for itime = 1:length(t) |
---|
224 | T = t(itime)-etime(clock, t0); |
---|
225 | if T > 0 |
---|
226 | pause(T); |
---|
227 | end |
---|
228 | |
---|
229 | % Get data |
---|
230 | tmp = mcaget(h); |
---|
231 | if N > 0 |
---|
232 | tmp = tmp(:,1:N); |
---|
233 | end |
---|
234 | AM = [AM tmp]; |
---|
235 | tout(1,itime) = etime(clock, t0); |
---|
236 | |
---|
237 | % MCA timestamps are a separate call |
---|
238 | if nargout >= 3 |
---|
239 | DateNumber = 726834; %datenum('1-Jan-1990'); |
---|
240 | for k = 1:length(h) |
---|
241 | result{1} = mca(60,h(k)); |
---|
242 | day = result{1}(1,1); % Days in seconds |
---|
243 | nsec = result{1}(1,2); % nanoseconds |
---|
244 | |
---|
245 | % The EPICS epoch is 1-Jan-1990 |
---|
246 | DataTime(k,1) = 24*3600*DateNumber + day + sqrt(-1)*nsec; |
---|
247 | end |
---|
248 | end |
---|
249 | end |
---|
250 | |
---|
251 | end |
---|
252 | |
---|
253 | else |
---|
254 | |
---|
255 | t1 = clock; |
---|
256 | tout = etime(t1, t0); |
---|
257 | days = datenum(t1(1:3)) - 719529; %datenum('1-Jan-1970'); |
---|
258 | tt = 24*60*60*days + 60*60*t1(4) + 60*t1(5) + t1(6); |
---|
259 | DataTime = fix(tt) + rem(tt,1)*1e9*sqrt(-1); |
---|
260 | |
---|
261 | % Expand multiple channelnames back to multiple devices |
---|
262 | AM = NaN; |
---|
263 | AM = AM(j,:); |
---|
264 | return |
---|
265 | |
---|
266 | end |
---|
267 | |
---|
268 | |
---|
269 | % Expand the blank channel names |
---|
270 | if ~isempty(iblank) |
---|
271 | AM = [NaN*ones(1,size(AM,2)); AM(iblank:end,:)]; |
---|
272 | if nargout >= 3 |
---|
273 | DataTime = [(NaN+NaN*sqrt(-1))*ones(1,size(DataTime,2)); DataTime(iblank:end)]; |
---|
274 | end |
---|
275 | end |
---|
276 | |
---|
277 | |
---|
278 | % Expand multiple channelnames back to multiple devices |
---|
279 | AM = AM(j,:); |
---|
280 | if nargout >= 3 |
---|
281 | DataTime = DataTime(j,:); |
---|
282 | end |
---|
283 | |
---|