[控场AI]
· 10 分钟阅读· 5,067 字

AI Agent 通过 MCP 为西门子 S7-1500 编写 SCL 程序

AI Agent 通过 MCP 为西门子 S7-1500 编写 SCL 程序

AI Agent 经 MCP 桥驱动 TIA Portal,独立完成 S7-1500 分拣程序全流程并主动划清能力边界。

本文记录了一次真实的工业控制实验:通过自研 MCP 服务器 TiaLink 把 TIA Portal V19 的 Openness API 暴露给 AI Agent,让它为 S7-1500 编写输送带分拣控制程序,并在 S7-PLCSIM 中完成「添加 CPU→编译→仿真→建 FB/UDT→写 SCL→下载→验证」的完整闭环。Agent 先搭建验证环境再写代码,交付了 11 状态的状态机、两处关键设计(每周期确定性输出写入、双气缸软件互锁)、状态转换表、14 个测试用例和 12 项竞态分析。更值得注意的是它明确拒绝三件事:替代硬件安全回路实现急停、替代气动硬互锁、在仿真中整定时间参数。作者提醒仿真通过不等于现场就绪,且工具为自研,视角需打折。

把大语言模型接到西门子 TIA Portal 上,让它独立完成一个输送带分拣控制程序——这已经不只是概念验证了。

有人真的搭了一套 MCP 服务器(TiaLink),把 TIA Portal V19 的 Openness API 暴露给 AI Agent(WorkBuddy广告),然后给了它一个真实工程任务:为 S7-1500(CPU 1511-1 PN)实现输送带分拣控制,并在 S7-PLCSIM 中验证。

rss source: An AI Agent Programmed a Siemens S7-1500 Through an MCP Bridge

不是「生成一段代码片段」,而是完整闭环:添加 CPU → 编译 → 启动仿真 → 创建 FB/UDT → 编写 SCL → 编译 → 下载 → 验证。

最有意思的不是代码本身,而是 Agent 做了哪些工程决策,以及在哪些地方它明确拒绝越界。

工具链与任务设定

整套工具链分三层:Agent(WorkBuddy)负责读规格、规划步骤、写代码和测试;MCP 桥(TiaLink)把 TIA Portal 操作暴露为 MCP 工具——添加设备、创建块、写 SCL、编译、下载、回读;目标环境是 TIA Portal V19 + Openness,验证在 S7-PLCSIM 中完成。桥接程序与 TIA Portal 跑在同一台工业 PC 上,Agent 可以远程接入。

任务规格相当具体:SCL 状态机状态号必须与规格一致(方便 HMI、报警、测试和现场调试引用同一套编号);逻辑封装为带独立背景 DB 的可复用 FB;输入/输出/内部变量用 i_ / q_ / stat_ 前缀清晰分离;使用 IEC 定时器 TON_TIME 而非手写扫描周期累加;实现入口去重、质量结果锁存、双气缸互锁、故障锁存、手动复位、正常停止等功能。

还有一条关键要求:每个扫描周期所有输出必须写入确定值,不依赖上一周期残留。以及最末尾那一句话:「先添加一个 CPU,检查仿真器是否可用。」

这句话恰恰是测试的重点。配置类任务靠截图就能判断,但程序要靠行为判断。Agent 会先搭建验证环境,还是直接开始写代码?

MCP(Model Context Protocol) 是由 Anthropic 于 2024 年底提出的开放协议,用于在 AI 模型与外部工具/数据源之间建立标准化接口。它的核心思路类似于「AI 世界的 USB-C」:把任意软件能力(文件系统、数据库、工业软件 API)封装为统一的工具描述,模型即可通过结构化调用完成操作。在本文场景中,TiaLink 把 TIA Portal 的 Openness API 逐项映射为 MCP 工具,Agent 便无需理解底层 COM 接口细节,只要按 MCP 协议发起「添加设备」「写 SCL」等调用即可。

Siemens Openness API 是西门子官方提供的 TIA Portal 自动化接口,基于 .NET/COM,允许外部程序以编程方式完成项目创建、硬件组态、块生成、编译和下载等操作,通常用于批量工程、版本迁移和 CI 场景。它是 TiaLink 能够「遥控」TIA Portal 的底层基础,但本身并不面向大语言模型,需要 MCP 桥做一层语义化封装。

Agent 的执行顺序与状态机设计

Agent 选择的顺序是:先检查是否已有 CPU,然后添加 PLC_1(CPU 1511-1 PN);编译并启动 S7-PLCSIM,确认下载/运行正常;创建 FB_ConveyorSort 并编写 SCL 状态机;创建所需 UDT;在 OB1 中调用 FB,使用背景 DB DB_ConveyorSort_1;编译下载无错误;最后交付状态转换表、14 个测试用例和竞态/边界分析。

它先搭建了验证环境——这是一个好信号。

状态机横跨 0 到 100 共 11 个状态:INIT(首次扫描,清除锁存和故障码)→ READY(等待启动)→ FEED(输送运行,入口去重、质量锁存、分拣超时监控)→ CHECK(停在分拣位,根据锁存结果分支)→ PUSH_A / PUSH_B(OK 推 A 缸,NG 推 B 缸)→ RETRACT(确认缩回到位)→ DISCHARGE(等待工件离开分拣位)→ 回到 FEED。此外还有 FAULT(故障锁存,所有输出关闭)和 STOPPED(正常停止,可重启)。

值得注意的设计细节:30(CHECK)状态直接根据锁存结果决定走 50 还是 60,不做任何实时判断;70(RETRACT)状态同时监控缩回限位和超时定时器,超时则跳转到故障态。

SCL 代码中的两个核心设计

Agent 交付的完整 FB 代码里,有两处设计值得细看。

Section 0 的确定性输出写入。 每个扫描周期开始时,先把所有输出全部写为 FALSE 或确定值,再在后续逻辑中按需置位。这直接回应了规格中「每个输出每周期必须有确定值」的要求。如果程序员习惯性地只在条件满足时写输出,一旦前一周期的残留值没有被覆盖,就可能产生危险行为。

Section 7 的互锁与输出映射。 气缸 A 伸出需要同时满足三个条件:有 A 伸出请求、没有 B 伸出请求、B 缸已确认缩回。气缸 B 同理。缩回输出直接取伸出输出的非值——对于双作用气缸,这是去 energized 即安全的方向。

代码注释里 Agent 还专门标注:对于弹簧复位气缸,缩回输出应强制为 0(失电即缩回),而不是主动驱动。

安全逻辑方面,Section 2 只读取 i_xSafetyOK 作为安全回路状态输入,并在注释中明确写出「不要在这里实现安全功能」。Section 3 做了传感器合理性检查——如果同一气缸的伸出限位和缩回限位同时为 1,立即触发故障。Section 5 的故障复位要求操作者按下复位按钮、安全回路恢复、且所有传感器矛盾消失,缺一不可。

SCL(Structured Control Language) 是 IEC 61131-3 标准定义的高级结构化文本语言,在西门子 TIA Portal 中与梯形图(LAD)、功能块图(FBD)并列,语法接近 Pascal,支持 IF/CASE/FOR 等结构,特别适合编写状态机、算法和复杂分支逻辑。本文中 Agent 生成的状态机、互锁和定时器逻辑全部用 SCL 表达,原因是它比图形化语言更容易被文本模型准确生成和校验。

FB(Function Block)与背景 DB 是西门子 PLC 编程中的关键概念。FB 是可带「记忆」的可复用逻辑单元,其内部静态变量存放在独立的背景数据块(Instance DB)中,同一定时器、边沿检测器在不同调用实例间互不干扰。这正是文中「多实例」竞态条件的技术根源:如果多条产线共用同一个背景 DB,定时器状态会被互相覆盖。UDT(用户自定义数据类型)则用于把一组相关变量打包成结构体,便于在 FB 接口和 HMI 之间传递。

它主动标记的 12 个竞态与边界条件

这部分是整篇记录里最有工程价值的内容。Agent 在交付代码的同时,明确列出了 12 个需要注意的竞态条件和边界情况:

  1. 入口去重与传感器卡滞——锁存直到工件离开入口光电才去重,但如果工件因为卡滞没有离开,后续工件就会被漏掉。工艺必须保证单件间距。

  2. 质量结果的锁存时机——锁存在入口而非分拣位,因为质量系统结果到达分拣位时可能还不稳定,会和位置信号产生竞态。如果质量检测很慢,应该用手势/队列机制,而不是简单地延迟读取。

  3. 到达与超时在同一扫描周期——IEC TON 在达到 PT 的那个扫描周期将 Q 置为 TRUE。代码先检查超时再检查到达,到达时显式复位定时器。如果想要「到达优先」,必须调整顺序。

  4. 推料后的重复触发——工件推走后可能短暂遮挡分拣位光电。如果从 70 直接回 20,会造成双重分拣。状态 80(DISCHARGE)等待光电信号清除后才重新武装。

  5. 互锁的层级——软件互锁只阻止逻辑上的同时请求,不能替代气动/电气硬互锁或机械限位。

  6. 同扫描周期内的按钮优先级——故障/安全 > 停止 > 复位 > 启动,这个优先级必须冻结在需求文档里,否则不同实现会分歧。

  7. 停机的两种含义——立即停止还是完成当前工件后停止。代码实现的是立即停止(状态 100),如果需要受控完成,需要增加 StopPending 标志。

  8. PT = 0 边界——TON 会立即触发,可能把超时变成必然故障。如果时间参数可被 HMI 修改,必须校验下限。

  9. 复位按钮长按——使用边沿触发,长按不会持续掩盖反复出现的故障。

  10. 首次扫描初始化——状态 0 完成初始化,实际项目还应该使用 OB100。保留状态 0 是为了让初始化在状态机内部可见且可测试。

  11. 多实例——定时器和边沿存储都在 FB 静态变量中,绝对不能在多条产线之间共用一个背景 DB。

  12. 仿真 ≠ 现场——仿真器不模拟光电抖动、气动延迟或安全回路响应时间。所有时间参数必须在真机上整定。

IEC 定时器 TON_TIME 是 IEC 61131-3 定义的标准接通延时定时器:当 IN 为 TRUE 时开始计时,累计到预设时间 PT 的那个扫描周期将 Q 置为 TRUE;IN 变 FALSE 时立即复位。它的时间基准由 PLC 系统时钟提供,精度远高于「用手写扫描周期计数器累加」的做法,后者会因扫描周期抖动而失真。文中的边界条件 8(PT = 0)正来源于 TON 的语义——PT 为 0 时 Q 会在同一周期立即置位,若时间参数来自 HMI 而未做下限校验,就会把「超时保护」变成「必然故障」。

扫描周期(Scan Cycle) 是 PLC 运行的基本节拍:读取输入映像→执行用户程序→刷新输出映像,循环往复,典型周期在毫秒级。所有状态机、互锁和定时器逻辑都在这个节拍内评估。所谓「每个周期输出必须写确定值」,本质就是对抗输出映像的残留效应——若某周期条件不满足而跳过写操作,输出会保持上一周期的值,在安全相关场景中可能造成危险。

它明确拒绝做的三件事

这部分是作者认为最值得写出来的原因。

AI Agent 在完成软件部分后,明确把三件事交还给了人类:

急停必须由硬件安全回路实现(安全继电器/安全 PLC)。程序只读取 i_xSafetyOK 作为状态输入,不承担安全功能。

双气缸硬互锁必须由气动或电气方案实现。软件互锁只是补充手段,不能替代。

时间参数和传感器整定必须在真机上完成。仿真器无法提供真实的光电抖动或气动延迟数据。

它做完了软件能做的部分,然后把它无法验证的责任交还给人,没有假装「完成」了做不到的事。

作者在结尾写道:「这就是我对任何接触工业控制的代码生成器的期望——生成可验证的部分,并明确说明它无法验证的部分。」

诚实的局限性

作者自己也列出了几条限制:仿真通过不代表可以上现场;他只验证了代码编译、下载和逻辑层面的测试用例匹配,没有在真实硬件上做台架测试;Agent 的自报告步骤日志需要带着通常的怀疑态度看待。

仿真器不模拟光电传感器抖动、气动阀响应延迟、安全回路断电时间——所有这些都必须在真实设备上调参。一个在 PLCSIM 里跑通的状态机,距离在现场稳定运行还有相当的距离。

另外值得注意:Agent 和 TIA Portal MCP 桥都是作者团队(汇智网)自研工具,视角上需要打一个折扣。

一个 AI Agent 能独立完成从环境搭建到代码交付的完整 PLC 编程闭环,这个事实本身就值得关注。但更值得关注的,是它知道自己能力的边界在哪,并且没有试图跨越它。

#AI Agent PLC 编程#西门子 S7-1500#MCP 协议#SCL 状态机#TIA Portal Openness#工业自动化 AI#PLC 竞态条件
分享:

相关推荐