Handling the warnings for a MotoLogix system.
MotoLogix warnings are handled quite differently than MotoLogix alarms.
There is no variable in the data packet which tells the amount of active
warnings. Instead, we need to poll for warnings using MLxGetMessageDetail
.
That function reads the information as strings (in the active pendant language).
The warning information is stored in an array
(see MceWarningsIO
).
This function uses a state machine:
nSmReadWarnings
- getting the warning information from the controller
With polling it is important to find a balance between quick readings (of new warning data) and not holding up other (more important) MotoLogix commands:
- The polling time can be adjusted to your setup and demands
- The polling automatically slows down by factor five under certain conditions
Usage
MceWarnings
instance.Create the (global) variables for the interface data. These are also used for connecting to an HMI.
stWarnings : ARRAY [0..GVL.MLX_UBOUND] OF MceWarningsIO; // data for alarm handling of a MotoLogix system
Create the instances:
fbMceWarnings : ARRAY [0..GVL.MLX_UBOUND] OF MceWarnings;
Set the poll interval:
GVL.stWarnings[0].tPollInterval := ...;
Call the instances in a loop:
// function call
FOR i := 0 TO GVL.MLX_UBOUND DO
fbWarnings[i](
io := GVL.stWarnings[i],
MLX := GVL.stMLX[i]);
END_FOR;
Map all relevant outputs (see MceWarningsIO
)
to your HMI:
// this is just a portion of the relevant signals
... := GVL.stWarnings[0].aWarnings;
Version history
0.3.0
Changes
- fix number of warnings
show full history
0.2.0
Changes
- FB names according style guide
0.1.0
Changes
- initial version
Overview
kind | name | type | default | comment |
---|---|---|---|---|
in_out | io | MceWarningsIO | interface data | |
in_out | MLX | MLxData | MotoLogix shared memory variable |
Details
Interface data for this function.
Check the data type for more information.
MLX
MLxData
The MotoLogix variable which acts as the shared memory for a MotoLogix system.
Check the YaskawaMLx library for more information.
Source code
Declarations
(*Reading warnings*)
FUNCTION_BLOCK MceWarnings
(*
* -----------------------------------------------------------------------------
* Name : MceWarnings
* Version : 0.3.0
* Date : 2022-03-02
* Author : deGroot
* Family : YaskawaMce
* Organisation : github.com/YaskawaEurope/mlx-examples
*
* -----------------------------------------------------------------------------
* Reading warnings
* -----------------------------------------------------------------------------
*)
VAR_IN_OUT
io : MceWarningsIO; (*interface data*)
MLX : MLxData; (*MotoLogix shared memory variable*)
END_VAR
VAR
fbGetMessageDetail : MLxGetMessageDetail;
fbPollInterval : TON; (*polling delay*)
nIndex : USINT; (*index for reading warnings*)
aWarningBuffer : ARRAY [0..GVL.WARNINGS_UBOUND] OF STRING[162]; (*buffer of received robot warnings*)
END_VAR
Logic
// -----------------------------------------------------------------------------
// init
// -----------------------------------------------------------------------------
io.bError := FALSE;
fbGetMessageDetail.Enable := FALSE;
fbPollInterval.IN := FALSE;
// -----------------------------------------------------------------------------
// poll interval (allow fast readings only in some system states)
// -----------------------------------------------------------------------------
CASE mlx.SystemState OF
6,
8,
12,
13:
fbPollInterval.PT := io.tPollInterval;
ELSE
fbPollInterval.PT := (5 * io.tPollInterval);
END_CASE;
IF NOT MLX.Signals.RemoteMode THEN
fbPollInterval.PT := io.tPollInterval;
END_IF;
// -----------------------------------------------------------------------------
// State machine 1: read warnings
// -----------------------------------------------------------------------------
CASE io.nSmReadWarnings OF
// -------------------------------------
// idle
// -------------------------------------
0:
IF MLX.Signals.MLXGatewayConnected THEN
// init
nIndex := 0;
MEMUtils.MemSet(
pbyBuffer := ADR(aWarningBuffer),
byValue := 0,
dwSize := SIZEOF(aWarningBuffer));
io.nSmReadWarnings := 10;
ELSE
// clear old data
io.nWarnings := 0;
MEMUtils.MemSet(
pbyBuffer := ADR(io.aWarnings),
byValue := 0,
dwSize := SIZEOF(io.aWarnings));
END_IF;
// -------------------------------------
// read warning with MLxGetMessageDetail
// -------------------------------------
10:
fbGetMessageDetail.Enable := TRUE;
fbPollInterval.IN := TRUE;
IF fbGetMessageDetail.Sts_EN AND fbGetMessageDetail.Sts_DN THEN
IF fbGetMessageDetail.Sts_ER THEN
io.nErrorCode := 1000 + io.nSmReadWarnings;
io.nSmReadWarnings := 99;
ELSE
IF (fbGetMessageDetail.MessageDetail.ExtendedDescription1 <> '') THEN
// store warning in buffer
nIndex := LIMIT(0, nIndex, GVL.WARNINGS_UBOUND);
aWarningBuffer[nIndex] :=
CONCAT(
STR1 := fbGetMessageDetail.MessageDetail.ExtendedDescription1,
STR2 := fbGetMessageDetail.MessageDetail.ExtendedDescription2);
nIndex := nIndex + 1;
END_IF;
// the errorNumber returns the "warning slot number" (0..9) so let's
// use it to detect when the polling sequence is complete
IF (fbGetMessageDetail.MessageDetail.errorNumber < 9 ) THEN
io.nSmReadWarnings := 20;
ELSE;
io.nSmReadWarnings := 30;
END_IF;
END_IF;
END_IF;
IF NOT MLX.Signals.MLXGatewayConnected THEN
io.nSmReadWarnings := 0;
END_IF;
// -------------------------------------
// poll delay
// -------------------------------------
20:
fbPollInterval.IN := TRUE;
IF fbPollInterval.Q THEN
fbPollInterval.IN := FALSE;
io.nSmReadWarnings := 10;
END_IF;
// -------------------------------------
// poll sequence complete
// -------------------------------------
30:
io.nWarnings := nIndex;
io.aWarnings := aWarningBuffer;
io.nSmReadWarnings := 0;
// -------------------------------------
// state machine error
// -------------------------------------
99:
io.bError := TRUE;
io.nSmReadWarnings := 0;
ELSE
io.nSmReadWarnings := 0;
END_CASE;
// -----------------------------------------------------------------------------
// outputs
// -----------------------------------------------------------------------------
io.bPollingCompleted := (io.nSmReadWarnings = 30);
// -----------------------------------------------------------------------------
// FB calls
// -----------------------------------------------------------------------------
fbGetMessageDetail(MLX := MLX);
fbPollInterval();
Implementation
fbWarnings : ARRAY[0..0] OF MceWarnings;
fbWarnings[0]( io := dummy, MLX := dummy );