MceAlarms

0.2.0

Handling the alarms for a MotoLogix system.

The MotoLogix data packet has a variable which tells the amount of active alarms. To read the alarm information we need to call MLxGetErrorDetail for each active alarm. That function reads the information as strings (in the active pendant language).

The alarm information is stored in an array (see MceAlarmsIO).

This function uses two states machines:

Usage

Each MotoLogix system needs its own MceAlarms instance.

Create the (global) variables for the interface data. These are also used for connecting buttons or an HMI.

stAlarms : ARRAY [0..GVL.MLX_UBOUND] OF MceAlarmsIO; // data for alarm handling of a MotoLogix system

Create the instances:

fbAlarms : ARRAY [0..GVL.MLX_UBOUND] OF MceAlarms;

Map all relevant inputs (see MceAlarmsIO) to your HMI.

GVL.stAlarms[0].bReset := ...;

Call the instances in a loop:

// function call
FOR i := 0 TO GVL.MLX_UBOUND DO
  fbAlarms[i](
    io := GVL.stAlarms[i],
    blinkSignals := GVL.stBlinkSignals,
    MLX := GVL.stMLX[i]);
END_FOR;

Map all relevant outputs (see MceAlarmsIO) to your HMI and/or to higher level state machines:

// this is just a portion of the relevant signals
... := GVL.stAlarms[0].bResetIndicator;
... := GVL.stAlarms[0].nAlarms;
... := GVL.stAlarms[0].aAlarms;

Version history

0.2.0

  deGroot

Changes

Changed:
  • FB names according style guide
show full history

0.1.0

  deGroot

Changes

Added:
  • initial version

Overview

kindnametypedefaultcomment
in_outioMceAlarmsIOinterface data
in_outblinkSignalsMceBlinkSignalsIOsignals for blinking indicator lights
in_outMLXMLxDataMotoLogix shared memory variable

Details

Interface data for this function.

Check the data type for more information.

blinkSignals

MceBlinkSignalsIO

Signals for blinking indicator lights.

Check the data type for the available blinking patterns.

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

(*Alarm reading + alarm reset*)
FUNCTION_BLOCK MceAlarms

(*
 * -----------------------------------------------------------------------------
 * Name               : MceAlarms
 * Version            : 0.2.0
 * Date               : 2022-02-23
 * Author             : deGroot
 * Family             : YaskawaMce
 * Organisation       : github.com/YaskawaEurope/mlx-examples
 * 
 * -----------------------------------------------------------------------------
 * Alarm reading + alarm reset
 * -----------------------------------------------------------------------------
 *)

VAR_IN_OUT
  io : MceAlarmsIO; (*interface data*)
  blinkSignals : MceBlinkSignalsIO; (*signals for blinking indicator lights*)
  MLX : MLxData; (*MotoLogix shared memory variable*)
END_VAR

VAR
  fbResetAndHold : MLxResetAndHold;
  fbGetErrorDetail : MLxGetErrorDetail;
  nIndex : USINT; (*index for reading alarms*)
  bOsrReset : BOOL; (*rising edge*)
  aOneShots : ARRAY [0..0] OF BOOL; (*bits for one shot signals*)
END_VAR

Logic

// -----------------------------------------------------------------------------
// init
// -----------------------------------------------------------------------------
io.bError := FALSE;
fbResetAndHold.Enable := FALSE;
fbGetErrorDetail .Enable := FALSE;


// -----------------------------------------------------------------------------
// common
// -----------------------------------------------------------------------------
// rising edge signals
bOsrReset := io.bReset AND NOT aOneShots[0];
aOneShots[0] := io.bReset;


// -----------------------------------------------------------------------------
// State machine 1: read alarms
// -----------------------------------------------------------------------------
CASE io.nSmReadAlarms OF
  // -------------------------------------
  // idle, wait for new alarm data
  // -------------------------------------
  0:
    IF (io.nAlarms <> MLX.NumberOfQueuedErrors)
      AND MLX.Signals.MLXGatewayConnected THEN

      io.nAlarms := DINT_TO_USINT(MLX.NumberOfQueuedErrors);
      io.nErrorCode := 0;
      io.nSmReadAlarms := 10;
    END_IF;

  // -------------------------------------
  // prepare reading
  // -------------------------------------
  10:
    nIndex := 0;
    MEMUtils.MemSet(
      pbyBuffer := ADR(io.aAlarms),
      byValue := 0,
      dwSize := SIZEOF(io.aAlarms));

    IF (io.nAlarms > 0) THEN
      io.nSmReadAlarms := 20;
    ELSE
      io.nSmReadAlarms := 0;
    END_IF;

  // -------------------------------------
  // read alarm with MLxGetErrorDetail
  // -------------------------------------
  20:
    fbGetErrorDetail.Enable := TRUE;
    IF fbGetErrorDetail.Sts_EN AND fbGetErrorDetail.Sts_DN THEN
      IF fbGetErrorDetail.Sts_ER THEN
        io.nErrorCode := 1000 + io.nSmReadAlarms;
        io.nSmReadAlarms := 99;
      ELSE
        // store alarm information
        io.aAlarms[nIndex].nAlarmNumber :=
          fbGetErrorDetail.ErrorDetail.errorNumber;

        MEMUtils.MemCpy(
          pbySrc := ADR(fbGetErrorDetail.ErrorDetail.Message),
          pbyDest := ADR(io.aAlarms[nIndex].sMessage),
          dwSize := SIZEOF(io.aAlarms[nIndex].sMessage));

        MEMUtils.MemCpy(
          pbySrc := ADR(fbGetErrorDetail.ErrorDetail.ExtendedDescription1),
          pbyDest := ADR(io.aAlarms[nIndex].sSubCode),
          dwSize := SIZEOF(io.aAlarms[nIndex].sSubCode));

        MEMUtils.MemCpy(
          pbySrc := ADR(fbGetErrorDetail.ErrorDetail.TimeStamp),
          pbyDest := ADR(io.aAlarms[nIndex].sTimeStamp),
          dwSize := SIZEOF(io.aAlarms[nIndex].sTimeStamp));

        nIndex := nIndex + 1;
        io.nSmReadAlarms := 30;
      END_IF;
    END_IF;

  // -------------------------------------
  // check if done
  // -------------------------------------
  30:
    // more errors to read
    IF nIndex < io.nAlarms THEN
      io.nSmReadAlarms := 20;
    // done
    ELSE
      io.nSmReadAlarms := 0;
    END_IF;

  // -------------------------------------
  // state machine error
  // -------------------------------------
  99:
    io.bError := TRUE;
    io.nSmReadAlarms := 0;

  ELSE
    io.nSmReadAlarms := 0;

END_CASE;


// -----------------------------------------------------------------------------
// outputs
// -----------------------------------------------------------------------------
io.bAlarmActive := (MLX.NumberOfQueuedErrors <> 0);


// -----------------------------------------------------------------------------
// State machine 2: reset alarm
// -----------------------------------------------------------------------------
CASE io.nSmResetAlarm OF
  // -------------------------------------
  // idle
  // -------------------------------------
  0:
    IF bOsrReset AND MLX.Signals.RemoteMode
      AND MLX.Signals.MLXGatewayConnected THEN
      io.nErrorCode := 0;
      io.nSmResetAlarm := 10;
    END_IF;

  // -------------------------------------
  // reset alarm
  // -------------------------------------
  10:
    fbResetAndHold.Enable := TRUE;
    IF fbResetAndHold.Sts_EN AND fbResetAndHold.Sts_DN THEN
      IF fbResetAndHold.Sts_ER THEN
        io.nErrorCode := 2000 + io.nSmResetAlarm;
        io.nSmResetAlarm := 99;
      ELSE
        io.nSmResetAlarm := 0;
      END_IF;
    END_IF;

  // -------------------------------------
  // state machine error
  // -------------------------------------
  99:
    io.bError := TRUE;
    io.nSmResetAlarm := 0;

END_CASE;


// -----------------------------------------------------------------------------
// outputs
// -----------------------------------------------------------------------------
io.bResetIndicator := (io.bAlarmActive AND blinkSignals.bSlow)
                      OR ((io.nSmResetAlarm = 10) AND blinkSignals.bFast);


// -----------------------------------------------------------------------------
// FB calls
// -----------------------------------------------------------------------------
fbGetErrorDetail(MLX := MLX);
fbResetAndHold(MLX := MLX);

Implementation

Snippet of the function call:
fbAlarms : ARRAY[0..0] OF MceAlarms;

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

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