使用西门子TIA Portal构建结构化文本状态机

文章概要

继续探索UDFB中封装的PLC状态机。前文已介绍梯形图形式的UDFB。本文通过结构化文本方案对UDFB进行扩展和优化。面向中级PLC程序员,助其迈向程序结构与组织的新阶段。

stopwatch_00 预计阅读时间:6分钟

延伸阅读

本工程简报是西门子TIA Portal UDFB系列讨论的权威篇章,基于图1所示的西门子S7-1200 CPU 1215 FC开发测试。关联文章包括:

电机启动器的结构化文本 UDFB 入门

用户自定义功能块(UDFB)是可编程逻辑控制器(PLC)编程的基石。UDFB将PLC代码封装为便捷容器,可实例化集成至大型程序。当UDFB集合构成PLC核心库时,其强大功能与便捷性尤为显著。程序员可在PLC软件工具支持下,自由选择IEC 61131-3标准语言编写UDFB。

本工程简报延续西门子TIA Portal UDFB专题讨论,基于西门子S7-1200 CPU 1215 FC开发测试。前文介绍了控制监测三相电机启动器的梯形图UDFB。本期提供采用结构化文本(ST)构建的等效UDFB,其特性如图1所示case语句。

这是一项有价值的练习,因为用不同语言构建相同逻辑功能可以让我们对比结果。随后我们就能定性判断哪种方法对技术人员和PLC程序员更有利。

假定读者已具备梯形图和结构化文本的使用经验。假定读者能流畅转换组合逻辑电路语言,并掌握移动函数的使用。

可下载UDFB功能块说明:

1 :展示case语句的结构化文本,根据无符号整数uiState的值控制状态机行为。

作者思考(经验) :若不提及AI的发展现状,本文就不算完整。或许你听说过"氛围编程",以及AI带来的希望与风险。

我认为AI是强大工具,能协助组织甚至编写PLC中较为复杂的结构化代码。这在UDFB设计中尤为明显,因其问题空间定义明确且范围有限。这正是发挥AI优势的理想场景。

这是否意味着程序员将被取代?我深表怀疑,因为大型PLC程序绝非简单。控制领域仍需要懂行的程序员来理解PLC程序与设备运行的关系。基于梯形图的解决方案在实时调试方面也持续具有优势。

或许我们可以达成共识:职责将从底层程序员转向PLC架构师,由AI构建底层模块。

技术提示 :示例程序采用匈牙利命名法。此惯例在PLCopen编码指南中有说明。虽然优先级较低,但在教学或协作环境中很有用,能提升程序可读性。在UDFB中尤为实用,能清晰标识每个类型,这在顶层梯形图中实例化UDFB时特别有帮助。

本文使用的类型前缀如下:

  • x = 布尔类型
  • ui = 无符号整数类型
  • tim = 时间类型
  • str = 字符串类型(字符数组)

此外,我们使用St前缀表示状态常量。如下一节所示,这极大提高了程序可读性。

电机启动器 UDFB 的状态逻辑回顾

向下箭头展开摘要

前文中我们通过状态描述了电机启动器控制逻辑。为方便起见,此处再次列出状态与故障触发条件:

电机启动器状态

该UDFB包含五种状态。通过监测电机启动器辅助触点的反馈信号,可检测到各状态关联的基础故障。

  1. 断开状态 :电机启动器处于未激活状态,接触器线圈未通电。若电机启动器意外闭合超过timGlitch时长,UDFB将进入故障状态。这种情况可能发生在技术人员使用绝缘螺丝刀强制闭合电机启动器衔铁时。

  2. 闭合 中状态:电机启动器接触器正从断开状态向物理闭合状态过渡。若触点未在timTransition时限内完成闭合,UDFB将进入故障状态。图1展示了因此状态触发故障的UDFB。

  3. 闭合状态 :关联电机上的启动器正在运行。若传感器信号丢失超过timGlitch时长,UDFB将进入故障状态。该故障可能由连接电机启动器或反馈线路的驱动线松动引起。也可能是过载事件导致热过载模块触发电机启动器跳闸。

  4. 断开 中状态:电机启动器接触器正从闭合状态向断开状态过渡。若触点未在timTransition时限内完成断开,则触发故障——这表明主继电器或中间继电器触点已熔焊。

  5. 故障状态 :电机启动器处于故障状态。当使能信号禁用且复位按钮按下时,故障状态将解除。

结构化文本 UDFB 的组成要素

该结构化文本UDFB采用状态机架构。此结构体现在此代码片段中。我们从一个根据#uiState中存储的值进行切换的case语句开始。然后,与之前的梯形图逻辑程序类似,我们使用常量枚举各个状态。例如,uiStClosed映射到十进制值2,该值被定义为无符号整数。请务必查阅前一篇文章以获取状态的完整描述。

CASE #uiState OF
    #uiStOpen:
        ;
    #uiStClosing:
        ;
    #uiStClosed:
        ;
    #uiStOpening:
        ;
    #uiStFault:
        ;
    ELSE
        ;
END_CASE;

电机启动器 UDFB 的状态结构

每个状态都设计为以下结构:

  • 默认定时器配置。

  • 基于xEnable的状态变化。此UDFB对xEnable作为主要输入是电平敏感的。正常情况下,状态机将在到达uiStClosed和uiStOpen的过程中经过过渡状态uiStClosing和uiStOpening。

  • 基于xSensor的状态变化。此输入是主要的反馈机制,用于确保电机启动器响应并在正确时间进入正确状态。

  • 基于定时器超时的状态变化,例如当电机启动器接触器未能在timTransition时间内闭合时。

  • 四个UDFB布尔输出的逻辑。

技术提示 :虽然梯形图和状态机实现看起来不同,但它们本质上是相同的结构。回想一下,描述该代码需要五个梯形图网络。现在,在此示例中,我们看到它需要大约100行结构化文本代码。

请注意,高级(单次使用)定时器实现扩展了结构化文本的规模。

此外,为了代码结构的一致性,结构化文本中存在一些冗余。这在uiStClosed状态中最为明显,其中ELSIF语句检查xSensor,而我们已知关键数据已隐含在xTimedOut变量中。要理解此语句,请考虑当输入xTimerEnable := NOT #xSensor时TON的操作。

电机启动器 UDFB 的定时器考量

PLC的定时器在程序循环过程中会消耗有限的内存和时间。在之前的梯形图解决方案中,我们特意通过使用四个独立的定时器来优先考虑清晰性。

在此结构化文本实现中,我们使用了一个TON定时器的单一实例,该实例在四个状态间共享。使用单一计时器会增加复杂度,因为该计时器需要包含多行代码:

  • 定时器实例化
  • 加载特定状态的定时器预设时间(PT)
  • 维护特定状态的定时器激活(在正确时间启用)
  • 判断定时器是否到期的条件语句

定时器实例化示例

以下代码片段包含了定时器实例化。这是名为Timer的TON定时器的典型实例化。启用输入信号映射到xTimerEnable,PT映射到变量tiDelay。最后为了程序清晰度,Q输出映射到局部变量xTimedOut。

(* This single TON is used across multiple states
     CAUTION: Be sure to momentarily turn off (reset) the TON's enable signal for each state transition.
*)

"Timer".TON(IN:=#xTimerEnable,
            PT:=#timDelay);

#xTimedOut := "Timer".Q;

技术提示 :在多个状态间复用定时器时,必须确保在状态转换重新加载PT时禁用启用信号。这可以避免TON的Q输出意外变化,进而触发非预期的状态转换。

定时器重载与激活示例

以下代码片段展示了电机启动器开启状态的逻辑。共有五行代码与定时器相关。

  • 本状态第一行代码根据传感器状态启用定时器。第二行将PT设置为timGlitch输入值。这样就能使定时器具备消除触点抖动等干扰的能力。

  • 可以看到每个状态转换都关联了#xTimerEnable := FALSE;语句。注意这些本质上都是单次触发操作。因此定时器将仅停用一个周期。

  • 最后可以看到使用#xTimedOut值的IF语句。该语句会在传感器未在timGlitch时间内切换时强制跳转到故障状态。

    #uiStOpen:
        
        #xTimerEnable := #xSensor;          // Allow for contact bounce
        #timDelay := #timGlitch;
        
        IF #xEnable THEN
            #uiState := #uiStClosing;
            #xTimerEnable := FALSE;
        ELSIF #xSensor AND #xTimedOut THEN  // Technically, there is no need to check #xSensor as the value is reflected in the TON.Q. Retain the structure for clarity.
            #uiState := #uiStFault;
            #xTimerEnable := FALSE;
            #strFaultCondition := 'Contactor Forced';
        END_IF;
        
        #xCoilDrive := FALSE;
        #xValid := TRUE;
        #xBusy := FALSE;
        #xFault := FALSE;

结构化文本程序的实时监控与调试

实时监控与调试是PLC操作人员必备的核心技能。这包括维修技师、安装人员以及原始程序开发员。梯形图凭借其图形化的梯级、触点和线圈高亮显示,具有直观易读的显著优势。但必须认识到,PLC调试工具并不局限于梯形图语言。

结构化文本同样具备如图2所示的实时监控功能。图中展示的是运行在西门子S7-1200 CPU 1215 FC上的UDFB功能块实时运行状态。

图2中添加了系列编号以便清晰标识目标变量。首先可见绿色高亮区块表明IF条件判断为真。同时展开的绿色结果框下拉箭头显示了IF语句中所有变量的当前值。

该条件语句的语义是:当功能块禁用、传感器(电机辅助反馈)禁用且复位按钮按下时,退出故障状态。红色标注数字对应IF语句中的变量位置及右侧调试窗口显示。

可见xEnable、xSensor和xReset的值分别为FALSE、FALSE和TRUE。仔细观察发现IF语句中对xEnable和xSensor进行了取反运算。综合来看,三个条件实际均为真值,故IF判断成立。

虽然过程不复杂,但由于右侧调试窗口未显式显示NOT运算符,会略微增加认知负担。与梯形图不同,我们需要同时考虑变量值及其修饰符(如取反操作)。梯形图的简洁性优势在凌晨三点的应急维修场景中尤为明显。

2 :结构化文本实时调试界面截图,显示IF语句判断为真。

结构化文本是否优于梯形图?

严格来说并非如此!

最佳编程语言应当是在设备生命周期内能最大限度减少停机时间的方案。切记每分钟100至1000美元不等的停机损失,会迅速抵消前期设备或编程投入。

笔者认为梯形图与结构化文本之争需要综合考量:

  • PLC类型
  • 受控设备类型
  • 程序复杂度,包括总操作数及层次化设计
  • 劳动力培训,尤其考虑到技术人员可能无暇钻研结构化文本
  • 人员流动率
  • AI编程的兴起明显倾向于辅助结构化文本

结语

如这两篇文章所示,梯形图与结构化文本可采用相似逻辑设计——即以uiState维护状态的状态机流畅切换两种语言的能力是每位PLC程序员都应掌握的技能

如同弓箭手,我们需通过在不同位置射出一千箭而非同一位置重复千次来习得准度换言之,应探索多种PLC及编程语言,因不存在万能方案且职业生涯中必将遭遇诸多变体

相关文章

若喜欢本文,这些相关文章或许对您有所助益:

内容提要

  • 回顾用于控制监测三相电机启动器的UDFB封装状态机运作
  • 跨多状态共用定时器的使用准则
  • 关于"梯形图是否优于结构化文本"这一经典问题的指引
  • 提供系列学术严谨的问题集
  • 此处可下载结构化文本PDF: UDFB_ST.pdf (148.0 KB)