MultiArray Handling

A MultiArray is a multidimensional data buffer that is used in the Condition Monitoring Library in combination with the transfer tray. It enables an application to easily exchange multidimensional data between several PLC tasks. During communication between the tasks, no memory is copied, only references to the data buffers are transferred, making communication extremely efficient. Communication requires only a very low overhead with execution times in the microsecond range.

The MultiArray communication ring

The filling (writing of content) and sending (transfer of access rights) of MultiArrays for input or result data streams have the consequence that "free" MultiArrays are constantly required. For this reason, the evaluated MultiArrays are returned as "empty" data containers to the task that filled them. This creates a continuous cycle of MultiArrays, see the diagram in section Parallel processing with Transfer Tray.

Normally, at least three MultiArrays are required per circuit: The first MultiArray "belongs" to the control task and is about to be filled with new data. The process task accesses the second MultiArray and processes it. A third MultiArray must be kept in reserve, so that it is available if the control task has filled the current MultiArray, but remaining oversampling data has to be written into a next MultiArray in exactly this cycle. Therefore, the minimum number is three.

MultiArray Handling 1:

Number of MultiArrays

For safety, four MultiArrays per circuit are recommended as a worst-case requirement. If more than one algorithm accesses the data of a MultiArray, it is recommended to provide an additional MultiArray for each further accessing algorithm.

The number of MultiArrays provided is set via the input parameters nResultBuffers of the function blocks of the Condition Monitoring Library. The default value is 4.

MultiArray Handling 2:

Number of MultiArrays in the communication ring

More than four MultiArrays are only required if the result buffers (= MultiArrays) are to be processed directly by several algorithms. In other words, if more than two analysis modules in the communication ring participate for these results. It is recommended to increase the number of result buffers by one with each additional analysis module. The number of MultiArray buffers used in an asynchronous communication ring can be configured in each analysis function block.

These additional buffers are created and managed internally. They require a certain amount of additional memory in the AMS router.

Basically, the dimension of a MultiArray can be configured separately in terms of length, size and even data type. The parameters together define the shape of the MultiArray for its entire lifecycle.

Note that the internal structure of the MultiArray is automatically managed and does not require any programming. The fatigue life of the MultiArray is the same as that of the application, i.e. from PLC start to PLC stop; the MultiArrays are transferred from one task to another using the so-called transfer tray.

The concept is very flexible. Changing and redistributing the calculation to other tasks and/or CPUs is simple and uncomplicated.

Configuration of MultiArrays

MultiArrays are configured with the ST_MA_MultiArray_InitPars structure. This is part of the Tc3_MultiArray library, which is installed with the Condition Monitoring Setup.

Example configuration of a MultiArray:

cInitSource : ST_MA_MultiArray_InitPars:= ( eTypeCode := eMA_TypeCode_LREAL,
                         nDims := 2,
                         aDimSizes := [cChannels, cBufferLength]);

If the MultiArray is used with the FB_CMA_Source function block, then a configured MultiArray instance (or several) is required by the source instance fbSource. The MultiArray described above has 2 dimensions (nDims = 2, nDims = 1 is also allowed); the size of the dimensions is described with aDimSizes. Accordingly, the described MultiArray is of dimension cChannels x cBufferLength with data type LREAL for each element.
Example of using MultiArrays with FB_CMA_Source:

fbSource : FB_CMA_Source := ( stInitPars := cInitSource,
                  nOwnId := eID_Source,
                  aDestIDs := [eID_Rms],
                  nResultBuffers := 4);

MultiArrays are flexible in terms of data storage management. For example, in the above case, the rows and columns are completely interchangeable. If the dimensions are correctly assigned/identified (as shown in the example below), this has no effect on the results.

Advanced configuration options

As you can see in the example below, FB_CMA_Source (or FB_CMA_Sink, FB_CMA_BufferConverting) provides parameters such as nWorkDim, pStartIndex or nElementsDim. These parameters can be used to:

A combination of these parameters not only guarantees memory optimization, but also guarantees selectivity in multi-channel, multi-task applications. See the example below.

Application scenario

This application scenario is only valid within the TwinCAT Condition Monitoring application area. As mentioned above, the MultiArrays are managed automatically, but they must first be initialized. This is done in the PLC declaration with the help of ST_MA_MultiArray_InitPars and is passed to the FB_CMA_Source instance.

Each algorithm function block transfers its results using the MultiArrays configured with stInitPars. Their shapes are defined with the initialization parameters (see respective explanations of the function blocks), with the exception of FB_CMA_Sink. It is also possible to copy only a part of the MultiArray into a PLC array for further processing or evaluation. This is done with FB_CMA_BufferConverting.

The function blocks have methods with which PLC variables can be written or read in MultiArrays. For more information on the methods and their parameters, see the descriptions of the function blocks.

MultiArray Handling 3:

The FB_CMA_Sink function block does not require any initialization of a MultiArray. The shape of the MultiArrays used by FB_CMA_Sink is specified internally.

Each dimension of a MultiArray, called WorkDim, has an index beginning with 0.

In the case of two-dimensional MultiArrays, the working dimension 0 is normally linked to the number of channels in the Condition Monitoring Library (see "Example configuration of a MultiArray" in the text above)

Examples for handling MultiArrays

For a better understanding of how to use a MultiArray in a Condition Monitoring application, we consider the following case study.

Three signals from an acceleration sensor with an oversampling factor of 10 are recorded, e.g. with two EL3632s. The input data is collected in a MultiArray with the length 1000 and transferred to a function block. In this case it is the function block for calculating the FB_CMA_MomentCoefficients. FB_CMA_MomentCoefficients calculates different statistical parameters of the input data for each channel, depending on the configuration. Our goal is now to configure the MultiArray at the output of the FB_CMA_MomentCoefficient so that only a certain part of the result, for example the mean value and the standard deviation, is output.

The input and output variables are declared and initialized as follows:

cInitSource : ST_CM_MultiArray_InitPars := (eTypeCode := eMA_TypeCode_LREAL,
                        nDims := 2,
                        aDimSizes := [3,1000]);

aBuffer  : ARRAY [1..3] OF ARRAY [1..cOverSamples] OF LREAL;
fbSource : FB_CMA_Source := (stInitPars := cInitSource,
                 nOwnID := eID_Source,
                 aDestIDs := [eID_MomentCoeffs]);
                    
// MultiArray indices begin with 0, not 1!                                  
// aStartIndex := [0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],...               
aStartIndex : ARRAY [1..2] OF UDINT := [0, 1];    
                                   
// Select channels := 1: one, 2: one and two, 3: one, two and three and so on
// Select moments := 0: count, 1: mean, 2: standard deviation, 3: skew, 4: kurtosis
aMomentCoef : ARRAY [1..3, 1..2] OF LREAL;

As shown above, the fbSource gets a MultiArray with 2 dimensions and should pass the data from aBuffer to the FB_CMA_MomentCoefficients after appropriate buffering. As a function of the initialization parameters, you can either save the data:

MultiArray Handling 4:

Because the MultiArray is two-dimensional, this is done by calling the Input2D() method.

fbSource.Input2D(pDataIn := ADR(aBuffer),
         nDataInSize := SIZEOF(aBuffer), 
         eElementType := eMA_TypeCode_LREAL,
         nWorkDim0 := 0, (* aBuffer stores channels across first dim*)
         nWorkDim1 := 1, (* aBuffer stores samples across second dim*)
         pStartIndex := 0,
         nOptionPars := 0 );

Let's go through this method call step by step:

All the above settings completely configure the MultiArray to store the channels along its first dimension (rows) and the sampled values along its second dimension (columns) up to the length cBufferLength.

Similarly, a FB_CMA_Sink instance can write the contents of the MultiArray to the local PLC variable aMomentCoef.

fbSink.Output2D(pDataOut := ADR(aMomentCoef),
           nDataOutSize := SIZEOF(aMomentCoef),
           eElementType := E_MA_ElementTypeCode.eMA_TypeCode_LREAL,
           nWorkDim0 := 0,        (* aMomentCoef stores channels across first dim *)
           nWorkDim1 := 1,        (* aMomentCoef stores moments across second dim *)
           nElementsDim0 := 3,    (* aMomentCoef stores all 3 channels *)
           nElementsDim1 := 2,    (* aMomentCoef stores mean and deviation*)
           pStartIndex := ADR(aStartIndex), 
           nOptionPars := 0);

Again, let's go through this method call step by step:

MultiArray Handling 5:

In the configuration shown, the Output2D() method will only copy one segment of the MultiArray into the PLC variable aMomentCoef. The segment to be copied is configured with the parameters nWorkDim0, nWorkDim1, nElementsDim0, nElementsDim1 and pStartIndex as explained above.