Files
mocha/example.m
2021-03-22 12:41:12 +01:00

1069 lines
42 KiB
Matlab
Raw Blame History

%function example()
%mocha
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Jan Chrin, Paul Scherrer Institut
% March 2017
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (1) Establishing connections to EPICS Process Variables (PVs)
% (2) Simple single channel operations (and the PVData Object)
% (3) Understanding the Status Error Code / MATLAB Exceptions
% (4) Waveforms and Arrays
% (5) Handling Enumerated Types
% (6) Multiple scalar operations, i.e., operations on several PVs with scalar values
% (7) Multiple cell array ('compound') operations, i.e., on several PVS with scalar/vector values
% (8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors
% (9) Asynchronous interactions and retrieving data from Cache
% (10) Synchronous group operations, also with externally defined groups
% (11) Monitors, either with or without user supplied callbacks (in essence, matlab scripts)
% (12) Control system parameters, i.e., operating limits, engineerimg units
% (13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc.
% (14) Setting timeouts for set/get operations
% (15) Setting synchronous group timeouts for set/get operations
% (16) Special Methods, e.g., setAndGet, setAndMatch
% (17:END) Gracefully terminate CAFE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the mocha release is accompanied with the long established mca scripts
% which have been accordingly 'mocha-fied',
% i.e., the 'mocha' interface is used from within the mca scripts
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Test channels
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% To run this test script, first create 5 soft channels of the given class.
% pv(1:2) are scalar numerics, pv(3) is a wf, pv(4) is a mbbo record (enum),
% pv(5) is a dbr_string_t, pv(6) does not exist
pv={'ARIDI-BPM-01LE:X-AVG','ARIDI-BPM-01LE:Y-AVG','ARIDI-BPM-01LE:WF-INT-2','ARIDI-BPM-01LE:SET-ENABLE','ARIDI-BPM-01LE:SET-ENABLE.DESC','PV-JOKE'};
%
% MATLAB's Run and Advance utility will run each of these 17 sections at the user's prompt.
% To create an executable:
% uncomment function example in first line and run the mcc compiler
% mcc -m example
% ./run_example.sh $MATLAB_DIR
% The following monitorAction.m is included in the movcha release for test purposes.
% Otherwise please copy and place it in your local directory from where matlab
% will be started. This file can optionally be used as a callback function for monitors.
%monitorAction.m
%{
function varargout = monitorAction(varargin)
disp('monitorAction called for:');
pvName=mocha('getPVFromHandle', varargin{1});
disp(pvName);
X=['Handle =', num2str(varargin{1})];
disp(X);
%[varargout{1} varargout{2}] = mocha ('getCache', varargin{1});
[var1,var2]=mocha ('getCache', varargin{1});
[s,t]=mocha('getStatus', varargin{1});
%X=['Value=', num2str(varargout{1}), ' Status=', num2str(s), ' [',t(1), ' ', t(2),']'];
X=['Value =', num2str(var1)];
Y=['Status=', num2str(s)];
disp(X)
disp(Y)
disp([t(1),t(2)])
%}
%%%%
mocha('test'); %test if mocha MEX-file is accessible
mocha('version'); %lists mocha/cafe version
%mocha('show'); %lists all available mocha methods
%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (1) Establishing connections to EPICS Process Variables (PVs)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Explicitly opening channels is good practice even if only optional
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (1) Establishing connections to EPICS Process Variables (PVs) ');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%returns an array of handles (object references)
%hpv=mocha('open',pv);
%When executing the 'open' message as above, the default behaviour
%is for each 'open' to wait for a maximum amount of time, given by:
openTime = mocha ('getOpenWaitTime'); %currently 0.4s
%The 'open' wait time can, however, be configured by the user as follows:
mocha ('setOpenWaitTime', 0.2); %set to 0.2s
mocha ('setOpenWaitTime'); %reset to default (0.4s)
%The above shoud be set before the mocha 'open' method is executed
%If opening numerous channels, however, better to do this with a single message.
%This is done as shown here:
mocha('openPrepare');
hpv=mocha('open',pv);
% and more mocha 'open' messages would follow here...
% Finally send the messages and wait for a maximum of 0.2s for connections to complete
mocha('openNowAndWait', 0.2)
%There are a number of ways to extract information on the created handles
%print all handles whether connected or not
mocha('printHandles');
%Array of handles and matching PVnames
[handles, pvs] = mocha ('getHandles');
[handles, pvs] = mocha ('getConnectedHandles');
[handles, pvs] = mocha ('getDisconnectedHandles');
%Array of handles, matching PVnames and connection states
[handles, pvs, states] = mocha ('getHandleStates');
%print information on disconnected channels
if (~mocha('allConnected'))
mocha('printDisconnectedHandles');
%or
[handles, pvs] = mocha ('getDisconnectedHandles');
for n =1 : length(handles)
X=['Handle=', num2str(handles(n)), 'PV=',pvs(n)];
disp(X);
end
end
%To check on the connection state of a single channel
logicValue=mocha('isConnected', pv(1)); %by pvName
logicValue=mocha('isConnected', hpv(1)); %byHandle
%Handle and PV Mapping
%Retrieve handle for a given PV
handle = mocha ('getHandleFromPV', pv(1));
pvName = mocha ('getPVFromHandle', hpv(1));
%%
%or run the MATLAB script (which also shows latest values)
disp('If val is NaN then a harmless warning will appear from struct2table');
%Warning: Out of range or non-integer values truncated during
%conversion to character
pvtable
%Channels may be closed when the application no longer needs them
%mocha ('close', pv(1)); %close given channel
%mocha ('close', pv); %close given channels
%Close all chanels and release all ca resources before exiting MATLAN
%mocha ('close');
%END (1) Establishing connections to EPICS Process Variables (PVs)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(2) Simple single channel operations (and the PVData Object)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (2) Simple single channel operations ');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%Now perform some get/set operations
%Mocha operations will accept either a pv name or the pv handle
%(as returned from the mocha 'open' method) as the 2nd input argument
%GET value
%by pvName; value (scalar or vector) returned in native data type
[value, status]= mocha ('get', pv(1));
%by Handle; value (scalar or vector) returned in native data type
[value, status]= mocha ('get', hpv(1));
%by pvName; value (scalar or vector) returned as a MATLAB double
[value, status]= mocha ('get', pv(1), 'uint8');
%by pvName; value (scalar or vector) returned as a MATLAB uint8 type
[value, status]= mocha ('get', pv(1), 'double');
%SET
%value (scalar or vector) can be in any MATLAB data type
[status] = mocha('set', pv(1), value);
%Single channel operations that return data, alarms and timestamps
%pvData struct returned; pvData.val has the native data type
pvData = mocha ('getPV', pv(1));
%pvData struct returned; pvData.val has the double data type
disp('Displaying pvdata struct');
pvData = mocha ('getPV', pv(1), 'double')
pvData.val;
pvData.status; % int32
pvData.alarmStatus; %int16
pvData.alarmSeverity; %int16
pvData.ts; %[year, month, day, hour, min, sec, nsec]
%Other ways to retrieve alarms and timestamps from cache following a 'get'
ts=mocha('getTimestamp', pv(1));
[ets]=mocha('getETS', pv(1)) % [secPastEpoch, nsec]
[alarmStatSev] = mocha ('getAlarm', pv(1)); %[alarmStatus, alarmSeverity]
[alarmStatSev] = mocha ('getAlarmAsString', pv(1)) %[alarmStatus, alarmSeverity]
%The string equivalenty of an integer alarmStatus/Severity
%may be gotten at any time as follows;
alarmStatus_str = mocha('alarmStatusAsString', pvData.alarmStatus);
alarmSeverity_str = mocha('alarmSeverityAsString', pvData.alarmSeverity);
%Alarm conditions and alarm severities can be listed as follows:
disp('Listing all possible alarm condition value/name pairs')
[strVal, intVal] = mocha('alarmStatusList');
for n = 1:length(intVal)
[intVal(n), strVal(n)]
end
disp('Listing all possible alarm severity value/name pairs')
[strVal, intVal] = mocha('alarmSeverityList');
for n = 1:length(intVal)
[intVal(n), strVal(n)]
end
%An extended (x) struct holding supplementary data may also be retrieved:
disp('Displaying extended pvdata struct');
pvStruct = mocha ('getStruct', pv(1))
pvStruct.handle; %uint32
pvStruct.pv; %char
pvStruct.val;
pvStruct.status; %int32
pvStruct.status_str; %char
pvStruct.alarmStatus; %int16
pvStruct.alarmStatus_str; %char
pvStruct.alarmSeverity; %int16
pvStruct.alarmSeverity_str; %char
pvStruct.ts; %[year, month, day, hour, min, sec, nsec]
pvStruct.epicsTS; %[secPastEpoch, nsec]
%END (2) Simple single channel operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(3) Understanding the Status Error Code / MATLAB Exceptions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (3) Understanding the Status Error Code / MATLAB Exceptions');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
[value, status]= mocha ('get', pv(1));
pvData = mocha ('getPV', pv(1));
status = pvData.status;
%A Status Code of 1 represents a normal completion
%Status Codes <=480 are generated by the native ca library
%Status Codes >=600 are generated by the underlying CAFE library
%A status code is paired to an enumerated name
statusAsString=mocha ('statusAsString', status);
%The following returns the enumerated name
%preceded with severity (SUCCESS, INFO, WARNING, ERROR)
statusText = mocha ('statusAsText', status);
%Further information concerning the code
statusInfo = mocha ('statusInfo', status);
%Another way to retrieve the full status information w.r.t. the previous
%operation on a given handle is
[status, statusArray] = mocha ('getStatus', pv(1))
%status is the integer status code
%statusArray[1] returns same data as statusText above
%statusArray[2] returns same data as statusInfo above
%Status code/name pairs can be listed as follows:
disp('Listing all possible status code value/name pairs')
[strVal, intVal] = mocha('statusList');
%Alarm conditions and alarm severities can be listed as follows:
%disp('Listing all possible alarm condition value/name pairs')
[strVal, intVal] = mocha('alarmStatusList');
for n = 1:length(intVal)
[intVal(n), strVal(n)]; %not printed to window
end
%Rather than have to check on the status codes, CAFE MATLAB exceptions can be
%enabled (mocha default is to have exceptions dis-enabled)
mocha ('withExceptions', true) %enables MATLAB exceptions for single channel operations
try
[val, status] = mocha ('get', pv(6)) %pv(6) is dis-connected as channel does not exist
catch ME
ME
%A MATLAB exception, MException, comprises the 'identifier' and 'message' properties
if strfind(ME.identifier,'CAFE_WARN')
warning(ME.message);
elseif strfind(ME.identifier, 'CAFE_INFO')
disp(ME.message);
elseif strfind(ME.identifer,'CAFE_ERROR')
error(ME.message);
else
disp(ME.message);
end
end
mocha ('withExceptions', false) %dis-enable MATLAB exceptions for single channel operations
%END (3) Simple single channel operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(4) Waveforms and Arrays
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (4) Waveforms and Arrays');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
[value, status] = mocha ('get', pv(3)); %Returns all elements of the wf
[pvdata] = mocha ('getPV', pv(3)); %Returns all elements of the wf in pvdata.val
%The default behaviour is for all elements of the wf to be read out and
%presented. However, this number together with an offset can be configured
%by the user
nelemWF = mocha('setNelem', pv(3), 20);
offsetWF= mocha('setOffset',pv(3), 12);
%nelemWF = mocha('setNelem', pv(3)); %sets to native value
%offsetWF= mocha('setOffset',pv(3), 0); %but remember to set offset to 0 too!
%The subsequent method then returns an array (value) of length 20,
%containing data from the 13th until the 32nd element of the waveform.
[value, status] = mocha ('get', pv(3), 'double')
%END (4) Waveforms and Arrays
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(5) Handling Enumerated Data Types
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (5) Handling Enumerated Data Types');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%Consider pv(4) which is an mbbo record with enumerated value/names
%0/off 1/on 2/{transient state}
%with current value 1, i.e., 'on'
%Default behaviour is to present the value as a string:
[value, status] = mocha ('get', pv(4));
%Hence above method will return a value of 'on'
X=[pv(4), 'has value', value];
disp(X);
%Any MATLAB numberic data type, such as 'int8', 'single' could also be specified
[value, status] = mocha ('get', pv(4), 'uint8');
%Hence above method would return a value of 1
X=[pv(4), 'has value', num2str(value)];
disp(X);
%For set, the input value can be any valid numeric or string;
%It will be internally converted to an unsigned short before being sent to the IOC.
[status] = mocha ('set', pv(4), 0); % will send the value 0, i.e. 'off'
[status] = mocha ('set', pv(4), 'off'); % will send the value 0, being the value euivalent of the enumerated name
[status] = mocha ('set', pv(4), '0'); %will send an unsigned short value of 0
[status] = mocha ('set', pv(4), 'anything'); %will complain that this is not a valid enumerated name
[status] = mocha ('set', pv(4), '0anything'); %will convert this to an unsigned short value of 0
%END (5) Handling Enumerated Data Types
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(6) Multiple Scalar Operations, i.e., operations on several PVs with scalar values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (6) Multiple Scalar Operations, i.e., operations on several PVs with scalar values');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%GET:
%Messages are collected and transmitted with one single method invocation
%If Handle/PV points to a WF, only the 1st element of the WF is returned.
%If a data type for the retrieved data is not specified, then the native type
%of the first handle/pv is selected, here (pv(1))
pvInput=[pv(1:3),pv(6)];
[val, isAllOK, s] = mocha ('getScalarArray', pvInput, 'double');
% Alternatively
% [val, isAllOK, s] = mocha ('get', pvInput, 'double');
% may be called;
% mocha('getScalarArray') will then be called internally
[val, isAllOK, s] = mocha ('get', pvInput, 'double')
if isAllOK ~= 1
for n=1:length(s)
if s(n) ~= 1
[codes,ctext]=mocha('getStatus', pvInput(n));
X=['GET: Error in Elem:', num2str(n), pvInput(n), ':'];
Y=[num2str(codes), ctext(1)];
disp(X); disp(Y);
end
end
end
%SET:
val(1)=val(1)+0.001;
[isAllOK, s] = mocha ('setScalarArray', pvInput, val);
% Alternatively
% [isAllOK, s] = mocha ('set', pvInput, val);
% may be called;
% mocha('setScalarArray') will then be called internally
[isAllOK, s] = mocha ('set', pvInput, val);
if isAllOK ~= 1
for n=1:length(s)
if s(n) ~= 1
[codes,ctext]=mocha('getStatus', pvInput(n));
X=['SET: Error in Elem.:', num2str(n), pvInput(n), ':'];
Y=[num2str(codes), ctext(1)];
disp(X); disp(Y);
end
end
end
%END (6) Multiple Scalar Operations, i.e., operations on several PVs with scalar values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(7) Multiple cell array ('compound') operations, i.e., on several PVS with scalar/vector values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (7) Multiple cell array ("compound") operations, i.e., on several PVS with scalar/vector values');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%GET
%Note the use of the handles; one could equally use the PV array, pv
[val, isAllOK, s] = mocha ('getCellArray', hpv);
%returns a cell array, wherein the elements are of native data type and can be of any size
%SET
val{1}=1.111;
val{2}=2.222;
val{3}=(1:256); %wf
val{4}='on'; %mbbo
[isAllOK, s] = mocha ('set', hpv, val{:});
%Here, the data type of all returned values is defined to be a string
[val, isAllOK, s] = mocha ('getCellArray', hpv, 'string')
%END (7) Multiple Scalar Operations, i.e., operations on several PVs with scalar values
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section (8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%GET
%returns a sequence of pvData structs
%%
[pvData, isAllOK] = mocha ('getPVArray', pv)
disp('Display all pvData.val values and statuses:');
%pvData(i) corresponds to the data returned by pv(i)
{pvData.val}
[pvData.status]
%pvData(1:6).ts %timestamps
%[pvData(1:6).alarmStatus]
%[pvData.alarmSeverity]
%Note: the following method is equivelent to the above
%as it will call getPVArray internally
[pvData, isAllOK] = mocha ('getPV', pv);
%returns a sequence of extended (x) pvData structs
%%[pvStruct, isAllOK] = mocha ('getStructArray', pv)
%pvStruct(i) corresponds to the data returned by pv(i)
%%disp('Display all pvStruct as arrays:');
%%[pvStruct.handle]
%%{pvStruct.pv}
%%{pvStruct.val}
%%[pvStruct.status]
%%{pvStruct.status_str}
%%[pvStruct.alarmStatus]
%%{pvStruct.alarmStatus_str}
%%[pvStruct.alarmSeverity]
%%{pvStruct.alarmSeverity_str}
%%pvStruct.ts
%%pvStruct.epicsTS
%%[pvStruct.alarmSeverity]
%%{pvStruct.alarmSeverity_str}
%pvStruct(1:6).ts %timestamps
%[pvStruct(1:6).alarmStatus]
%% %%%%
%Note: the following method is equivelent to the above
%as it will call getStructArray internally
[pvStruct, isAllOK] = mocha ('getStruct', pv);
%%%%%%%%
disp('Alternatively part data (values, statuses only) could also be retrieved with getCellArray:');
%% %%%%
[val, isAllOK, s] = mocha ('getCellArray', hpv)
%%%%%%%%%%%%%%
%SET -overwrite pvData
pvData(1).val =0.2345;
pvData(2).val =2.6789;
pvData(3).val =(256:512);
pvData(4).val = 'off';
%%%%%%
[isAllOK, s] = mocha ('set', hpv, pvData(1:6).val);
%%%%%%%%%%%%%%%%%%%
%Check values were set
[val, isAllOK, s] = mocha ('getCellArray', hpv)
%%%%%%%%%
disp('Recall we had previously set an offset for wf of value:');
offset=mocha('getOffset',hpv(3))
disp('Setting new offset/nelem for wf has value:');
offset=mocha('setOffset',hpv(3),0)
%nelem =mocha('setNelem',hpv(3), mocha('getnelemnative',hpv(3)) )
nelem =mocha('setNelem',hpv(3),10);
disp('Note that setNelem and setOffset are for readback of waveform only');
%SET
%Another way to set
dd{1} = 3.33;
dd{2} = uint8(4);
dd{3} = [1,2,3,4,5,6,7,8,9,10,11,12,2.6,2.7,2.8,2.9,3.0,3.1,3.2,3.3]; %(2:257); %
dd{4} = 'off';
dd{5} = 'Enable or Dis-enable BPM';
dd{6} = 0;
[isAllOK,s] = mocha ('setMany', pv(1:5), dd{1:5});
%or this will call setMany
dd{4} = 'on';
[isAllOK,s] = mocha ('set', pv(1:5), dd{1:5});
%Check values were set
[pvData, isAllOK] = mocha ('getPVArray', hpv(1:5));
{pvData.val}
pvData(3).val
%END (8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(9) Asynchronous interactions and retrieving data from Cache
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(9) Asynchronous interactions and retrieving data from Cache');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%GET
%Messages are aggregated until the user decides when to send the messages
%Note that there is no variable for the return data! This will be retrieved
%later through the getCache method
[s] = mocha ('getAsyn', pv(1));
[isAllOK,s] = mocha ('getAsyn', pv(2:5));
%Now send the messages
mocha('sendNow'); %optional; otherwise 'getCache' will do the send
%or mocha('caFlush');
%getCache methods are used to retrieve the data;
%methods will wait until any outstanding callback is complete or a timeout is reached
[val, s] = mocha('getCache', pv(1), 'double');
pvData = mocha('getCache', pv(2));
%get several pvs in one call
[val, isAllOK, s] = mocha('getScalarArrayCache', pv, 'string');
%or getCache will call getScalarArrayCache
[val, isAllOK, s] = mocha('getCache', pv, 'string')
[val, isAllOK, s] = mocha('getCellArrayCache', pv)
[pvData, isAllOK] = mocha('getPVArrayCache', pv)
%return extended pvStruct
[pvStruct, isAllOK] = mocha('getStructArrayCache', pv)
%SET
%Set messages are by default asynchronous and non-blocking.
%The user may configure any given handle such that the messages are blocking,
%meaning a subsequent set method will wait until the server has reported back to the client:
%BLOCKING:
mocha('setPutWait', pv); %policy changed to blocking for all handles pv(1:6)
status = mocha ('set', pv(1), 0.1); %blocks, status may return a timeout error
%NON_BLOCKING - this is the default
mocha('setPutNoWait', pv); %policy changed to non-blocking for all handles pv(1:6)
status = mocha ('set', pv(1), 0.2); %blocks, status will never return a timeout error
%Want to be sure the value got written?
disp('Executing setAndGet; Return val should equal input value, i.e., 0.3');
[val, status]= mocha('setAndGet', pv(1), 0.3) %val will be 0.3 on success.
%The above method initiates a set followed immediately by a get.
%The user should be aware that in the event of other applications writing
%to the same epics channel, the possibility exists that this external write
%may occur between the set and subsequent get in the above method.
%The data type of the returned value matches that of the input value.
%AGGREGATING ASYNCHRONOUS SET OPERATIONS - Can be ignored as user case is expected to be uncommon
%If required set methods can also be aggregated before being sent asynchronously over the network
dd{1} = double(3.3);
dd{2} = uint8(4);
dd{3} = [11,12,13,14,15,6,7,8,9,10,11,12,2.6,2.7,2.8,2.9,3.0,3.1,3.2,3.3]; %(2:257); %
dd{4} = 'off';
dd{5} = 'Enable or Dis-enable BPM';
dd{6} = 0;
mocha('setPutPrepare', pv(1:6));
s = mocha ('set', pv(1), dd{1});
s = mocha ('set', pv(2), dd{2});
s = mocha ('set', pv(3), dd{3});
s = mocha ('set', pv(4:5), dd{4:5});
s = mocha ('set', pv(6), dd{6});
mocha('sendNow');
%Note that a subsequent set on the same given channel
%will trigger a 'send' to IOC transaction on the pending set
mocha('setPutPrepare', pv(1:6));
s = mocha ('set', pv(1), dd{1});
s = mocha ('set', pv(1), 0.2); %will first trigger a send of the previous 'set'
[val,s]=mocha('get', pv(1)) %a get method will also initiate a send of all previous messages
%Reset Policy - Remember to reset the policy, e.g., to asynchronous, blocking
mocha('setPutWait', pv);
%or
%Reset Policy - Remember to reset the (default) policy, e.g., to asynchronous, non-blocking, non-aggregating
mocha('setPutNoWait', pv);
%END (9) Asynchronous interactions and retrieving data from Cache
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(10) Synchronous Group Operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(10) Synchronous Group Operations');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%
%Uses the ca_sg functionality which guarantees a set of ca requests have completed, or a timeout is reached
%First define a group; here a simple group of two BPMs
s = mocha('defineGroup', 'gBPM', pv(1:2));
%First define a group; here a collection of non-related pvs
s = mocha('defineGroup', 'gSnapshot', pv(1:5));
%Open a group; optional, otherwise first get/set method will establish the connections
gHandle1 = mocha('openGroup', 'gBPM');
gHandle2 = mocha('openGroup', 'gSnapshot');
%A synchronous group can be regarded as a logical software unity;
%*** A pv within a group will have its own, separate handle ***
%as revealed from within the following command
mocha('printHandles');
%or
[hArray, pvArray]=mocha('getHandles');
%For example, three ca virual circuits have thus been created for pv(1)
%as this pv exists in its own right, within group 'gBPM' and within group 'gSnapshot'
%Likewise two ca virtual circuits have been created for the waveform in pv(3)
%The various handles for the given pv may be configured independently
%e.g. In the following we will set the nelem for pv(3) (hpv(3)) to 6
% and the the nelem for pv(3) within the group 'gSnapshot' to 12
newNelem=mocha('setNelem', pv(3), 6); %corresponds to handle for pv(3)
%set nelements for handle withing group for pv(3) to 12
handlesWithinGroup=mocha('getHandlesWithinGroup', gHandle2);
newNelem=mocha('setNelem', handlesWithinGroup(3), 12); %handlesWithinGroup(3) corresponds to pv(3) in group 'gSnapshot'
disp('pv(3) should have been read with 6 elements:')
[val,s]=mocha('get', pv(3));
val
disp('pv(3) should have been read with 12 elements:')
[val,s]=mocha('get', handlesWithinGroup(3));
val
[pvData1, isAllOK] = mocha('getPVGroup', 'gBPM'); %2nd argument could equally have been the group handle, i.e., gHandle1
[pvData2, isAllOK] = mocha('getPVGroup', gHandle2); %2nd argument could equally have been the group name, i.e., 'gSnapshot'
%To retrieve extended PVData;
[pvStruct, isAllOK] = mocha('getStructGroup', 'gBPM');
%pvData is an array of returned s
pvData2.val
pvData2.status; % int32
pvData2.alarmStatus; %int16
pvData2.alarmSeverity; %int16
pvData2.ts; %[year, month, day, hour, min, sec, nsec]
mocha('get',handlesWithinGroup(3))
pvData2(3).val=(1:256);
[isAllOK,s]=mocha('setGroup', gHandle2, pvData2.val);
%reset to 256
mocha('setNelem', handlesWithinGroup(3), 256)
mocha('get',handlesWithinGroup(3))
%Configuring groups through XML - See documentation/talk for XML format
%Here the test.xml contains a group consistimng of 2 BPMs
mocha('loadXMLGroups', 'test.xml');
%List Groups and group Members
disp('listGroups:');
[groups] = mocha('listGroups')
disp('Show members of group gSnapshot:');
[members]= mocha('listGroupMembers', 'gSnapshot')
disp('Show members of group gTest (as loaded from test.xml):');
[members]= mocha('listGroupMembers', 'gTest')
%This will only CLOSE and remove groups that have already been OPENED!
%%for i =1:length(groups)
%%mocha('closeGroup', groups{i})
%%end
%END (10) Synchronous Group Operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%(11) Monitors, either with or without user supplied callbacks (in essence, matlab scripts)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(11) Monitors, either with or without user supplied callbacks (in essence, matlab scripts');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%Simple Monitors
monitorID = mocha ('monitor', pv(1));
[monitorIDArray, isAllOK, statusArray] = mocha ('monitor', pv(1:6)); %start monitors for several pvs/handles
%Once the monitor is started, data may be retrieved via one of the cache methods
pause(0.1)
[val,s] = mocha('getCache', pv(1)); %Scalar or vector returned in native data type
[val,s] = mocha('getCache', pv(1), 'double'); %Scalar or vector returned as a MATLAB double
[val,s] = mocha('getCache', pv(1), 'uint8'); %Scalar or vector returned as a MATLAB uint8
[pvData] = mocha('getPVCache', pv(1)) %PVData Object returned with pvData.val in native data type
[pvData] = mocha('getPVCache', pv(1), 'single'); %PVData Object returned with pvData.val as a MATLAB float
[pvData] = mocha('getPVCache', pv(1), 'int32'); %PVData Object returned as a MATLAB int32
[pvStruct] = mocha('getStructCache', pv(1)) %Extended (x) mocha closepvData
s = mocha('monitorStop', pv(1), monitorID); %Stop monitor for pv/handle with given monitorID
s = mocha('monitorStop', pv(1)); %Stop all monitors for this pv/handle
s = mocha('monitorStop', pv(1:6)); %Stop all monitors for these pvs/handles
s = mocha('monitorStop'); %Stop all monitors for all pvs/handles
%Monitors with Actions, i,e, callback of MATLAB script
%Need to give the numeric value of the handle as input argument to monitorAction
monAction=['monitorAction(', num2str(hpv(1)), ')'] ;
%The above reads monAction = 'monitorAction(1)'
%Here monitorAction(1) refers to a Matlab Script monitorAction.m
%that takes a single input argument, which is the handle of the monitored channel
monitorID= mocha('monitor',hpv(1),monAction);
%Mulitple monitors with actions:
%monAction2=['monitorAction(', num2str(hpv(2)), ')'] ;
%[monitorID] = mocha('monitor', hpv(1:2), monAction, monAction2);
%The monitorAction.m script will typically retrieve data from Cache as follows:
%[val,status]=mocha ('getCache', varargin{1});
mocha('monitorFlushEvent', pv(1)); %will execute the MATLAB script monitorAction.m if new data has arrived
mocha('monitorFlushEvent'); %will execute all 'actions' for all 'handles' that have received new data
%The above command is used in conjunction with MATLAB timer (as for MCA's mcamontimer.m)
obj.t = timer('TimerFcn', 'mocha(''monitorFlushEvent'')', 'Period', 2.0, 'ExecutionMode', 'fixedSpacing');
%Else if double quotes cannot be used in the above; here's a way around the problem:
%obj.t = timer('TimerFcn', 'mocha(402)', 'Period', 2.0, 'ExecutionMode', 'fixedSpacing');
start(obj.t);
disp ('Callback for monitors for 5 seconds')
for n=1:5
mocha('set', pv(1), n); %See the script be executed
pause(0.5);
end
stop(obj.t);
%END Monitors, either with or without user supplied callbacks (in essence, matlab scripts)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (12) Control system parameters, i.e. operating limits, engineerimg units
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(12) Control system parameters, i.e. operating limits, engineerimg units');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
[ctrlData] = mocha('getCtrl', hpv(1));
%Usually it is sufficient to use the getCtrlCache method
[ctrlData] = mocha('getCtrlCache', hpv(1));
ctrlData
% This is what an output may look like for an ao/ai record
%{
handle: 1
pv: 'ARIDI-BPM-01LE:X-AVG'
val: 3.2000
status: 1
alarmStatus: 0
alarmSeverity: 0
precision: 6
units: 'mm'
noEnumStrings: 0
enumStrings: {1<>0 cell}
upperDisplayLimit: 2
lowerDisplayLimit: -2
upperAlarmLimit: NaN
lowerAlarmLimit: NaN
upperWarningLimit: NaN
lowerWarningLimit: NaN
upperControlLimit: 2
lowerControlLimit: -2
%}
[ctrlData] = mocha('getCtrlCache', hpv(4));
ctrlData
% This is what an output may look like for an mbbo/i record
%{
handle: 2
pv: 'ARIDI-BPM-01LE:SET-ENABLE'
val: 'off'
status: 1
alarmStatus: 0
alarmSeverity: 0
precision: 0
units: ''
noEnumStrings: 3
enumStrings: {'off' 'on' 'monitor'}
upperDisplayLimit: 0
lowerDisplayLimit: 0
upperAlarmLimit: 0
lowerAlarmLimit: 0
upperWarningLimit: 0
lowerWarningLimit: 0
upperControlLimit: 0
lowerControlLimit: 0
%}
%
%END (12) Control system parameters, i.e. operating limits, engineerimg units
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc. ');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
iStruct=mocha('getInfo', pv(1));
iStruct
% This is what an output may look like:
% The members connectFlag, accessRead, and accessWrite are all of MATLAB data type, logical
%{
handle: 1
pv: 'ARIDI-BPM-01LE:X-AVG'
channelID: '0x7f46fc879ae0'
connectFlag: 1
hostName: 'psi-softioc-2.psi.ch:45408'
dataType: 'DBR_DOUBLE'
className: 'ai'
accessRead: 1
accessWrite: 1
nelem: 1
connectionState: 'CA_OP_CONN_UP'
%}
%
%END (13) Retrieve channel medadata, e.g., data type, native no. elements, connection state, read/write access, etc.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (14) Setting timeouts for set/get operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(14) Setting timeouts for set/get operations');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%Timeouts in CAFE are self-regulating and are regulated by
%the following parameters in defines.h in the CAFE livrary
%const bool DEFAULT_SELF_GOVERNING_TIMEOUT = true;
%const unsigned short DEFAULT_PEND_IO_NO_TRIES = 2;
%const double DEFAULT_PEND_IO_INCREMENT_TIME = 2.0;
%Self governing timeouts may be turned off/on for all handles,
%or on a per handle basis
%Make true (default) for handle hpv(1)
mocha('setselfgoverningtimeout', pv(1), true);
%Make true for all handles
mocha('setselfgoverningtimeout', true);
%Timeouts can be set separately for blocking SET/GET operations
%either globally or on a per handle basis
[t] = mocha('getTimeout', pv(1));
%t(1) is timeout for a blocking put operation
%t(2) is timeout for a blocking get operation
%the minimum timeout is returned from among all handles
[t] = mocha('getTimeout');
%t(1) is minimum put timeout from among all handles
%t(2) is minimum get timeout from among all handles
%Timeouts can be set in a number of ways, for all handles
%or on a per handle basis
%set both put and get timeouts for handle hpv(1) to 10.0 seconds
status=mocha('setTimeout', pv(1), 10.0);
%set both put and get timeouts for all handles to 10.0 seconds
status=mocha('setTimeout', 10.0);
%set put timeout for handle hpv(1) to 5.0 seconds
status=mocha('setTimeoutPut', pv(1), 5.0);
%set put timeouts for all handles to 5.0 seconds
status=mocha('setTimeoutPut', 5.0);
%set get timeout for handle hpv(1) to 10.0 seconds
status=mocha('setTimeoutGet', pv(1), 10.0);
%set put timeouts for all handles to 10.0 seconds
status=mocha('setTimeoutGet', 10.0);
%
%END (14) Setting timeouts for set/get operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (15) Setting synchronous group timeouts for set/get operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(15) Setting synchronous group timeouts for set/get operations');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%Self governing timeouts may be turned off/on for all group handles,
%or on a per group handle basis
%Make true (default) for handle hpv(1)
mocha('setSGselfgoverningtimeout', gHandle1, true);
%Make true for all handles
mocha('setSGselfgoverningtimeout', true);
%Timeouts can be set separately for blocking SET/GET operations
%either globally or on a per grop handle basis
[t] = mocha('getSGTimeout',gHandle1);
%t(1) is timeout for a group put operation
%t(2) is timeout for a grop get operation
%the minimum timeout is returned from among all handles
[t] = mocha('getSGTimeout');
%t(1) is minimum put timeout from among all group handles
%t(2) is minimum get timeout from among all group handles
%Timeouts can be set in a number of ways, for all gourp handles
%or on a per grop handle basis
%set both put and get timeouts for group handle, gHandle1, to 10.0 seconds
status=mocha('setSGTimeout', gHandle1, 10.0);
%set both put and get timeouts for all group handles to 10.0 seconds
status=mocha('setSGTimeout', 10.0);
%set put timeout for group handle, gHandle1, to 5.0 seconds
status=mocha('setSGTimeoutPut', gHandle1, 5.0);
%set put timeouts for all group handles to 5.0 seconds
status=mocha('setSGTimeoutPut', 5.0);
%set get timeout for group handle, gHandle1, to 10.0 seconds
status=mocha('setTimeoutGet', gHandle1, 10.0);
%set put timeouts for all group handles to 10.0 seconds
status=mocha('setSGTimeoutGet', 10.0);
%
%END (15) Setting synchronous group timeouts for set/get operations
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (16) Special Methods, e.g., setAndGet
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(16) Special Methods, e.g., setAndGet, setAndMatch ');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%%Several specialized methods exist within the CAFE library,
%%such as setAndMatch which can set a number of PVs to a given value
%%and then examines a given collection of readback PVS.
%%Method verifies whether or not the set/readback values agree within
%%the given tolerance and timeout. Useful for, e.g., ID Gap Scans,
%%Other specialized methods can be exposed to mocha on request
% \brief Set Channels followed by a corresponding readback of Channels
% Method verifies whether or not the set/readback values agree within
% the given tolerance and timeout. ICAFE_NORMAL is returned as soon as
% a match is reached else ECAFE_TIMEOUT_SET_AND_MATCH if timeout.
% \param 1 input: 'setAndMatch'
% \param 2 input: array of handles/pvs to set
% \param 3 input: array of values to set
% \param 4 input: array of handles/ov of readback channel
% \param 5 input: tolerance (+-) margin
% \param 6 input: timeout value; maximum time allowed for agreement to occur
% \param 7 input: printFlag bool, set to true for diagnostics
% \return ECA_NORMAL if all OK else first ECAFE error encountered, else
% ECAFE_TIMEOUT_SET_AND_MATCH if timeout
% For the purpose of this example, the readbnack channels are the same as
% the input channels thus ensuring that a match is found
status=mocha ('setAndMatch', pv(1:2), [1.1,2.2], pv(1:2), 0.01, 5.0, true);
%%Another simple method is the setAndGet Method
%%Set a PV and immediately retrieve its value
%The method (previously presente in (9) above, initiates a set and is
%followed immediately by a get.
%The user should be aware that in the event of other applications writing
%to the same epics channel, the possibility exists that this external write
%may occur between the set and subsequent get within the 'setAndGet'.
setValue=0.4;
[getValue, status] = mocha ('setAndGet', pv(1), setValue)
%The data type of the returned value matches that of the input value.
%
%END (16) Special Methods, e.g., setAndGet
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% (17) Gracefully terminate CAFE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
disp('Section(17) Gracefully terminate CAFE ');
disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
%Stops all monitors (if any)
%Closes all channels
%Releases all CA resources
mocha ('close')
%
%END (17) Gracefully terminate CAFE
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%