MceWarnings

0.3.0

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).

A full polling sequence consists of 10 polling actions.

This function uses a state machine:

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

Each MotoLogix system needs its own 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

  deGroot

Changes

Changed:
  • fix number of warnings
show full history

0.2.0

  deGroot

Changes

Changed:
  • FB names according style guide

0.1.0

  deGroot

Changes

Added:
  • initial version

Overview

kindnametypedefaultcomment
in_outioMceWarningsIOinterface data
in_outMLXMLxDataMotoLogix 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

Snippet of the function call:
fbWarnings : ARRAY[0..0] OF MceWarnings;

fbWarnings[0]( io := dummy,  MLX := dummy );

Pages built with Hugo - 23 Apr 2024 11:54 CEST