跳到正文
Learn-LAD
PLC AI 实战/投运前先仿真:下载到虚拟 PLC 跑起来

投运前先仿真:下载到虚拟 PLC 跑起来

把编译通过的程序下载到 S7-PLCSIM Advanced,按场景表跑行为、记录实测值,并知道 403、ResetModule、I/O 未配置这些故障怎么定位。

进阶 第 3 课 35 分钟 TiaLink

学完你能:能用虚拟 PLC 完成一次黑盒行为验证:注册/上电/下载/运行,按场景表拿到实测数据,并分清编译验证与行为验证的边界。

概述

前几课的最后一关都是「编译 0 错误 0 警告 + 读回核对」——那证明的是块本身一致、结构没被改坏。这一课把验证再往前推一步:让程序真的跑起来。把程序下载到 S7-PLCSIM Advanced 的虚拟 PLC,按一张场景表给输入、看输出,把每个场景的实测值记下来。

本课流程已在 TiaLink 1.1.0.0 + TIA Portal V19 + S7-PLCSIM Advanced 6.0 上实测:对象是示例库的排风机控制(S7-1500,一个网络,TOF 1 分钟)。新建一台 CPU 1516-3 PN/DP、插一块 DI 和一块 DQ 后编译 0 错误 0 警告;注册实例、上电、下载、RUN 一次通过;4 个场景都拿到了实测值。

实测还抓到一个「编译查不出、看图容易读错」的行为:按停止按钮后排风机不会立即停。这个网络的 TOF 输入是 Turn_On_PB AND NOT Turn_Off_PB——松开按钮和按停止按钮对 TOF 来说是同一个下降沿,风机都会继续排风 1 分钟。看一眼图很容易读成「按停止就立即停」,行为只能由实测说了算——这就是本课要示范的事。

口径:仿真通过 ≠ 现场验收。PLCSIM Advanced 只仿真 CPU 的行为,总线、HMI、驱动、安全回路都不在仿真范围内;安全逻辑、联锁与急停仍必须人工评审。

你将学会

  • 用 /sim/status 判断这台机器能不能仿真(TiaLink 带 --no-sim、或没装 S7-PLCSIM Advanced 时,/sim/* 全部 403);
  • 虚拟 PLC 的固定顺序:注册实例 → 上电 → 等 Stop → 下载 → RUN,以及「新注册的实例是空的」意味着什么;
  • 把一段需求变成场景表(正常 / 边界 / 复位),用标签名或 I/O 地址做黑盒验证;
  • 处理典型故障:1516 无板载 I/O 的编译警告、ResetModule 下载失败、tag 列表没刷新;
  • 交付一份「场景表 + 实测值 + 结论」,并分清哪些东西不在仿真范围内。

前置条件

  • Windows 机器,已安装 TIA Portal V19;
  • TiaLink 已启动且没有加 --no-sim,并已连接你的沙盒工程;页首状态条会自动检测。仿真前先确认运行时可用:http://localhost:8080/api/v1/sim/status 里 available=true(本课实测机器装的是 S7-PLCSIM Advanced 6.0)。S7-PLCSIM Advanced 需要单独安装,TiaLink 不会替你装;没装或禁用时 /sim/* 一律返回 403;
  • 一个支持 Streamable HTTP MCP 的客户端(Claude Code、Cursor、VS Code 等),MCP 端点为 http://localhost:8080/mcp;
  • 一台 S7-1500 工程(PLCSIM Advanced 仿真的是 1500;本课用 CPU 1516-3 PN/DP)。示例页导入的是块和点表、不含设备:空工程要先补一台 CPU;1516 没有板载 I/O,还要插一块 DI、一块 DQ(或者接受那条编译警告);
  • 练习对象:示例库排风机控制;
  • 三条纪律:用沙盒工程(下载会自动打开工程的两个仿真属性、并清除新 1500 的默认保护);不保存(下载 ≠ 保存);仿真只做行为验证,不作为安全验收。

步骤

真实使用只有一次输入:说清「把哪个程序、跑哪些场景、要实测值」。建 CPU、插模块、导入、编译、注册实例、下载、读写、填表,都是 agent 做的。你要做的只有两处:下载时如果 TIA 弹授权窗点一下确认,以及最后看一眼场景表。

第一步:配好 TiaLink 与 MCP

在博途那台机器上启动 TiaLink、打开沙盒工程。页首状态条会自动检测;然后在客户端里加一个 Streamable HTTP MCP 服务:

先在本页顶部点「设置」填一次地址(存在本机,示例库页面也用同一个地址),下面的 URL 会跟着更新,点「复制」直接贴进客户端配置:

MCP
{
  "mcpServers": {
    "tialink": {
      "type": "http",
      "url": "http://localhost:8080/mcp",
      "headers": { "Authorization": "Bearer <你的 TiaLink API Token>" }
    }
  }
}

看到什么:客户端列出 TiaLink 的工具(名字以 tialink_ 开头,能看到 tialink_sim_read / tialink_sim_write 这组就对了)。也可以先在浏览器打开 http://localhost:8080/api/v1/sim/status:available=true 说明 S7-PLCSIM Advanced 就绪;403 说明 TiaLink 禁用了仿真(--no-sim)或机器上没装。

第二步:你输入的(全部内容)

把下面这段发给 agent(练习对象换成你的程序):

用 S7-PLCSIM Advanced 把当前工程的程序跑起来验证行为,不要保存工程。工程里现在没有设备,请:

  1. 新建一台 S7-1500(CPU 1516-3 PN/DP;1516 没有板载 I/O),给它插一块 DI、一块 DQ,地址从 0 开始;
  2. 导入示例库的「排风机控制」(点表 → 系统实例 DB → Main),编译到 0 错误 0 警告;
  3. 注册一个仿真实例,上电、下载、RUN;
  4. 按下面的场景表逐条执行,把实测值写进表里(不要拿期望值当结果):
    • S1:Turn_On_PB=1 → 看 Stove、Exhaust;
    • S2:Turn_On_PB=0,等 5 秒 → 看 Stove、Exhaust;
    • S3:再等到 60 秒以后 → 看 Exhaust 是否变 0;
    • S4:重新启动,然后按 Turn_Off_PB=1 → 看两个输出,以及 Exhaust 多久变 0;
  5. 最后交付:场景表(含实测值)+ 一句结论。如果实测和预期不一致,先说明原因,再决定要不要改程序。

发完这一条,你等着看结果就行。下面是它实际会做的事(本次实测过程)。

第三步:agent 实际做了什么(1)——把工程准备到可下载

  • 新建 S7-1500 / CPU 1516-3 PN/DP,插 DI、DQ 两块模块(槽 2、槽 3,起始地址 0);
  • 导入示例的三份 SimaticML:点表 → 系统实例 DB(IEC_Timer_0_DB)→ Main(OB1);系统实例 DB 也可以直接导入;
  • 整机编译:0 错误 0 警告。

1516 没有板载 I/O:插 DI/DQ 后,编译从 0/1 到 0/0
本课实测:先 0 错误 1 警告,插模块后 0/0

为什么会有那条警告:1516 没有板载 I/O,点表里的 %I0.0、%Q0.0 在硬件里“不存在”,编译器会提醒 Inputs or outputs are used that do not exist in the configured hardware。插上模块(地址从 0 起)后警告消失。PLCSIM 里即使不插模块,I/Q 位也能读写,但别把警告带进交付。

第四步:agent 实际做了什么(2)——注册、上电、下载、RUN

虚拟 PLC 的固定顺序:注册 → 上电 → 下载 → RUN → 读写
本次实测的调用链和回包(实例名 L4Sim2)

S7-PLCSIM Advanced 控制面板:实例 L4Sim2 已注册并在运行
实测截图:控制面板里的 L4Sim2(Online Access = PLCSIM/Softbus,虚拟 IP 192.168.0.1)

看到什么:实例状态 Off → Booting → Stop;下载报告 "state":"Success",随后 post StartModules 自动 RUN;刷新标签后能看到 9 个程序标签(4 个点表标签 + 5 个 IEC_Timer_0_DB.*)。控制面板里能看到这个实例(上图:L4Sim2,Online Access 选 PLCSIM)。新注册的实例是空的——没有下载之前 run 会报 IsEmpty / InvalidOperatingState。

本次踩到的坑:复用旧实例名(持久化存储里是另一套硬件配置)和插完模块再下载,都会让下载卡在 Download configuration '...ResetModule' was unhandled。换一个新实例名重新注册,一次通过。

第五步:agent 实际做了什么(3)——跑场景表

场景实测:松开和按停止是同一个下降沿
TOF 的实测行为:停止按钮同样触发 1 分钟延时

读写用标签名(tialink_sim_read / tialink_sim_write 的 op=tag / op=set-tag),也可以用地址(op=io,%I0.0 / %Q0.0)。每条只记实测值:

# 操作 期望(按 facts 表达式) 实测
S0 初始 全 0 On=0、Off=0、Stove=0、Exhaust=0
S1 Turn_On_PB=1 Stove=1、Exhaust=1 +2 秒:1 / 1 ✓
S2 Turn_On_PB=0,等 5 秒 Stove=0、Exhaust=1(TOF 保持) +2 秒:0 / 1;+12 秒仍 0 / 1 ✓
S3 再等到 60 秒以后 Exhaust=0 +64 秒:0 / 0 ✓
S4 重新启动,按 Turn_Off_PB=1 Stove=0;Exhaust 继续排风(TOF 对停止同样延时) 停止 +2 秒:0 / 1(ET=2139 ms);+64 秒:0 / 0 ✓

监控表实测:按停止后 Stove=FALSE、Exhaust=TRUE、ET 正在计时
实测截图:两个按钮都是 TRUE,Stove=FALSE、Exhaust=TRUE,IEC_Timer_0_DB.ET = T#15S_148MS

结论:S4 是这张表的价值所在。按停止按钮只让 Stove 立即停;Exhaust 的 TOF 输入同时变 0,风机继续排风 1 分钟——和松开按钮的行为完全一样。这不是 bug,是这段逻辑的真实行为(排气设计上甚至可能是有意的);但它显然是编译和人工阅读都容易漏掉、只有跑起来才敢下结论的部分。要改成「停止立即停风机」,得动逻辑(比如给 TOF 的输入另做保持条件),改完再把这张表重跑一遍。

验证清单

  • /sim/status 显示 available=true(没装 PLCSIM Advanced 或 TiaLink 带 --no-sim 时 /sim/* 会 403);
  • 工程里有 S7-1500 设备,编译 0 错误 0 警告(1516 无板载 I/O:插 DI/DQ,或知道那条警告的原因);
  • 实例注册后 operatingState 到 Stop 再下载,下载报告 Success;
  • 下载后实例为 Run,tags?refresh=true 能看到程序标签;
  • 场景表覆盖正常 / 边界 / 复位,每条都有实测值(不是把期望抄一遍);
  • 至少得到一条只靠编译和读回拿不到的结论(本例:按停止后风机仍排 1 分钟);
  • 知道实验工程是未保存的(或明确知道保存了什么);
  • 不需要的仿真实例已停止 / 注销(DELETE /sim/instance)。

常见坑

  • --no-sim 或没装 PLCSIM Advanced:所有 /sim/* 返回 403;先查 /sim/status。TiaLink 只驱动运行时,不负责安装。
  • 新实例是空的:注册完直接 run 会报 IsEmpty / InvalidOperatingState;顺序必须是上电 → 下载 → RUN。
  • 上电后别急着下载:poweron 后先等 Booting 结束到 Stop。
  • ResetModule was unhandled:复用了旧实例名(持久化存储里是别的硬件配置),或刚改过硬件配置;换一个新实例名重新注册即可(本课实测撞了两次)。
  • 下载会自动改工程:打开两个仿真属性、清除新 1500 的默认保护——所以必须用沙盒工程;不保存就不会落盘。
  • 按名读写前先 tags?refresh=true:否则 DoesNotExist;I/Q 也可以直接按地址读写。
  • I/Q 地址必须存在:1516 没有板载 I/O,直接导入用 %I/%Q 的程序会报 Inputs or outputs are used that do not exist in the configured hardware;插模块,或把点表换成 %M。
  • 下载可能超过工具超时:大工程更慢;超时 ≠ 失败,先看实例状态和 TIA 里的下载结果再决定重试。
  • 仿真不是验收:PLCSIM Advanced 只跑 CPU 行为;总线、HMI、驱动、安全回路、F-CPU 的安全程序都不覆盖。
  • 别在正式工程实验:下载 ≠ 保存,但工程属性和保护设置会被改,别让实验的副作用混进交付工程。

下一步

本课工具

TiaLink

把 TIA Portal 接到你的智能体:导入、编译、读回核对、PLCSIM 仿真。本地运行,工程数据不出厂。

打开 TiaLink