首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >[SCL] 西门子基本控制库LBC学习1 双向执行器 LBC_TwoWayActuator

[SCL] 西门子基本控制库LBC学习1 双向执行器 LBC_TwoWayActuator

作者头像
科控物联
发布2026-03-19 14:59:45
发布2026-03-19 14:59:45
500
举报

使用举例。如果只是最普通的电磁阀(线圈得电到工作位,断电回原点)怎么使用?

setOutputWorkContinous 设为true

goToWorkposition 绑定输出,goToHomeposition悬空即可。

=====================================

简介:

使用两个或一个控制命令控制两种状态(例如阀门的位置)之间的执行器。适用于双稳态设备。

Input参数

Identifier

Data Type

DefaultValue

Description

enable

Bool

FALSE

TRUE:Enable functionalityofFB

commandHomePos

Bool

FALSE

Risingedge:Moveactuatortohomeposition

commandWorkPos

Bool

FALSE

Risingedge:Move actuatortoworkposition

feedbackHomePos

Bool

FALSE

TRUE:Feedbackactuatorisinhomeposition

feedbackWorkPos

Bool

FALSE

TRUE:Feedbackactuatorisinwork position

acknowledge

Bool

FALSE

Acknowledgementofthe alarms

Input参数

Identifier

Data Type

Description

valid

Bool

TRUE:Valid setofoutput values availableattheFB

busy

Bool

TRUE:FBisnotfinishedandnewoutput valuescanbeexpected

error

Bool

FALSE:NoerrorTRUE:AnerroroccurredduringtheexecutionoftheFB

status

Word

16#0000-16#7FFF:Status oftheFB16#8000-16#FFFF:Error identification(seefollowingTable)

goToHomePos

Bool

TRUE:Controloutput tomovetoactuatortohomeposition

goToWorkPos

Bool

TRUE:Controloutput tomovetoactuatortoworkposition

inHomePos

Bool

TRUE:Actuatorisinhomeposition

inWorkPos

Bool

TRUE:Actuatorisinwork position

diagnostics

LBC_typeDiagnostics

Modulerelateddiagnosticinformation

In/Out参数

Identifier

Data Type

Description

configuration

LBC_typeTwoWayActuatorConfiguration

Modulerelatedconfigurationparameters

moduleInterface

LBC_typeTwoWayActuatorInterface

Moduleinterfaceforexternalsystems

状态和错误代码

代码/值

标识符/描述

16#0000

STATUS_NO_ERROR_OCCURRED状态:执行期间未发生错误

16#7000

STATUS_NO_CALL状态:当前未处理任何作业

16#7001

STATUS_FIRST_CALL状态:传入新作业后的第一个呼叫(上升沿“启用”)

16#7002

STATUS_SUBSEQUENT_CALL状态:在活动处理期间进行后续调用,没有更多详细信息

16#7003

STATUS_POSITION_NOT_DEFINED状态:执行器位置不确定

16#7004

STATUS_IN_HOME_POSITION状态:执行器处于原位

16#7005

STATUS_MOVE_TO_WORK_POSITION状态:执行器正在向工作位置移动

16#7006

STATUS_IN_WORK_POSITION状态:执行器处于工作位置

16#7007

STATUS_MOVE_TO_HOME_POSITION状态:执行器正在向原位移动

16#8201

ERR_CONFIGURATION_LEAVE_FEEDBACK_TIME_NEGATIVE错误:离开位置反馈时间的负值

16#8202

ERR_CONFIGURATION_REACH_FEEDBACK_TIME_NEGATIVE错误:达到位置反馈时间的负值

16#8400

ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME错误:同时显示家庭和工作位置的命令

16#8401

ERR_MORE_THAN_ONE_FEEDBACK_PRESENT_AT_SAME_TIME错误:中立和工作职位的反馈同时存在

16#8402

ERR_TIMEOUT_HOME_POSITION错误:监控超时,缺少反馈到主位置

16#8403

ERR_TIMEOUT_WORK_POSITION错误:监控超时,错过反馈工作位置

16#8404

ERR_INCORRECT_FEEDBACK_WORK_POSITION错误:未预料到反馈工作位置的外观

代码/值

标识符/描述

16#8405

ERR_INCORRECT_FEEDBACK_HOME_POSITION错误:未预料到反馈原点位置的外观

16#8406

ERR_MISSING_FEEDBACK_WORK_POSITION错误:缺少反馈工作位置

16#8407

ERR_MISSING_FEEDBACK_HOME_POSITION错误:缺少反馈主页位置

16#8408

ERR_NOT_LEAVING_HOME_POSITION错误:未离开主位置

16#8409

ERR_NOT_LEAVING_WORK_POSITION错误:未离开工作位置

16#8600

ERR_UNDEFINED_STATE错误:由于状态机中未定义状态

用户定义的数据类型

模块相关诊断信息

Identifier

Data Type

DefaultValue

Description

status

Word

16#0000

16#0000-16#7FFF: Status of the FB16#8000-16#FFFF:Error identification

subfunctionStatus

Word

16#0000

Statusorreturnvalue ofcalledFB's, FCs,systemblocksor otherstatus information

stateNumber

DInt

0

Stateinthestate machineoftheblockwhere theerroroccurred

模块相关配置参数

标识符

数据类型

默认值

描述

referenceDesignator

String[20]

'TwoWayAct.'

设备名称或设备ID

monitoringLeavingFeedback

时间

T#5s

离开“运动开始”位置的控制时间

monitoringReachingFeedback

Time

T#5s

Control time for reaching the "end ofmovement"position

setOutputHomeContinuously

Bool

TRUE

TRUE: Output home is set as long ascommand home is present. FALSE: Outputhas just an impulse as long as the actuatorhasnotreachedthepositionandismoving

setOutputWorkContinuously

Bool

TRUE

TRUE: Output work is set as long ascommand work is present. FALSE: Outputhasjust impulseaslong astheactuatorhasnotreachedthe positionandismoving

disableHomeCommand

Bool

FALSE

TRUE:Disablecommandforhome position.Actuator starts moving to home positionwhen`commandWorkPos`issettoFALSE

disableFeedbackHomePos

Bool

FALSE

TRUE: Disable the monitoring of the Homeposition feedback. FALSE: Home position isreachedafter`monitoringReachingFeedback`timeexpires.

disableFeedbackWorkPos

Bool

FALSE

TRUE: Disable the monitoring of the Workpositionfeedback.FALSE:Work positionisreachedafter`monitoringReachingFeedback`timeexpires.

disableAlarms

Bool

FALSE

TRUE:Disablethealarmsoftheblock

resetOutputsOnError

Bool

FALSE

TRUE: in case of an error the outputs are bereset and the error has to be acknowledgedbeforefurther processingispossible

LBC_typeTwoWayActuatorInterface(UDT)

Moduleinterfaceforexternalsystems

Identifier

Data Type

DefaultValue

Description

commands

LBC_typeInterfaceCommands

default

Modulerelatedcommandsfromexternalsystems

configuration

LBC_typeTwoWayActuatorConfiguration

default

Modulerelated configurationparameters

monitoring

LBC_typeTwoWayActuatorProcessValues

default

Modulerelated monitoringinformation

diagnostics

LBC_typeDiagnostics

default

Modulerelated diagnosticinformation

功能描述

如果输入使能为 TRUE,则将模块置于操作状态。

执行器由 commandWorkPos 和 commandHomePos 两个输入控制,任何时候只能设置一个。

如果 commandWorkPos 为 TRUE,则该块设置输出 goToWorkPos,

如果CommandHomePos 是正确的,然后该块设置输出 goToHomePos。

一旦模块开始从一个位置移动到另一个位置,两个控制时间被启动-离开位置和到达位置的控制时间。

这些定时器的用途是监测执行器是否离开实际位置,并监测执行器到达新的位置,它正在向前移动-到达反馈。

这些定时器可以通过模块接口中的参数进行配置。如果执行器是从Home移动到工作位置,离开的位置是home位置(反馈home位置) ,到达的位置是工作位置(反馈工作位置)。

如果执行器是从工作位置移动到home位置,离开位置是工作位置(反馈工作位置) ,到达位置是home位置(反馈家庭位置)。相同的时间设置(离开反馈和达到反馈)是独立使用.

当执行器完成向工作位置或home位置移动时,各自的输出被复位(FALSE)。这是为了控制执行器,不需要额外的力量,一旦他们到达他们的最终位置。

如果需要在到达目的地时保留 goToWorkposition 或 goToHomeposition 的输出设置(TRUE) ,则可以通过 setOutputHomeContinous 和 setOutputWorkContinous 配置它。

在其中一个反馈或两个反馈都不可用的情况下,可以从块的参数中禁用它们的监视。

在这种情况下,将一个状态转换为另一个状态(Home to Work 和 Work to Home)的转换和持续时间完全在 monitor ingReachingFeeback 参数上完成。

如果时间过期,反馈没有被禁用,模块将引发一个错误。根据配置 resetOutputsOnError,如果参数设置为 FALSE (默认值) ,它将保持实际状态,或者通过重置输出跳入错误状态。

如果模块处于错误状态,则必须通过输入确认来确认错误,一旦确认错误,就可以重新启动操作。

[汇总贴] S7-200 SMART 截至20221029

以下为SCL源代码,可以直接copy使用。不copy代码就不用往下看了。

代码语言:javascript
复制
TYPE "LBC_typeTwoWayActuatorProcessValues"
VERSION : 0.1
   STRUCT
      enable { ExternalWritable := 'False'} : Bool;
      commandHomePos { ExternalWritable := 'False'} : Bool;
      commandWorkPos { ExternalWritable := 'False'} : Bool;
      feedbackHomePos { ExternalWritable := 'False'} : Bool;
      feedbackWorkPos { ExternalWritable := 'False'} : Bool;
      goToHomePos { ExternalWritable := 'False'} : Bool;
      goToWorkPos { ExternalWritable := 'False'} : Bool;
      inHomePos { ExternalWritable := 'False'} : Bool;
      inWorkPos { ExternalWritable := 'False'} : Bool;
      error { ExternalWritable := 'False'} : Bool;
   END_STRUCT;

END_TYPE

TYPE "LBC_typeTwoWayActuatorConfiguration"
VERSION : 0.1
   STRUCT
      referenceDesignator { S7_SetPoint := 'True'} : String[20] := 'TwoWayAct.';
      monitoringLeavingFeedback { S7_SetPoint := 'True'} : Time := T#5s;
      monitoringReachingFeedback { S7_SetPoint := 'True'} : Time := T#5s;
      setOutputHomeContinuously { S7_SetPoint := 'True'} : Bool := TRUE;
      setOutputWorkContinuously { S7_SetPoint := 'True'} : Bool := TRUE;
      disableHomeCommand { S7_SetPoint := 'True'} : Bool;
      disableFeedbackHomePos { S7_SetPoint := 'True'} : Bool;
      disableFeedbackWorkPos { S7_SetPoint := 'True'} : Bool;
      disableAlarms { S7_SetPoint := 'True'} : Bool;
      resetOutputsOnError { S7_SetPoint := 'True'} : Bool;
   END_STRUCT;

END_TYPE

TYPE "LBC_typeDiagnostics"
VERSION : 0.1
   STRUCT
      status { ExternalWritable := 'False'} : Word;
      subfunctionStatus { ExternalWritable := 'False'} : Word;
      stateNumber { ExternalWritable := 'False'} : DInt;
   END_STRUCT;

END_TYPE

TYPE "LBC_typeInterfaceCommands"
VERSION : 0.1
   STRUCT
      refreshConfiguration : Bool;
      editConfiguration : Bool;
      saveConfiguration : Bool;
      acknowledge : Bool;
   END_STRUCT;

END_TYPE

TYPE "LBC_typeTwoWayActuatorInterface"
VERSION : 0.1
   STRUCT
      commands { S7_SetPoint := 'False'} : "LBC_typeInterfaceCommands";
      configuration { S7_SetPoint := 'False'} : "LBC_typeTwoWayActuatorConfiguration";
      monitoring { ExternalWritable := 'False'; S7_SetPoint := 'False'} : "LBC_typeTwoWayActuatorProcessValues";
      diagnostics { ExternalWritable := 'False'; S7_SetPoint := 'False'} : "LBC_typeDiagnostics";
   END_STRUCT;

END_TYPE

FUNCTION_BLOCK "LBC_TwoWayActuator"
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : Siemens_Digital_Industry
FAMILY : LBC
NAME : LBC_TwoWayActuator
   VAR_INPUT 
      enable : Bool;
      commandHomePos : Bool;
      commandWorkPos : Bool;
      feedbackHomePos : Bool;
      feedbackWorkPos : Bool;
      acknowledge : Bool;
   END_VAR

   VAR_OUTPUT 
      valid { ExternalWritable := 'False'} : Bool;
      busy { ExternalWritable := 'False'} : Bool;
      error { ExternalWritable := 'False'} : Bool;
      status { ExternalWritable := 'False'} : Word := #STATUS_NO_CALL;
      goToHomePos { ExternalWritable := 'False'; S7_HiddenAssignment := 'Show'} : Bool;
      goToWorkPos { ExternalWritable := 'False'} : Bool;
      inHomePos { ExternalWritable := 'False'; S7_HiddenAssignment := 'HideIfNoParamAssigned'} : Bool;
      inWorkPos { ExternalWritable := 'False'; S7_HiddenAssignment := 'HideIfNoParamAssigned'} : Bool;
      diagnostics { ExternalWritable := 'False'} : "LBC_typeDiagnostics";
   END_VAR

   VAR_IN_OUT 
      configuration : "LBC_typeTwoWayActuatorConfiguration";
      moduleInterface : "LBC_typeTwoWayActuatorInterface";
   END_VAR

   VAR 
      statProcessValues { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "LBC_typeTwoWayActuatorProcessValues";
      statDiagnostics { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "LBC_typeDiagnostics" := (#STATUS_NO_CALL, (), ());
      statEmptyDiagnostics { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "LBC_typeDiagnostics";
      instTimerReachPos {InstructionName := 'IEC_TIMER'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : IEC_TIMER;
      instTimerLeavePos {InstructionName := 'IEC_TIMER'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : IEC_TIMER;
      statReferenceDesignator { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String[20];
      statDisableAlarms { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statEnablePrevious { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statAckPrevious { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statCmdHomePrevious { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statCmdWorkPrevious { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statValid { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statBusy { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statError { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statFbState { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt := #FB_STATE_NO_PROCESSING;
      statFbStatePrevious { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt := #FB_STATE_NO_PROCESSING;
      statErrorUserCleared { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statErrorAutoCleared { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      statDisablingCompleted { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
   END_VAR

   VAR_TEMP 
      tempCmdHomeRisingEdge : Bool;
      tempCmdWorkRisingEdge : Bool;
      tempMoreThanOneCommandPresent : Bool;
   END_VAR

   VAR CONSTANT 
      FB_STATE_NO_PROCESSING : Int := 0;
      FB_STATE_POSITION_NOT_DEFINED : Int := 50;
      FB_STATE_IN_HOME_POSITION : Int := 51;
      FB_STATE_TO_WORK_POSITION : Int := 52;
      FB_STATE_IN_WORK_POSITION : Int := 53;
      FB_STATE_TO_HOME_POSITION : Int := 54;
      FB_STATE_ERROR_HANDLER : Int := 80;
      FB_STATE_DISABLING : Int := 90;
      STATUS_NO_ERROR_OCCURRED : Word := 16#0000;
      STATUS_NO_CALL : Word := 16#7000;
      STATUS_FIRST_CALL : Word := 16#7001;
      STATUS_SUBSEQUENT_CALL : Word := 16#7002;
      STATUS_POSITION_NOT_DEFINED : Word := 16#7003;
      STATUS_IN_HOME_POSITION : Word := 16#7004;
      STATUS_MOVE_TO_WORK_POSITION : Word := 16#7005;
      STATUS_IN_WORK_POSITION : Word := 16#7006;
      STATUS_MOVE_TO_HOME_POSITION : Word := 16#7007;
      SUB_STATUS_NO_ERROR : Word := 16#0000;
      ERR_CONFIGURATION_LEAVE_FEEDBACK_TIME_NEGATIVE : Word := 16#8201;
      ERR_CONFIGURATION_REACH_FEEDBACK_TIME_NEGATIVE : Word := 16#8202;
      ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME : Word := 16#8400;
      ERR_MORE_THAN_ONE_FEEDBACK_PRESENT_AT_SAME_TIME : Word := 16#8401;
      ERR_TIMEOUT_HOME_POSITION : Word := 16#8402;
      ERR_TIMEOUT_WORK_POSITION : Word := 16#8403;
      ERR_INCORRECT_FEEDBACK_WORK_POSITION : Word := 16#8404;
      ERR_INCORRECT_FEEDBACK_HOME_POSITION : Word := 16#8405;
      ERR_MISSING_FEEDBACK_WORK_POSITION : Word := 16#8406;
      ERR_MISSING_FEEDBACK_HOME_POSITION : Word := 16#8407;
      ERR_NOT_LEAVING_HOME_POSITION : Word := 16#8408;
      ERR_NOT_LEAVING_WORK_POSITION : Word := 16#8409;
      ERR_UNDEFINED_STATE : Word := 16#8600;
      NEGATIVE_TIME_NOT_ALLOWED : Time := T#0s;
   END_VAR


BEGIN
  REGION BLOCK INFO HEADER
    //===============================================================================
    // Siemens AG / (c)Copyright 2020
    //-------------------------------------------------------------------------------
    // Title:            LBC_TwoWayActuator_TwoCmd
    // Comment/Function: Controls an actuator between two states (e.g. positions of a valve) with two or one control commands.
    //                   For bi stable state devices.
    // Library/Family:   LBC - Library of Basic Control modules
    // Author:           Siemens Digital Industries
    // Tested with:      S7-PLCSIM Advanced 3.0
    // Engineering:      TIA Portal V16
    // Restrictions:     ENO mechanism is not used - forced to TRUE.
    // Requirements:     PLC (S7-1200 / S7-1500)
    //-------------------------------------------------------------------------------
    // Change log table:
    // Version  | Date       | Expert in charge        | Changes applied
    //----------|------------|-------------------------|-----------------------------
    // 01.00.00 | 15.02.2021 | SIMATIC Systems Support | First released version
    //===============================================================================
  END_REGION BLOCK INFO HEADER

  REGION DESCRIPTION
  (/**/)
  END_REGION DESCRIPTION

  REGION PROCESS INPUT SIGNALS
    // Assign and initialize internal variables
    #statProcessValues.enable := #enable;
    #statProcessValues.commandHomePos := #commandHomePos;
    #statProcessValues.commandWorkPos := #commandWorkPos;
    #statProcessValues.feedbackHomePos := #feedbackHomePos;
    #statProcessValues.feedbackWorkPos := #feedbackWorkPos;

    // Positive edges
    #tempCmdHomeRisingEdge := #statProcessValues.commandHomePos AND NOT #statCmdHomePrevious;
    #tempCmdWorkRisingEdge := #statProcessValues.commandWorkPos AND NOT #statCmdWorkPrevious;
    // Save old values
    #statCmdHomePrevious := #statProcessValues.commandHomePos;
    #statCmdWorkPrevious := #statProcessValues.commandWorkPos;
    // Set temp tag to TRUE if more than one command is present
    #tempMoreThanOneCommandPresent := #statProcessValues.commandWorkPos AND (#statProcessValues.commandHomePos AND NOT #configuration.disableHomeCommand);
    // Copy configuration to static for usage in supervision
    #statDisableAlarms := #configuration.disableAlarms;
  END_REGION PROCESS INPUT SIGNALS

  REGION ALARM ACK
    // Resetting alarms on positive edge of the "ack" bit
    IF (#acknowledge OR #moduleInterface.commands.acknowledge) AND NOT #statAckPrevious AND #statErrorAutoCleared THEN
      #statDiagnostics := #statEmptyDiagnostics;
      #diagnostics := #statEmptyDiagnostics;
      #statFbState := #FB_STATE_POSITION_NOT_DEFINED;
      #statErrorAutoCleared := FALSE;
    END_IF;
    #statAckPrevious := (#acknowledge OR #moduleInterface.commands.acknowledge);
  END_REGION ALARM ACK

  REGION PARAMETER CHECK
    // Check parameter if block is enabled
    IF #statProcessValues.enable THEN
      IF #configuration.monitoringLeavingFeedback < #NEGATIVE_TIME_NOT_ALLOWED THEN
        #statDiagnostics.status := #ERR_CONFIGURATION_LEAVE_FEEDBACK_TIME_NEGATIVE;
        #statDiagnostics.stateNumber := #statFbState;
        #statErrorAutoCleared := TRUE;
        #statFbState := #FB_STATE_ERROR_HANDLER;

      ELSIF #configuration.monitoringReachingFeedback < #NEGATIVE_TIME_NOT_ALLOWED THEN
        #statDiagnostics.status := #ERR_CONFIGURATION_REACH_FEEDBACK_TIME_NEGATIVE;
        #statDiagnostics.stateNumber := #statFbState;
        #statErrorAutoCleared := TRUE;
        #statFbState := #FB_STATE_ERROR_HANDLER;
      END_IF;
    END_IF;
  END_REGION PARAMETER CHECK

  REGION ENABLING/DISABLING
    IF #statProcessValues.enable AND #statDiagnostics.status = #STATUS_NO_CALL THEN // Enable FB
      // First call; initialize FB
      #statValid := TRUE;
      #statBusy := TRUE;
      #statError := FALSE;
      #statErrorUserCleared := FALSE;
      #statErrorAutoCleared := FALSE;
      #statDiagnostics.status := #STATUS_FIRST_CALL;
      #statDiagnostics.subfunctionStatus := #SUB_STATUS_NO_ERROR;
      #statDiagnostics.stateNumber := 0;
      #diagnostics := #statEmptyDiagnostics;
      #statDisablingCompleted := FALSE;

      // Copy configuration to static for usage in associated value of supervision
      #statReferenceDesignator := #configuration.referenceDesignator;

      // Initializes moduleInterface configuration with process configuration
      #moduleInterface.configuration := #configuration;

      // Reset timers
      #instTimerLeavePos.TON(IN := FALSE,
                             PT := #configuration.monitoringLeavingFeedback);
      #instTimerReachPos.TON(IN := FALSE,
                             PT := #configuration.monitoringReachingFeedback);

      // State machine - start functionality
      #statFbState := #FB_STATE_POSITION_NOT_DEFINED;

    ELSIF NOT #statProcessValues.enable AND #statEnablePrevious THEN // Disable FB 
      #statFbState := #FB_STATE_DISABLING;

    ELSIF #statDiagnostics.status = #STATUS_FIRST_CALL THEN // Set status identifier of subsequent call
      #statDiagnostics.status := #STATUS_SUBSEQUENT_CALL;
    END_IF;

    // Edge detection 'enable' input
    #statEnablePrevious := #statProcessValues.enable;
  END_REGION ENABLING/DISABLING

  REGION STATE MACHINE
    REPEAT
      #statFbStatePrevious := #statFbState;

      CASE #statFbState OF // State machine of FB
        #FB_STATE_NO_PROCESSING: // No processing active
          REGION No Processing
            ; // No processing active (Note: this state must always be present and left empty)
          END_REGION No Processing

        #FB_STATE_POSITION_NOT_DEFINED: // If block is enabled move to valid state
          REGION Position/State of the actuator not defined
            // Evaluate commands - only one allowed to be present at the same time
            IF #tempMoreThanOneCommandPresent THEN
              // Write message and stay here - no progress
              #statDiagnostics.status := #ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Only one of n can be checked by using XOR for all of them together
            ELSIF ((#statProcessValues.feedbackHomePos AND NOT #configuration.disableFeedbackHomePos)
              AND (#statProcessValues.feedbackWorkPos AND NOT #configuration.disableFeedbackWorkPos))
            THEN
              // Write message and stay here - no progress
              #statDiagnostics.status := #ERR_MORE_THAN_ONE_FEEDBACK_PRESENT_AT_SAME_TIME;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Checking aa first step the feedbacks
            ELSIF #statProcessValues.feedbackHomePos AND NOT #configuration.disableFeedbackHomePos THEN
              // Set next state
              #statFbState := #FB_STATE_IN_HOME_POSITION;

            ELSIF #statProcessValues.feedbackWorkPos AND NOT #configuration.disableFeedbackWorkPos THEN
              // Set next state
              #statFbState := #FB_STATE_IN_WORK_POSITION;

              // Checking for control commands or position feedback
            ELSIF (#statProcessValues.commandHomePos OR #configuration.disableHomeCommand)
              AND NOT #statProcessValues.commandWorkPos
            THEN
              // Set next state
              #statFbState := #FB_STATE_TO_HOME_POSITION;

            ELSIF #statProcessValues.commandWorkPos
              AND (NOT #statProcessValues.commandHomePos OR #configuration.disableHomeCommand)
            THEN
              // Set next state
              #statFbState := #FB_STATE_TO_WORK_POSITION;

            ELSE // Stay in state and set message
              #statDiagnostics.status := #STATUS_POSITION_NOT_DEFINED;
            END_IF;
          END_REGION Position/State of the actuator not defined

        #FB_STATE_IN_HOME_POSITION: // Actuator is at home position
          REGION In home pos
            #statErrorAutoCleared := FALSE;
            // Set output commands
            #statProcessValues.goToHomePos := #configuration.setOutputHomeContinuously;
            #statProcessValues.goToWorkPos := FALSE;

            // Evaluate commands - only one allowed to be present at the same time
            IF #tempMoreThanOneCommandPresent THEN
              // Write message and stay here - no progress
              #statDiagnostics.status := #ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Go to Work position - rising edge on command
            ELSIF #tempCmdWorkRisingEdge AND (NOT #statProcessValues.commandHomePos OR #configuration.disableHomeCommand) THEN
              // Set next state
              #statFbState := #FB_STATE_TO_WORK_POSITION;

              // Missing feedback for home position
            ELSIF NOT #statProcessValues.feedbackHomePos AND NOT #configuration.disableFeedbackHomePos THEN
              #statDiagnostics.status := #ERR_MISSING_FEEDBACK_HOME_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Opposite feedback work appeared
            ELSIF #statProcessValues.feedbackWorkPos AND NOT #configuration.disableFeedbackWorkPos THEN
              #statDiagnostics.status := #ERR_INCORRECT_FEEDBACK_WORK_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

            ELSE // Stay in state and set message
              #statDiagnostics.status := #STATUS_IN_HOME_POSITION;
            END_IF;
          END_REGION In home pos

        #FB_STATE_TO_WORK_POSITION: // Moving the actuator towards "work" position
          REGION To work pos
            #statErrorAutoCleared := FALSE;
            // Set output commands
            #statProcessValues.goToHomePos := FALSE;
            #statProcessValues.goToWorkPos := TRUE;

            // Start monitoring leaving home position
            #instTimerLeavePos.TON(IN := NOT #configuration.disableFeedbackHomePos,
                                   PT := #configuration.monitoringLeavingFeedback);
            // Start monitoring reaching work position 
            #instTimerReachPos.TON(IN := TRUE,
                                   PT := #configuration.monitoringReachingFeedback);

            // Arriving at Work position - feedback present OR feedback disabled and time has expired
            IF (#statProcessValues.feedbackWorkPos AND NOT #configuration.disableFeedbackWorkPos) OR
              (#instTimerReachPos.Q AND #configuration.disableFeedbackWorkPos)
            THEN
              // Set next state
              #statFbState := #FB_STATE_IN_WORK_POSITION;

              // Evaluate commands - only one allowed to be present at the same time
            ELSIF #tempMoreThanOneCommandPresent THEN
              // Write message and stay here - no progress
              #statDiagnostics.status := #ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Cancel of go to work position command
              // Program goes back to home position if home command is deactivated
            ELSIF NOT #statProcessValues.commandWorkPos
              AND (#tempCmdHomeRisingEdge OR #configuration.disableHomeCommand)
            THEN
              // Set next state
              #statFbState := #FB_STATE_TO_HOME_POSITION;

              // Time expired for leaving Home position
            ELSIF #statProcessValues.feedbackHomePos AND #instTimerLeavePos.Q THEN
              // Set state and status
              #statDiagnostics.status := #ERR_NOT_LEAVING_HOME_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Time expired for reaching Work position
            ELSIF NOT #statProcessValues.feedbackWorkPos AND #instTimerReachPos.Q THEN
              // Set state and status
              #statDiagnostics.status := #ERR_TIMEOUT_WORK_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

            ELSE // Stay in state and set message
              #statDiagnostics.status := #STATUS_MOVE_TO_WORK_POSITION;
            END_IF;
          END_REGION To work pos

        #FB_STATE_IN_WORK_POSITION: // Actuator is at work position
          REGION In work pos
            #statErrorAutoCleared := FALSE;
            // Set output commands
            #statProcessValues.goToHomePos := FALSE;
            #statProcessValues.goToWorkPos := #configuration.setOutputWorkContinuously;

            // Evaluate commands - both can't be present at the same time
            IF #tempMoreThanOneCommandPresent THEN
              // Write message and stay here - no progress
              #statDiagnostics.status := #ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Go to Home position command
            ELSIF (NOT #statProcessValues.commandWorkPos AND (#tempCmdHomeRisingEdge OR #configuration.disableHomeCommand)) THEN
              // Set next state
              #statFbState := #FB_STATE_TO_HOME_POSITION;

              // Missing feedback for work position
            ELSIF NOT #statProcessValues.feedbackWorkPos AND NOT #configuration.disableFeedbackWorkPos THEN
              #statDiagnostics.status := #ERR_MISSING_FEEDBACK_WORK_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Opposite feedback home appeared
            ELSIF #statProcessValues.feedbackHomePos AND NOT #configuration.disableFeedbackHomePos THEN
              #statDiagnostics.status := #ERR_INCORRECT_FEEDBACK_HOME_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

            ELSE // Stay in state and set message
              #statDiagnostics.status := #STATUS_IN_WORK_POSITION;
            END_IF;
          END_REGION In work pos

        #FB_STATE_TO_HOME_POSITION: // Moving the actuator towards home position
          REGION To home pos
            #statErrorAutoCleared := FALSE;
            // Set output commands
            #statProcessValues.goToHomePos := TRUE;
            #statProcessValues.goToWorkPos := FALSE;

            // Start monitoring leaving home position 
            #instTimerLeavePos.TON(IN := NOT #configuration.disableFeedbackWorkPos,
                                   PT := #configuration.monitoringLeavingFeedback);
            // Start monitoring reaching work position 
            #instTimerReachPos.TON(IN := TRUE,
                                   PT := #configuration.monitoringReachingFeedback);

            // Arriving at Home position - feedback present -OR feedback disabled and Time has expired
            IF (#statProcessValues.feedbackHomePos AND NOT #configuration.disableFeedbackHomePos) OR
              (#instTimerReachPos.Q AND #configuration.disableFeedbackHomePos)
            THEN
              // Set next state
              #statFbState := #FB_STATE_IN_HOME_POSITION;

              // Evaluate commands - only one allowed to be present at the same time
            ELSIF #tempMoreThanOneCommandPresent THEN
              // Write message and stay here - no progress
              #statDiagnostics.status := #ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Command work position has rising edge
            ELSIF #tempCmdWorkRisingEdge
              AND (NOT #statProcessValues.commandHomePos OR #configuration.disableHomeCommand) THEN
              // Set next state
              #statFbState := #FB_STATE_TO_WORK_POSITION;

              // Time expired for leaving Work position
            ELSIF #statProcessValues.feedbackWorkPos AND #instTimerLeavePos.Q THEN
              // Set state and status
              #statDiagnostics.status := #ERR_NOT_LEAVING_WORK_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

              // Time expired for reaching Home position
            ELSIF NOT #statProcessValues.feedbackHomePos AND #instTimerReachPos.Q THEN
              // Set state and status
              #statDiagnostics.status := #ERR_TIMEOUT_HOME_POSITION;
              #statDiagnostics.stateNumber := #statFbState;
              #statErrorAutoCleared := TRUE;

            ELSE // Stay in state and set message
              #statDiagnostics.status := #STATUS_MOVE_TO_HOME_POSITION;
            END_IF;
          END_REGION To home pos

        #FB_STATE_ERROR_HANDLER: // Error handling state
          REGION Error handling
            // Stay here until error is acknowledged
            #statErrorAutoCleared := TRUE;
            // Reset the outputs
            #statProcessValues.goToHomePos := FALSE;
            #statProcessValues.goToWorkPos := FALSE;
          END_REGION Error handling

        #FB_STATE_DISABLING: // Disabling active
          REGION Disabling
            // Switch off control outputs
            #statProcessValues.goToHomePos := FALSE;
            #statProcessValues.goToWorkPos := FALSE;

            #statDisablingCompleted := TRUE;
          END_REGION Disabling

        ELSE // Undefined state in state machine reached
          REGION Undefined state        
            #statDiagnostics.status := #ERR_UNDEFINED_STATE;
            #statDiagnostics.stateNumber := #statFbState;
            #statErrorUserCleared := TRUE;
          END_REGION Undefined state
      END_CASE;

      REGION State change handling
        // Reset the timers if state has changed
        IF #statFbStatePrevious <> #statFbState THEN
          #instTimerLeavePos.TON(IN := FALSE,
                                 PT := #configuration.monitoringLeavingFeedback);
          #instTimerReachPos.TON(IN := FALSE,
                                 PT := #configuration.monitoringReachingFeedback);
        END_IF;
      END_REGION State change handling

      REGION Reset outputs on error      
        // Check if the condition for error must be acknowledged - then move to error handler state
        IF #configuration.resetOutputsOnError AND #statDiagnostics.status.%X15
          AND #statDiagnostics.status <> #ERR_MORE_THAN_ONE_CMD_PRESENT_AT_SAME_TIME
          AND #statDiagnostics.status <> #ERR_UNDEFINED_STATE
          AND #statFbState <> #FB_STATE_ERROR_HANDLER
        THEN
          #statFbState := #FB_STATE_ERROR_HANDLER;
        END_IF;
      END_REGION Reset outputs on error

      // Leave state machine if state has not changed or error is present
      // Stay in state machine if state has changed and no error is present
    UNTIL (#statFbStatePrevious = #statFbState OR #statDiagnostics.status.%X15)
    END_REPEAT;
  END_REGION STATE MACHINE

  REGION CONFIGURATION HANDLING
    // Refresh module interface configuration with process configuration
    IF #moduleInterface.commands.refreshConfiguration AND NOT #moduleInterface.commands.editConfiguration THEN
      #moduleInterface.configuration := #configuration;
    END_IF;
    #moduleInterface.commands.refreshConfiguration := FALSE;

    // Save module interface configuration to process configuration
    IF #moduleInterface.commands.saveConfiguration AND #moduleInterface.commands.editConfiguration THEN
      #configuration := #moduleInterface.configuration;
      #statReferenceDesignator := #configuration.referenceDesignator;
      #moduleInterface.commands.saveConfiguration := FALSE;
    END_IF;
  END_REGION CONFIGURATION HANDLING

  REGION PROCESS OUTPUT SIGNALS
    // Write outputs
    IF #statDisablingCompleted THEN
      REGION Disabling
        // Reset outputs if disabling completed
        #statValid := FALSE;
        #statBusy := FALSE;
        #statError := FALSE;
        #statErrorUserCleared := FALSE;
        #statErrorAutoCleared := FALSE;
        #statDiagnostics.status := #STATUS_NO_CALL;
        // Execution finished --> set state no processing
        #statFbState := #FB_STATE_NO_PROCESSING;
      END_REGION Disabling

    ELSIF #statErrorUserCleared AND NOT #statError THEN
      REGION Error user cleared
        // Error can only be cleared by user; rising edge at enable input is needed to continue 
        #statValid := FALSE;
        #statBusy := FALSE;
        #statError := TRUE;
        // Write diagnostics
        #diagnostics := #statDiagnostics;
        // Execution aborted --> set state no processing
        #statFbState := #FB_STATE_NO_PROCESSING;

        // switch off control outputs
        #statProcessValues.goToHomePos := FALSE;
        #statProcessValues.goToWorkPos := FALSE;
      END_REGION Error user cleared

    ELSIF #statErrorAutoCleared AND NOT #statError THEN
      REGION Error auto cleared
        // Error can be reset by FB automatically
        #statValid := FALSE;
        #statBusy := TRUE;
        #statError := TRUE;
        // Write diagnostics
        #diagnostics := #statDiagnostics;
      END_REGION Error auto cleared

    ELSIF NOT #statErrorAutoCleared AND NOT #statErrorUserCleared AND #statError THEN
      REGION After user/auto cleared
        // If auto cleared error is acknowledged
        #statValid := TRUE;
        #statBusy := TRUE;
        #statError := FALSE;
      END_REGION After user/auto cleared
    END_IF;

    REGION Write monitoring structure
      #statProcessValues.inHomePos := #statFbState = #FB_STATE_IN_HOME_POSITION;
      #statProcessValues.inWorkPos := #statFbState = #FB_STATE_IN_WORK_POSITION;
    END_REGION Write monitoring structure

    REGION Write Process data to module interface
      #statProcessValues.error := #statError;
      #moduleInterface.monitoring := #statProcessValues;
      #moduleInterface.diagnostics := #statDiagnostics;
    END_REGION

    REGION Write work data to interface and outputs    
      // Function status
      #goToHomePos := #statProcessValues.goToHomePos;
      #goToWorkPos := #statProcessValues.goToWorkPos;

      #inHomePos := #statProcessValues.inHomePos;
      #inWorkPos := #statProcessValues.inWorkPos;

      // Write status outputs
      #valid := #statValid;
      #busy := #statBusy;
      #error := #statError;
      #status := #statDiagnostics.status;
      // ENO mechanism disabled, ENO - forced to TRUE
      ENO := TRUE;
    END_REGION Write static values to outputs    
  END_REGION PROCESS OUTPUT SIGNALS

END_FUNCTION_BLOCK

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 科控物联 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Input参数
  • In/Out参数
  • 用户定义的数据类型
  • LBC_typeTwoWayActuatorInterface(UDT)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档