Home C++ MATLAB Python Download
 
MATLAB Objects
for EPICS Channel Access
 

mocha is a MATLAB Mex file that provides EPICS connectivity through the CAFE library. mocha provides support for all MATLAB data types, offers synchronous and asynchronous methods for single and groups of channels, and may be compiled on both 32-bit and 64-bit architectures without further modification to the source code. The mocha release is also accompanied with the long established mca scripts that have been suitably mocha-fied, i.e., the underlying channel access calls are made through mocha. This benefits mca users with improved connection management and error reporting.


Preliminaries Basic single channel operations Opening and closing channels Multiple scalar operations Synchronous group operations Control display parameters and channel information Monitors Special methods

Preliminaries

%List the available methods
mocha ('show');

mocha methods invoking data operations take the general form:

[return1, return2, ... ] = mocha (⟨message⟩, ⟨handlePV⟩, ⟨input1⟩, ...)
where
    ⟨message⟩: 'open', 'set', 'get', 'getGroup', 'setGroup', 'monitor', ...
    ⟨handlePV⟩: handle or 'pvName';
               handle is an object reference of numeric value; it is returned by the 'open' operation
For 'set' methods:
    ⟨input1⟩: scalar or vector data input of any MATLAB type
    return1: status
For 'get' methods:
    ⟨input1⟩ is optional and defines the MATLAB ⟨datatype⟩ of return value(s)
    return1: scalar or vector data output
    return2: status

The ⟨datatype⟩ argument (of type 'char'), appearing in data retrieval methods is a placeholder for any of the following supported MATLAB data types:

'single','float','double',
'int8','int16','int32','int64','uint8','uint16','uint32','uint64',
'char','string'

Alternatively, 'native' may be entered, which specifies the data is to be retrieved in the native data type. If ⟨datatype⟩ is not specified, then 'native' is assumed.

A number of data retrieval methods are accompanied by an equivalent 'getCache' method that retrieves the last value from cache. For example, the 'get' method retrieves the current value from the control system while 'getCache' retrieves the last cached value as returned through either a preceding 'get' or 'monitor' operation.

The ⟨handlePV⟩ is a placeholder for either the Process Variable (PV) name, 'pvName', or handle (of type 'uint32'), which is the reference to the PV as returned from the channel 'open' method.

     handle  = mocha ('open',     'pvName' )
[val,status] = mocha ('get',      ⟨handlePV⟩)
[val,status] = mocha ('getCache', ⟨handlePV⟩)

%Tidy up: stop any monitors, close channels, release all CA resources
               mocha ('close')

All data operations on PVs return a status code. A status code of 1 (ICAFE_SUCCESS) represents a successful operation. The status of the last operation can also be retrieved as follows:

[status,statusTextInfo]  = mocha ('getStatus', ⟨handlePV⟩)

statusTextInfo(1) gives the equivalent ENUM text, while statusTextInfo(2) supplies additional information.

The status code can also be intrepreted by invoking the following methods:

%Status code in corresponding ENUM text
statusText = mocha ('statusAsText', status)

%Query meaning of status code
statusInfo = mocha ('statusInfo', status)
 

Basic Single Channel Operations

Data retrieval methods returning a scalar or vector value
%Scalar or vector returned in native data type
[res, status] = mocha ('get', ⟨handlePV⟩);

%Scalar or vector returned as a MATLAB double
[res, status] = mocha ('get', ⟨handlePV⟩, 'double');

%Scalar or vector returned as a MATLAB UINT8
[res, status] = mocha ('get', ⟨handlePV⟩, 'uint8');

%Scalar or vector returned as any one of the requested MATLAB data types;
%⟨datatype⟩ of 'char' or 'string' returns a cell containing an array of characters
[res, status] = mocha ('get', ⟨handlePV⟩, [⟨datatype⟩]);
Retrieving structured data

dstruct (or pvData struct) returned with value array having the MATLAB equivalent of the native data type, unless otherwise specified by ⟨datatype⟩

%dstruct.val holds scalar or vector in native data type
dstruct = mocha ('getStruct', ⟨handlePV⟩);

%dstruct.val holds scalar or vector in specified MATLAB data type
dstruct = mocha ('getStruct', ⟨handlePV⟩, [⟨datatype⟩]);

The struct (dstruct) has members:

dstruct.val ⟨datatype⟩
dstruct.status int32
dstruct.alarmStatus int16
dstruct.alarmSeverity   int16
dstruct.ts uint32 (array of 7 elements)
Timestamps and alarm status/severity values

CAFE differentiates between data acquisition and data presentation. The default is for timestamps and alarm status/severity values to be retrieved, even if they are not immediately presented to the user. Their data are, however, always retrieved and presented in the dstruct returned from the mocha getStruct method. The data may also be retrieved from cache through the following methods, assuming that the policy for their retrieval from the control system has not been otherwise modified from the default.

%Retrieves Alarm Status (res(1)) / Severity (res(2)) in array
alarmStSv = mocha ('getAlarm', ⟨handlePV⟩)

%Retrieves timestamp in uint32 array of length 7: 
%(1)=year, (2)=mon, (3)=day, (4)=hr, (5)=min, (6)=sec, (7)=nsec
timeStamp = mocha ('getTimeStamp', ⟨handlePV⟩)
Setting value(s)

The set method is able to interpret all MATLAB data types and caters for both scalars and vectors, e.g., for writing to waveforms.

%data (scalar or vector) may be in any MATLAB data type
status = mocha ('set', ⟨handlePV⟩, data)
Writing/reading strings to/from waveforms

A waveform with datatype DBR_CHAR can act as a container for strings

% Write string to waveform
status = mocha ('set', ⟨handlePV⟩, '\"Hello\t\World\n\"')
% Retrieve data from waveform, using the 'str' datatype
value = mocha ('get', ⟨handlePV[]⟩, 'str')
% or		
value = mocha ('getWFAsString', ⟨handlePV[]⟩)
 

Opening and Closing Channels

Opening channels

The mocha 'open' method creates the Channel Access (CA) virtual circuit and returns a handle (or handles) to the given PV(s). The following methods will wait for a default time period to establish a connection. Should the channel remain disconnected after this time, then the handle will be automatically activated on the channel's eventual connection. Note that it is not essential to explicitly invoke these 'open' methods, although it would be good practise to do so. They will otherwise be called internally by cafe at the time of the first data access operation.

If there are multiple invocations of cafe.open, it would be more efficient and less of a time sink, to first prepare the messages before flushing the message buffer once at the end.

%Opening several channels with a single call
pvArray= {'pvName1','pvName2','pvName3','pvName4'}

mocha ('openPrepare')
handle = mocha ('open', 'pvName')
hArray = mocha ('open', pvArray)
mocha ('openNowAndWait',  timeout)

%Connection state of handle(s), boolean returned
 isConnected = mocha ('isConnected', ⟨handlePV⟩)
allConnected = mocha ('allConnected')

%Display information on handles
mocha ('printHandle', ⟨handlePV⟩) %prints info for handle, h(1)
mocha ('printHandles') %prints info for all handles
mocha ('printDisconnectedHandles')

%returns an array of handles, hArray, and their associated PVs, pvArray
[hArray, pvArray] = mocha ('getDisconnectedHandles')
Closing channels
# Close connection to a single channel, referenced by either handle or PV name
mocha ('close', ⟨handlePV⟩)
# Close connection to all channels, and release all CA resources
mocha ('close')
 

Multiple Scalar and Compound Operations

Multiple scalar operations

Operations to set/get a MATLAB array of n scalar values to/from n PVs. Should one of the PVs be a waveform (or other multi-element record), then the get operation retrieves only the first element. The get operation returns a MATLAB array whose data type defaults to the native data type of the first element, unless otherwise specified by ⟨datatype⟩. statusArray holds the status of the corresponding individual handles. isALLOK is 1 if all status replies are 1, else the error code of the first failing handle is returned. [⟨handlePV⟩] may be an array of handles or a cell of process variables.

[valueArray, isAllOK, statusArray] = mocha ('getScalarArray', [⟨handlePV⟩], [⟨datatype⟩])
[            isAllOK, statusArray] = mocha ('setScalarArray', [⟨handlePV⟩], valueArray)
Multiple compound operations
[structArray, isAllOK] = mocha ('getStructArray', [⟨handlePV⟩], [⟨datatype⟩])
[structArray, isAllOK] = mocha ('setStructArray', [⟨handlePV⟩], [ structArray.val])
 

Synchronous Group Operations

The synchronous group operations make use of use the ca_sg functionality which guarantees a set of ca requests have completed or a timeout is reached. A synchronous group may be regarded as a logical software unity whose members have their own unique handle.

Defining and opening groups

A group is comprised of a collection (MATLAB cell) of process variables (PVNames) and is identified by its group name.

status = mocha ('defineGroup','groupName', PVNames);

A synchronous group may, optionally, be specifically opened to return a group handle. Otherwise first get/set group method will establish the connections.

[gHandle] = mocha ('openGroup', 'groupName');
Retrieving data from groups

The second argument to a 'getGroup' or 'setGroup' method may be the group handle or group name. An array of pvData structs is returned.

[pvData, isAllOK] = mocha ('getGroup', ⟨gHandleName⟩);
Timeouts in synchronous group interactions

A synchronous group acts as a single logical software entity, a consequence of which is that a timeout on a group operation is unable to inform on the offending channel(s), consequently rendering the data returned in 'getGroup' operations unreliable. To oversome this deficiency, in the event of such a timeout, a multiple channel transaction is autonomously invoked adn the resulting data is repackaged into the pvData object. In this way, data integretity and error reporting are ensured for each individual channel within the group. Indeed use of this latter method directly may be preferred by some users over the synchronous approach.

Setting data to groups
pvData(1).val=0.01; % Overwrite the pvData(1).val that was returned from 'getGroup' 
inputData{1}=1.1; % No. of input parameters must equal the number of members
...
[isAllOK, s] = mocha ('setGroup', ⟨gHandleName⟩, pvData.val);
[isAllOK, s] = mocha ('setGroup', ⟨gHandleName⟩, inputData{:}

Group members may be configured externally through XML configuration files. The minimal syntax required to configure a group is show.

  ⟨cafe:group id="gBPM"⟩
	⟨cafe:member⟩ ⟨cafe:name⟩ PV-NAME-1 ⟨/cafe:name⟩ ⟨/cafe:member⟩  
	⟨cafe:member⟩ ⟨cafe:name⟩ PV-NAME-2 ⟨/cafe:name⟩ ⟨/cafe:member⟩  
	...
⟨/cafe:group⟩  	 
Configuration of groups through XML

Group may be loaded from XML configuration files as shown. A list of all the defined groups and their members may be extracted.

status         = mocha ('loadXMLgroups', 'fileName.xml'); 
[groupNames]   = mocha ('listGroups'); 
[groupMembers] = mocha ('listGroupMembers', 'groupName');

Using groups in a non-synchronous manner

Data transactions involving group members may also be instigated in the usual multi-channel manner.

status         = mocha ('defineGroup','groupName', PVNames);
[groupMembers] = mocha ('listGroupMembers', 'groupName');
[handles]      = mocha ('open', groupMembers); 
[pvData]       = mocha ('getPV', [⟨handlePV⟩]); 

 

Control Display Parameters and Channel Information

Retrieving control system display data

pvctrl returned with value array having the MATLAB equivalent of the native data type, unless otherwise specified by ⟨datatype⟩. However, it is usually sufficent to use the getCtrlCache method in order to retrieve control parameters as these data can typically be assumed to be static.

%pvctrl.val holds scalar or vector in native data type
pvctrl = mocha ('getCtrl', ⟨handlePV⟩, [⟨datatype⟩]);
pvctrl = mocha ('getCtrlCache', ⟨handlePV⟩,  [⟨datatype⟩]);

The struct (pvctrl) has members:

pvctrl.val ⟨datatype⟩
pvctrl.status int32
pvctrl.alarmStatus int16
pvctrl.alarmSeverity   int16
pvctrl.precision uint16
pvctrl.units char
pvctrl.noEnumStrings uint16
pvctrl.enumStrings   cell{char,char,..}
pvctrl.upperDisplayLimit double
pvctrl.lowerDisplayLimit double
pvctrl.upperAlarmLimit double
pvctrl.lowerAlarmLimit   double
pvctrl.upperWarningLimit double
pvctrl.lowerWarningLimit double
pvctrl.upperControlLimit double
pvctrl.lowerControlLimit   double
Retrieving channel information

Information pertaining to the state of the channel and its access rights, etc., can be obtained through the following method invocation.

pvinfo = mocha ('getInfo', ⟨handlePV⟩);

The struct (pvinfo) has members:

pvinfo.handle uint32
pvinfo.pv char
pvinfo.channelID char
pvinfo.connectFlag   logical
pvinfo.hostName char
pvinfo.dataType char
pvinfo.className char
pvinfo.accessRead   logical
pvinfo.accessWrite logical
pvinfo.nelem uint32
pvinfo.connectionState char
 

Monitors

Initiating a simple monitor

A simple monitor, without a user-supplied callback function, is started as follows. A monitorID is returned. The expectation is that normally only one monitor per channel is started. CAFE, partly to prevent possible (unintentional) misuse, will not allow more than four (configurable).

monitorID = mocha ('monitor', ⟨handlePV⟩);

The current value may then be retrieved from cache in any meaningful datatype.

[val, status] = mocha ('getCache', ⟨handlePV⟩, [⟨datatype⟩]);
Initiating a monitor with a user-supplied callback (or 'action')

Monitors may be started with an optional user-supplied 'action'.

monitorID = mocha ('monitor', ⟨handlePV⟩, 'action');

The 'action' is carried out upon execution of a 'monitorFlushEvent' method.

% Flush 'action' for a given handle/pv 
mocha ('monitorFlushEvent', ⟨handlePV⟩);
% Flush 'action' for all events for all handles/pvs 
mocha ('monitorFlushEvent');

An 'action' can be, e.g., 'd=mocha("getCache",h1)' but it is more useful to run a MATLAB script that, e.g., retrieves data from cache and posts it to a widget. The procedure is typically used in conjunction with MATLAB timer that will flush out any outstanding updated values.

obj.t=timer('TimerFcn',
        'mocha(''monitorFlushEvent'')','Period',2.0,'ExecutionMode','fixedSpacing');
Stopping a monitor
% Stop a specific monitor (monitorID) for a given handle/pv 
status = mocha ('monitorStop', ⟨handlePV⟩, monitorID);
% Stop all monitors for a given handle/pv 
status = mocha ('monitorStop', ⟨handlePV⟩);
% Stop all monitors for all handles
status = mocha ('monitorStop');