Supported platforms: CODESYS 3.5 SAFETY

 

Reviewing I/O

This section describes how to review generated code related to I/O.

 

A MultiTool Creator project defines variable names for all user defined I/O.

In a safety control unit, user shall also define which I/O is safety related. This is done in MultiTool Creator using I/O > Safety related setting.

Safety related setting affects the context I/O is mapped to.

 

Mapped I/O variables depend on the used pin type and the used mode. See hardware specific I/O Programming sections.

For example, Programming > Programming SC52 Safety Control Unit > I/O Programming.

I/O Interface

IO_interface is a component generated in CODESYS, directly under the device.

 

  1. Check each used I/O pin. The IO_interface > IO_interface I/O mapping tab has a folder for each I/O pin.

 

  1. Check the pin context. The variable is mapped to a different code template program depending on MultiTool Creator's Safety related setting

 

The following image highlights the program name in red and the variable name in green, defined in MultiTool Creator.

 

  1. Check internal diagnostic mapping. Verify that all I/O variables under the Internal folder are mapped to the S_Inputs program. These are used by hardware diagnostics.

 

S_Init_IO (PRG)

All I/O initialization code (safety & non-safety related) is added to the S_Init_IO program.

 

  1. Verify that the program is executed from S_PLC_PRG.

 

S_PLC_PRG Code:

IF NOT o_InitDone AND PLC_PRG.o_InitDone THEN

(* Code template safe FB initializations *)

IF NOT S_Init_IO.o_Ready THEN

S_Init_IO();

 

  1. Verify initialization code generated to S_Init_IO program.

 

Pin and connector numbers are added to I/O initialization for diagnostic purposes when using MultiTool 6.4 (SDK3.6) or later, or MultiTool Creator.

 

The following variable definitions are added to the S_Init_IO program.

S_Init_IO Definitions

PROGRAM S_Init_IO

VAR_INPUT

END_VAR

VAR_OUTPUT

o_Ready: SAFEBOOL := FALSE;

o_Error: BOOL := FALSE;

o_ErrorInConnector: DWORD := DWORD#0;

o_ErrorInPin: DWORD := DWORD#0;

o_FWErrorCode: EPEC_SYSTEM.SYSTEM_ERROR_CODES;

END_VAR

VAR

result: EPEC_SYSTEM.SYSTEM_ERROR_CODES;

 

pin: DWORD := DWORD#0;

connector: DWORD := DWORD#0;

info1: DWORD := DWORD#0; // MSW connector, LSW pin

info2: DWORD := DWORD#0; // error specific

END_VAR

 

I/O initialization code always begins by setting the I/O driver to IODRV_STATE_CONFIGURATION:

S_Init_IO Code

IF result = EPEC_SYSTEM.SYSTEM_ERROR_CODES.FW_ERR_OK THEN

result := EPEC_IODRV.IoDrvSetState(EPEC_IODRV.IoDrvStates.IODRV_STATE_CONFIGURATION);

END_IF

 

After I/O driver is set to configuration mode the following is generated:

Firmware error is checked at each initialization function.

 

When I/O init's output o_Error is TRUE following diagnostic can be used by application:

  • Variables o_ErrorInConnector and o_ErrorInPin indicate the failed pin

  • Variable o_FWErrorCode indicates the failure reason

  • The error is also added to application log (when available)

 

Error code is added to application log only when device description includes SafeErrorLog library. In SC52 device description 3.5.10.6 or later is required.

See also How to use application error log.

 

I/O initialization code always ends with error checking and setting the I/O driver to IODRV_STATE_RUN:

S_Init_IO Code

IF result = EPEC_SYSTEM.SYSTEM_ERROR_CODES.FW_ERR_OK THEN

result := EPEC_IODRV.IoDrvSetState(EPEC_IODRV.IoDrvStates.IODRV_STATE_RUN);

o_FWErrorCode := result;

END_IF

IF result <> EPEC_SYSTEM.SYSTEM_ERROR_CODES.FW_ERR_OK THEN

o_Error:=TRUE;

o_ErrorInConnector := connector;

o_ErrorInPin := pin;

o_FWErrorCode := result;

 

info1 := SHL(connector, 16) OR pin;

EPEC_SERRLOG.S_AddError_DWORD(

i_ErrorCode := ApplicationErrors.IO_INIT,

i_LibraryErrorCode := result,

i_Info1 := info1, // MSW connector, LSW pin

i_Info2 := info2 // error specific

);

END_IF

 

o_Ready:=TRUE;

 

 

S_Inputs / Inputs (PRG)

 

  1. Verify that the S_Inputs program is called from S_PLC_PRG.

 

Initialization phase:

S_PLC_PRG Code:

ELSIF NOT S_Inputs.o_InitReady THEN

S_Inputs(i_Initialize:=TRUE);

 

Run phase:

S_PLC_PRG Code:

ELSIF PLC_PRG.o_Initdone THEN

(* Safe actions to execute before safe main program *)

S_Inputs(i_Initialize:=FALSE);

(* ... *)

S_Main();

 

  1. If the project has non-safety related inputs, verify that the Inputs program is called from PLC_PRG.

 

Initialization phase:

PLC_PRG Code:

 

ELSIF NOT Inputs.o_InitReady THEN

Inputs(i_Initialize:=TRUE);

 

Run phase:

PLC_PRG Code:

 

ELSIF S_PLC_PRG.o_InitDone THEN

(* ... *)

Inputs(i_Initialize:=FALSE);

(* ... *)

Main();

 

  1. Verify the generated code for safety related inputs

 

Same variables are generated regardless of Safety related selection in MultiTool Creator.

AI / DI measurement variables in S_Inputs are generated using SAFEDINT / SAFEBOOL type instead of DINT and BOOL.

 

There are no function blocks generated for pulse inputs.

 

 

SafeConversion library version 1.0.1.2

  • S_VoltageToDI includes also DI debounce filtering

SafeConversion library version 1.1.0.0 or later

  • S_VoltageToDI does not include debounce filtering

  • S_DebounceDI is used for debounce filtering

 

The following table lists the function blocks and functions which are generated for inputs depending on the mode:

Name

Input mode

Description

S_ADCToVoltageOrCurrent

AI V
AI mA
Cat. 2
DI

Raw ADC to SI value conversion

- With Cat. 2 mode there is two AD conversions for main and redundant channel.

- With AI V mode there is also pull-up voltage measurement on pins that have pull-up functionality

- In DI mode only for AI/DI pin types which have voltage measurement

S_VoltageToDI

DI

Voltage to DI conversion (with debounce filtering, SafeConversion 1.0.1.2)

S_DebounceDI

(SafeConversion 1.1.0.0 or later)

DI

DI debounce filtering

S_AIOverCurrentProtection

AI mA
Cat. 2

Over current monitoring for mA measurements

S_AddError_BYTE

AI V
AI mA
Cat. 2
DI

Adds input errors to application log.

Generated only when using device description with SafeErrorLog available.

 

MultiTool 6.6 or older code template uses constant limits for AI measurements.

S_ADCToVoltageOrCurrentS_ADCToVoltageOrCurrent

 

The following is an initialization example of type 091 pin Joystick_Y_B in AI V mode using 10V range

Initialization:

o_InitReady := o_InitReady AND FBScaleToSIUnits_Joystick_Y_B.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.U_TYPE091_10V,

S_i_OutputHighLimit := EPEC_HW.Constants.G_AI_10V_HIGH_VOLTAGE ,

S_i_OutputLowLimit := EPEC_HW.Constants.G_AI_LOW_VOLTAGE,

S_i_Cat2MonitoringCh := FALSE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_VOLTAGE_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Joystick_Y_B));

 

The following is an initialization example of type 093 pin Joystick_X_PosSwitch in DI mode

Initialization:

o_InitReady := o_InitReady AND FBScaleToSIUnits_Joystick_X_PosSwitch.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.U_TYPE093_10V,

S_i_OutputHighLimit := EPEC_HW.VALUE_AT_AD_MAXIMUM.U_TYPE093_10V ,

S_i_OutputLowLimit := DINT#0,

S_i_Cat2MonitoringCh := FALSE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_VOLTAGE_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Joystick_X_PosSwitch));

 

The following is an initialization example of type 093 pin Position in Cat. 2 mode. If AI mA mode is used, then redundant channel is not used.

Initialization:

o_InitReady := o_InitReady AND FBScaleToSIUnits_Position.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.I_TYPE093_20mA,

S_i_OutputHighLimit := EPEC_HW.Constants.G_AI_HIGH_CURRENT ,

S_i_OutputLowLimit := EPEC_HW.Constants.G_AI_LOW_CURRENT,

S_i_Cat2MonitoringCh := FALSE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_CURRENT_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Position));

 

o_InitReady := o_InitReady AND FBScaleToSIUnitsCat2Redundant_Position.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.I_TYPE093_20mA,

S_i_OutputHighLimit := EPEC_HW.Constants.G_AI_HIGH_CURRENT ,

S_i_OutputLowLimit := EPEC_HW.Constants.G_AI_LOW_CURRENT,

S_i_Cat2MonitoringCh := TRUE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_CURRENT_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Position));

 

The following is a run phase code example of AD conversion. The same principle applies to AI V, AI mA, Cat. 2 and DI. Variable prefixes may differ depending on measurement.

Code:

FBScaleToSIUnits_Joystick_Y_B (

i_Enable := i_Enable,

i_ADCValue := AI_RAW_MAIN_Joystick_Y_B, (*Variable mapped to I/O interface*)

o_Status => o_AiScaleStatus_Joystick_Y_B,

S_o_Output => o_AI_MAIN_Joystick_Y_B); (*Variable used by application*)

 

 

 

 

MultiTool 6.7 or newer code template uses user defined limits for AI measurements.

S_ADCToVoltageOrCurrentS_ADCToVoltageOrCurrent

 

 

The following is an initialization example of type 091 pin Joystick_Y_B in AI V mode using 10V range

Initialization:

o_InitReady := o_InitReady AND FBScaleToSIUnits_Joystick_Y_B.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.U_TYPE091_10V,

S_i_OutputHighLimit := 10000,

S_i_OutputLowLimit := 0,

S_i_Cat2MonitoringCh := FALSE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_VOLTAGE_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Joystick_Y_B));

 

The following is an initialization example of type 093 pin Joystick_X_PosSwitch in DI mode

Initialization:

o_InitReady := o_InitReady AND FBScaleToSIUnits_Joystick_X_PosSwitch.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.U_TYPE093_10V,

S_i_OutputHighLimit := EPEC_HW.VALUE_AT_AD_MAXIMUM.U_TYPE093_10V ,

S_i_OutputLowLimit := DINT#0,

S_i_Cat2MonitoringCh := FALSE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_VOLTAGE_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Joystick_X_PosSwitch));

 

The following is an initialization example of type 093 pin Position in Cat. 2 mode.

If AI mA mode is used, then redundant channel is not used.

Initialization:

o_InitReady := o_InitReady AND FBScaleToSIUnits_Position.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.I_TYPE093_20mA,

S_i_OutputHighLimit := 21900 ,

S_i_OutputLowLimit := 0,

S_i_Cat2MonitoringCh := FALSE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_CURRENT_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Position));

 

o_InitReady := o_InitReady AND FBScaleToSIUnitsCat2Redundant_Position.Init(

S_i_OutputMaximum := EPEC_HW.VALUE_AT_AD_MAXIMUM.I_TYPE093_20mA,

S_i_OutputHighLimit := 21900 ,

S_i_OutputLowLimit := 0,

S_i_Cat2MonitoringCh := TRUE,

S_i_DiagnosticDelay := EPEC_HW.Constants.G_CURRENT_INPUT_DIAGNOSTIC_DELAY,

i_pEventCode := ADR(o_EventCode_Position));

 

 

The following is a run phase code example of AD conversion.

Variable prefixes may differ depending on measurement.

 

Example applies to:

AI V mode

DI mode

AI mA with SafeSSeriesHardware up to version 1.3.2.7

Cat. 2 mode with SafeSSeriesHardware up to version 1.3.2.7 (note that Cat. 2 mode has main and redundant measurements)

 

AI mA & Cat. 2 modes: Runtime code is executed before S_AIOverCurrentProtection.

 

Code:

FBScaleToSIUnits_Joystick_Y_B (

i_Enable := i_Enable,

i_ADCValue := AI_RAW_MAIN_Joystick_Y_B, (*Variable mapped to I/O interface*)

o_Status => o_AiScaleStatus_Joystick_Y_B,

S_o_Output => o_AI_MAIN_Joystick_Y_B); (*Variable used by application*)

 

The following is a run phase code example of AD conversion for AI mA mode with SafeSSeriesHardware version 1.4.0.0 or newer.

 

Runtime code is executed after S_AIOverCurrentProtection.

 

Code:

FBScaleToSIUnits_Position (

   i_Enable := o_AiOverCurrentStatus_Position.OutputValid,

   i_ADCValue := FbOvercurrent_Position.o_ADCValue,

   o_Status => o_AiScaleStatus_Position,

   S_o_Output => o_AI_MAIN_Position);

 

The following is a run phase code example of AD conversion for Cat. 2 mode with SafeSSeriesHardware version 1.4.0.0 or newer.

 

Runtime code is executed after S_AIOverCurrentProtection.

 

Code:

FBScaleToSIUnits_Position (

   i_Enable := o_AiOverCurrentStatus_Position.OutputValid,

   i_ADCValue := FbOvercurrent_Position.o_ADCValue,

   o_Status => o_AiScaleStatus_Position,

   S_o_Output => o_AI_MAIN_Position);

 

FBScaleToSIUnitsCat2Redundant_Position (

   i_Enable := o_AiOverCurrentStatus_Position.OutputValid,

   i_ADCValue := AI_RAW_MAIN_REDUNANT_Position,

   o_Status => o_AiScaleStatusRedundant_Position,

   S_o_Output => o_AI_REDUNDANT_Position);

 

 

 

 

 

 

 

The following example applies with SafeConversion version 1.0.1.2:

S_VoltageToDIS_VoltageToDI

 

The following is an initialization example of DI filtering for Joystick_X_PosSwitch

Initialization:

o_InitReady := o_InitReady AND FBVoltagetoDi_Joystick_X_PosSwitch.Init(

S_i_ThresholdHigh := 4500, (*Value from MultiTool*)

S_i_ThresholdLow := 3500, (*Value from MultiTool*)

S_i_DebounceDelay := 30, (*Value from MultiTool*)

i_pEventCode := ADR(o_EventCode_Joystick_X_PosSwitch));

 

The following is a run phase code example of DI filtering for Joystick_X_PosSwitch

Code:

FBVoltagetoDi_Joystick_X_PosSwitch(

i_Enable := FBScaleToSIUnits_Joystick_X_PosSwitch.o_Status.OutputValid,

S_i_Voltage := FBScaleToSIUnits_Joystick_X_PosSwitch.S_o_Output,

o_Status => o_DiConversionStatus_Joystick_X_PosSwitch,

S_o_DigitalState => o_DI_Joystick_X_PosSwitch);

 

 

 

 

The following examples apply with SafeConversion version 1.1.0.0 or later:

S_VoltageToDI & S_DebounceDIS_VoltageToDI & S_DebounceDI

 

The following is an initialization example of DI filtering for Joystick_X_PosSwitch

Initialization:

o_InitReady := o_InitReady AND FBVoltagetoDi_Joystick_X_PosSwitch.Init(

S_i_ThresholdHigh := 4500, (*Value from MultiTool*)

S_i_ThresholdLow := 3500, (*Value from MultiTool*)

i_pEventCode := ADR(o_EventCode_Joystick_X_PosSwitch));

 

o_InitReady := o_InitReady AND FBDebounceDi_Joystick_X_PosSwitch.Init(

S_i_DebounceDelay := 30, (*Value from MultiTool*)

i_FilterType := EPEC_SC.DebounceFilterType.Debounce_Fast, (*Debounce type from MultiTool*)

i_pEventCode := ADR(o_EventCode_Joystick_X_PosSwitch));

 

The following is a run phase code example of DI filtering for Joystick_X_PosSwitch

Code:

FBVoltagetoDi_Joystick_X_PosSwitch(

i_Enable := FBScaleToSIUnits_Joystick_X_PosSwitch.o_Status.OutputValid,

S_i_Voltage := FBScaleToSIUnits_Joystick_X_PosSwitch.S_o_Output,

o_Status => o_DiConversionStatus_Joystick_X_PosSwitch,

S_o_DigitalState => );

 

FBDebounceDi_Joystick_X_PosSwitch(

      i_Enable := FBVoltagetoDi_Joystick_X_PosSwitch.o_Status.OutputValid,

S_i_DigitalState := FBVoltagetoDi_Joystick_X_PosSwitch.S_o_DigitalState,

o_Status => o_DiDebounceStatus_Joystick_X_PosSwitch,

S_o_DigitalState => o_DI_Joystick_X_PosSwitch);

 

 

 

 

 

 

S_DebounceDIS_DebounceDI

 

The following is an initialization example of DI filtering for Joystick_X_PosSwitch

Initialization:

 

o_InitReady := o_InitReady AND FBDebounceDi_Joystick_X_PosSwitch.Init(

S_i_DebounceDelay := 30, (*Value from MultiTool*)

i_FilterType := EPEC_SC.DebounceFilterType.Debounce_Fast, (*Debounce type from MultiTool*)

i_pEventCode := ADR(o_EventCode_Joystick_X_PosSwitch));

 

The following is a run phase code example of DI filtering for Joystick_X_PosSwitch

Code:

 

FBDebounceDi_Joystick_X_PosSwitch(

      i_Enable := i_Enable,

S_i_DigitalState := ST_Joystick_X_PosSwitch,

o_Status => o_DiDebounceStatus_Joystick_X_PosSwitch,

S_o_DigitalState => o_DI_Joystick_X_PosSwitch);

 

 

 

 

 

 

 

 

S_AIOverCurrentProtection

 

 

The following is an initialization example of AI over current protection for Position

Initialization:

o_InitReady := o_InitReady AND FbOvercurrent_Position.init(i_pEventCode := ADR(o_EventCode_Position));

 

The following is a run phase code example of AI over current protection for Position

 

The following examples apply with SafeSSeriesHardware versions up to 1.3.2.7:

 

Runtime code is executed after S_ADCToVoltageOrCurrent.

 

SC52 Safety Control UnitSC52 Safety Control Unit

Code:

FbOvercurrent_Position(

i_Enable := o_AiScaleStatus_Position.OutputValid AND o_AiScaleStatusRedundant_Position.OutputValid,

S_i_Current:=o_AI_MAIN_Position,

o_Status => o_AiOverCurrentStatus_Position);

 

IF NOT o_AiOverCurrentStatus_Position.OutputValid AND i_Enable = TRUE THEN

(* Over current error set pin to voltage mode *)

EPEC_IODRV.IoDrvDOSetConfig (EPEC_HW.IO_Channels.PIN_1_02_DO_TYPE_V_mA, FALSE);

END_IF

 

 

 

SL84 Safety Control UnitSL84 Safety Control Unit

Code:

FbOvercurrent_Position(

i_Enable := o_AiScaleStatus_Position.OutputValid,

S_i_Current:=o_AI_MAIN_Position,

o_Status => o_AiOverCurrentStatus_Position);

 

IF ((NOT o_AiOverCurrentStatus_Position.OutputValid) OR FBScaleToSIUnits_Position.o_Status.OutputHigh) AND i_Enable = TRUE  THEN

(* Over current error set pin to voltage mode *)

EPEC_IODRV.IoDrvDOSetConfig (EPEC_HW.IO_Channels.PIN_1_1_DO_TYPE_V_mA, FALSE);

END_IF

 

 

 

 

The following example applies to SafeSSeriesHardware version 1.4.0.0 or later:

 

Runtime code is executed before S_ADCToVoltageOrCurrent.

 

Code:

FbOvercurrent_Position(

i_Enable := i_Enable,

i_ADCValue := AI_RAW_MAIN_Position,

o_Status => o_AiOverCurrentStatus_Position

o_ADCValue => );

 

IF NOT o_AiOverCurrentStatus_Position.OutputValid AND i_Enable = TRUE THEN

(* Over current error set pin to voltage mode *)

EPEC_IODRV.IoDrvDOSetConfig (EPEC_HW.IO_Channels.PIN_1_02_DO_TYPE_V_mA, FALSE);

END_IF

 

 

 

S_AddError_BYTE

 

Error code is added to application log only when device description includes SafeErrorLog library. In SC52 device description 3.5.10.6 or later is required.

See also How to use application error log.

 

The following is a run phase code example of adding pin X1_02 input error to application log

Code:

EPEC_SERRLOG.S_AddError_BYTE(

i_ErrorCode := ApplicationErrors.INPUTS,

i_LibraryErrorCode := o_EventCode_X1_02.EventID,

i_Info1 := o_EventCode_X1_02.FunctionID,

i_Info2 := o_EventCode_X1_02.DeviceID,

i_Info3 := o_EventCode_X1_02.ChannelID,

i_Info4 := 1, // connector

i_Info5 := 2, // pin

i_Info6 := 0,

i_Info7 := 0,

i_Info8 := 0);

 

S_Outputs / Outputs (PRG)

  1.  If the project has safety related outputs, verify that the S_Outputs program is called from S_PLC_PRG.

 

Initialization phase:

S_PLC_PRG Code:

ELSIF NOT S_Outputs.o_InitReady THEN

S_Outputs(i_Initialize:=TRUE);

 

Run phase:

S_PLC_PRG Code:

(* User safe main program *)

S_Main();

(* Safe actions to execute after safe main program *)

S_Outputs(i_Initialize:=FALSE);

 

  1. If the project has non-safety related outputs, verify that the Outputs program is called from PLC_PRG.

 

Initialization phase:

PLC_PRG Code:

 

ELSIF NOT Outputs.o_InitReady THEN

Outputs(i_Initialize:=TRUE);

 

Run phase:

PLC_PRG Code:

 

(* User non-safe main program *)

Main();

(* Non-safe actions to execute after non-safe main program *)

Outputs(i_Initialize:=FALSE);

 

 

  1. Verify generated code for safety related outputs

 

Currently there are no function blocks implemented in the S_Outputs / Outputs program. I/O interface mapped variables are controlled by program interface.

 

 

Example of DO output control

Code:

DO_Boom_Y_ONOFF := i_DO_Boom_Y_ONOFF;

o_CM_Boom_Y_ONOFF := CM_Boom_Y_ONOFF;

o_DOS_Boom_Y_ONOFF := DOS_Boom_Y_ONOFF;

(* Resolve status bits *)

o_ST_Boom_Y_ONOFF.InitOk := DWORD_TO_BOOL(ST_Boom_Y_ONOFF AND 1);

o_ST_Boom_Y_ONOFF.ParameterError := DWORD_TO_BOOL(ST_Boom_Y_ONOFF AND 2);

o_ST_Boom_Y_ONOFF.OverCurrent := DWORD_TO_BOOL(ST_Boom_Y_ONOFF AND 4);

 

Example of PWM output control

Code:

o_CM_BoomCurUpRatio := CM_BoomCurUpRatio;

PWFM_RATIO_BoomCurUpRatio := i_PWFM_RATIO_BoomCurUpRatio;

PWFM_FREQ_BoomCurUpRatio := i_PWFM_FREQ_BoomCurUpRatio;

o_PI_PULSE_WIDTH_BoomCurUpRatio := PI_PULSE_WIDTH_BoomCurUpRatio;

o_DOS_BoomCurUpRatio := DOS_BoomCurUpRatio;

(* Resolve status bits *)

o_ST_BoomCurUpRatio.InitOk := DWORD_TO_BOOL(ST_BoomCurUpRatio AND 1);

o_ST_BoomCurUpRatio.ParameterError := DWORD_TO_BOOL(ST_BoomCurUpRatio AND 2);

o_ST_BoomCurUpRatio.OverCurrent := DWORD_TO_BOOL(ST_BoomCurUpRatio AND 4);

 

Error code is added to application log only when device description includes SafeErrorLog library. In SC52 device description 3.5.10.6 or later is required.

See also How to use application error log.

 

Example of adding output's firmware error to application log.

Code:

connector := 1;

pin := 25;

info1 := SHL(connector, 16) OR pin; // MSW connector, LSW pin

info2 := DWORD#0; // reserved

errorCode := DWORD_TO_DINT(ST_BoomCurUpRatio AND 16#FFFFFFE); // filter out InitOk bit

EPEC_SERRLOG.S_AddError_DWORD(i_ErrorCode := ApplicationErrors.OUTPUTS_FW, i_LibraryErrorCode := errorCode, i_Info1:=info1, i_Info2:=info2);

 

 

See also

 

 

Source file topic100551.htm

Last updated 13-Jun-2024