%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 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%