
先说明一下这类“建系统、搭逻辑、跑仿真”的项目我做过不少次真正能让人少掉头发的关键就一句话把时序当状态机看别把灯当一堆散点看。下面这篇我会围绕“基于博途1200PLCHMI的交通灯控制系统仿真程序”这条主线从选型、时序设计、TIA工程搭建、仿真联调到排障完整走一遍每一步都配合我实际踩过的坑和验证过的做法写下来希望能给刚接触PLC仿真或者正在自己搭交通灯项目的朋友一点参照。1. 项目整体思路为什么要做一套“仿真版”交通灯1.1 仿真解决的是“快速验证控制逻辑”这件事很多人觉得交通灯项目太简单无非就是定时翻灯写个启保停加六个定时器就完事。但真放在工程语境里问题不是“灯会不会亮”而是逻辑在不同模式下是否可靠、时序切换是否无缝、异常情况下能不能复位以及现场操作员看到的人机界面是否直观。做仿真版核心诉求就是把这些东西在不上真机、不接线、不担心烧输出点的情况下全部验证一遍。PLC本体用S7-1200在博途TIA Portal里完成组态用PLCSIM模拟CPU运行HMI部分用精简系列面板的仿真模式显示画面。这套组合下程序和画面可以联动跑起来哪怕你手里一块实体硬件都没有也能完整体验“画面点启动→PLC执行时序→画面灯色变化”的闭环。1.2 这套系统的整体架构和选型逻辑系统架构并不复杂但每个模块的取舍背后都有原因。PLC侧S7-1200 1214C DC/DC/DC。选1214C是因为点数富余除了六个灯输出两个方向的R/Y/G还可以留出启动、停止、手动/自动切换等输入点后续扩展也不至于重新选型。HMI侧使用博途集成的精简面板仿真比如 KTP400 Basic 或直接用“仿真运行系统”跑画面。选精简面板的原因是项目不涉及复杂配方、趋势、脚本纯画面切换和指示灯显示精简面板完全够用仿真占用资源也小。通信方式HMI与PLC之间走PN/IEProfinet。在仿真环境下PLCSIM会提供一个虚拟网卡接口HMI仿真运行系统需要选到同一网络接口才能建立连接。编程语言核心控制逻辑我用了SCL写在函数块FB里而不是全部堆梯形图。原因后面细讲简而言之状态机用SCL书写更清晰可读性和可维护性都更强也方便别人接手看代码。注意选型这件事在仿真项目里看似无所谓其实影响后续联调。比如CPU固件版本、HMI设备版本、博途版本三者必须兼容否则会出现在线连接失败、下载组态中途报错这类问题。我建议所有仿真环境统一使用同一个博途版本如V16/V17不要混用。1.3 适合谁看、需要什么基础这套内容适合几类人刚学完PLC基础指令、想做个综合项目的初学者需要用仿真做方案验证的现场工程师以及准备求职面试、想在简历里写一个完整自动化小项目的同学。基础方面你需要了解博途的基本操作比如建项目、组态设备、写简单梯形图或SCL。如果完全零基础建议先熟悉软件界面和PLC基础指令跟上这篇的节奏会更轻松。2. 核心控制逻辑拆解交通灯的时序本质是状态机2.1 先把十字路口的相位关系理清楚一个标准十字路口两个方向的车流需要分时通行同时还要考虑转弯车、行人过街的冲突。简化模型下我划分成四个基础相位相位1南北直行绿灯东西向红灯持续25秒相位2南北直行黄灯过渡东西向仍红灯持续3秒相位3东西直行绿灯南北向红灯持续25秒相位4东西直行黄灯过渡南北向仍红灯持续3秒这样形成了一个完整周期绿灯25秒→黄灯3秒→红灯通行方向切换→绿灯25秒→黄灯3秒→回到初始单周期56秒。如果考虑全红清空时间即两个方向都红灯2秒则更安全周期变成58秒。实际项目中我建议把“全红时间”单独作为一个状态加进去虽然仿真时看不出来但贴近真实路口的控制习惯。每个状态的本质是一组输出组合。比如南北绿灯时输出是“南北绿1南北黄0南北红0东西绿0东西黄0东西红1”。所有灯的组合变化都能用状态枚举表达。2.2 为什么说状态机比“定时器堆叠”更可靠很多教材例程的做法是启动后每个方向的黄灯先闪然后用几个定时器串联触发下一步比如T1计时25秒后接通绿灯变黄灯T2计时3秒后切换。逻辑上没错但出现一个麻烦一旦中间某个定时器被复位或变量被干扰后面的连锁关系就会错位很难查。而且当需要加入手动模式、夜间模式时梯形图里会乱成一团。采用状态机的组织方式后整个过程变成用一个整型变量比如State表示当前处于哪个相位每个State对应一组输出赋值State之间的切换条件由该状态内的计时是否完成来触发切换时先执行“离开动作”复位计时、清输出再进入新的State。好处很明显每个时刻只有一个State有效输出的确定性极高新加模式只需要增加状态分支排查故障时看State值就能定位当前卡在哪个环节。这也是为什么我坚持用SCL来实现这个逻辑。2.3 时间参数与定时方案的选择定时方案的常见做法有两种第一种是多个TON定时器逐步接力T1时间到触发T2T2时间到触发T3。这种方案直观但定时器数量多中间变量也多状态切换时计时器的复位管理很麻烦。第二种是“计时基数阈值比较”。用一个自复位自由计时器比如周期为1秒的脉冲累加到一个时间计数值然后用比较指令判断当前计数值落在哪个时间区段决定输出状态。这个方案代码量小但时间参数一变比较区间就要大改读代码的人容易晕。我最终采用的是第三种在SCL状态机内使用TON定时器定时器变量放在FB的Static区。每个状态开始运行时就启动该状态自己的TON当TON的Q端输出为True时立即切换状态。核心逻辑示意CASE #state OF 0: // 初始状态南北绿灯 #out_N_S_Green : TRUE; #out_E_W_Red : TRUE; #ton_green_NS(IN : TRUE, PT : #t_green_ns); IF #ton_green_NS.Q THEN #state : 1; END_IF; 1: // 南北黄灯过渡 #out_N_S_Yellow : TRUE; #out_E_W_Red : TRUE; #ton_yellow_NS(IN : TRUE, PT : #t_yellow_ns); IF #ton_yellow_NS.Q THEN #state : 2; END_IF; // 后续状态类似 END_CASE;这种做法的核心优势是每个状态的计时起点都在进入该状态的瞬间重新开始因为离开状态时SCL的执行流不再调用这个TON计时值会被清零。这相当于用“进入状态”作为时间基准无比清晰。提示写SCL状态机时建议把时间参数绿灯时长、黄灯时长、全红时长都做成FB的Input参数或Static常量不要散落在代码里。以后调整路口配时时只改参数表不动逻辑。3. 博途工程搭建与核心代码实现3.1 新建工程、组态PLC和HMI的要点打开博途后新建项目选择CPU型号。我习惯先组态PLC再组态HMI因为HMI连接PLC时需要知道PLC的IP地址和Profinet网络名称。组态步骤大致为新建项目项目名称建议带版本日期比如“TrafficLight_Demo_V1”。添加新设备选择CPU 1214C DC/DC/DC固件版本按博途版本选取比如V4.4。设置PLC的IP地址在设备视图的“以太网地址”里填写比如192.168.0.1。这个地址就是仿真时HMI要连接的地址。添加HMI设备选择精简面板KTP400 Basic PN设置IP地址为192.168.0.2和PLC在同一网段。连接设置进入设备与网络视图将HMI的PN口与PLC的PN口进行“Profinet连接”拖拽确定主从关系。这里有个仿真特有的细节PLCSIM仿真的本质是模拟一个虚拟PLCHMI仿真运行系统通过PC网卡访问虚拟PLC。因此你在组态里看到的“连接”只是逻辑连接实际通信依赖仿真器的虚拟网卡。后面启动HMI仿真时必须在弹出的“连接”设置里选择正确的接口通常是“PLCSIM”对应的虚拟接口。3.2 PLC程序结构快组织、快定位一个清爽的程序结构应该让人打开项目就能找到核心逻辑。我的做法如下OB1主程序只调用两个FB不做任何其他逻辑。FB_TrafficLight交通灯状态机核心负责所有灯色输出和状态切换。FB_ModeControl模式控制可选负责自动/手动/夜间模式的切换。为什么要拆两个FB因为交通灯项目一旦加入手动模式比如维修时强制指定某个方向绿灯如果手动逻辑和自动逻辑写在同一个块里容易出现优先级混乱。拆开之后模式控制FB根据外部开关决定调用哪套输出逻辑边界特别清楚。为了简化本次只讲FB_TrafficLight的内容模式切换可以通过同样的方法扩展。3.3 输入输出变量定义与硬件映射先在PLC变量表里定义I/O点。由于控制器自带数字量通道六个输出点可以规划如下Q0.0南北红灯Q0.1南北黄灯Q0.2南北绿灯Q0.3东西红灯Q0.4东西黄灯Q0.5东西绿灯输入点两个I0.0启动按钮常开I0.1停止按钮常开然后在FB接口里定义Input启动信号、停止信号、绿灯时间、黄灯时间Output六个灯的输出变量Bool类型供OB1映射到Q点Static状态变量、定时器变量提示在OB1里调用FB时要把FB的输出变量再传给Q点比如“#fbTraffic.out_NS_Red Q0.0”。这一步不要漏否则FB内部运行正常外部设备却没反应排查起来容易怀疑人生。3.4 HMI画面搭建与变量绑定HMI画面是这个项目的门面。我搭画面的思路分三层第一层状态展示区。画一个简化的十字路口每个方向放三盏圆灯红黄绿。选中灯后在属性“动画”里添加“外观”动画变量选择PLC侧的对应输出。设置“红”变量为True时显示红色“绿”变量为True时显示绿色“黄”变量为True时显示黄色。变量类型选“位”。第二层控制按钮区。放置启动按钮和停止按钮分别绑定到I0.0和I0.1。但这里有个仿真中的常见坑按钮直接绑定I点在真实PLC里可行但在仿真里I点驱动比较绕。更稳妥的做法是在PLC内部做中间变量比如M0.0、M0.1HMI按钮绑定M变量程序里用M变量的边沿去触发启/停逻辑。这样既避免I点刷新的问题也更符合工程习惯。第三层运行状态区。显示当前状态编号、运行时间等数值。文本域绑定PLC侧的整型变量比如状态编号显示为数字。这个小而简单的功能会让画面看起来更专业。HMI变量表添加变量时要特别注意“采集周期”和“保持性”设置。对于开关量采集周期默认1秒也行但指示灯要求实时性高一些建议设为100ms。如果发现画面灯色切换总比实际慢多半就是采集周期太长。4. 仿真联调流程从“单块逻辑”到“完整闭环”4.1 启动PLCSIM并下载程序的完整步骤在博途里启动仿真我最推荐的操作顺序如下在“转至在线”下拉菜单选择“下载到设备”如果设备列表中已经有PLCSIM实例直接选它。如果没有启动PLCSIM先点击“启动仿真”按钮或快捷键会弹出“扩展的下载到设备”对话框选择“启动仿真”并回车。在弹出的PLCSIM窗口里把CPU拨到RUN状态。回到项目树右键点击PLC选择“在线并诊断”确认在线状态正常。这里要提醒一句首次下载前一定要编译整个PLC程序保证无错误。如果程序有错下载时虽然能到设备但CPU会停在STOP状态代码根本跑不起来。多留个“编译后再下载”的习惯能省很多时间。4.2 HMI仿真的启动与连接设置HMI仿真的启动分两步。先在博途项目树中右键HMI设备选择“仿真运行系统”会弹出HMI仿真窗口。这个窗口一开始会显示“正在连接PLC”或“连接已建立”。关键点来了如果在弹出的连接选择窗口里看不到PLCSIM接口大概率是网络接口配置不对。我的解决方法是在HMI的设备组态中检查“连接”选项卡里PLC地址是否为192.168.0.1启动仿真时选择“PN/IE”接口将PLC和HMI的IP地址规划在同网段不能有冲突。连接成功后HMI画面里就能实时看到PLC驱动的灯色变化。仿真闭环就此打通。4.3 流程验证用“慢速模式”做逐状态检查联调过程中强行把绿灯时间设成25秒做全流程测试太慢我一般会把时间参数临时改短比如绿灯改3秒、黄灯改1秒跑一个周期只需8秒左右肉眼就能判断状态切换正确性。这相当于“时间缩放测试”。测试观察点启动按钮按下后南北绿灯东西红灯是否同步点亮绿灯计时结束后南北绿灯熄灭、南北黄灯点亮同时东西红灯不变黄灯计时结束南北黄灯熄灭、南北红灯点亮东西红灯仍然亮着如果需要全红延时此时两方向都红持续设定的时间东西方向绿灯点亮南北方向保持红灯整个周期结束后能无缝回到起始状态。如果发现某个状态没有按预期切换优先检查State值停在几、对应TON是否被正确触发。由于我采用状态机结构定位一般不会超过五分钟。5. 常见问题排查与经验沉淀5.1 “灯不亮”的排查顺序我在好几个项目中见过类似的故障现场程序下载了仿真也跑着但HMI画面上灯就是不动。排查顺序我建议固定下来PLC是否处于RUN状态仿真器里CPU必须显示绿色RUN。如果停在STOP检查程序块有没有编译失败。变量映射是否完整OB1里接线是否正确FB输出有没有传给Q点或M点。用在线监视表直接监控Q0.0等地址看程序层有没有输出。HMI变量地址是否对应画面里绑定的是不是PLC的真实地址。如果在HMI变量表里建了别名变量务必确认别名变量与PLC变量地址一致。采集周期是否过慢前面提到100ms采集周期对于指示灯太慢建议调整。这一套流程下来绝大多数“不亮”问题都能解决。5.2 通信连接失败的典型原因HMI仿真窗口提示“无连接”或“连接中断”是新手高频问题。常见原因如下网络接口选错PLCSIM启动后虚拟网卡名称可能变化需要在HMI仿真的“接口参数”里手动选择PLCSIM对应的网卡。IP地址不在同一网段由于PLCSIM虚拟PLC的IP就是组态里设置的IP而HMI组态里设置的IP也是虚拟的两个必须在同一网段并且不能和真实物理网卡抢占地址。防火墙拦截个别情况下Windows防火墙会拦截PLCSIM虚拟网卡的通信。遇到连接不稳定时可以暂时关闭防火墙测试确认原因后再加例外规则。5.3 我实际踩过的三个坑希望你绕开第一个坑是变量表里重复定义地址。在HMI变量表里不小心把两盏灯都映射到同一个输出地址导致两灯同步变化看起来像逻辑错乱其实是地址冲突。排查时养成对照变量的习惯。第二个坑是在OB1里直接写全部逻辑而不是用FB。维护时改一个参数要在很长的梯形图里翻非常痛苦。用FB状态机之后这种痛苦基本消失。第三个坑是忘了做边缘检测。启动停止按钮如果不做R_TRIG边沿检测按住按钮时程序会反复触发启动状态机会不断从0重置导致灯永远在第一个状态循环看似“程序卡住”。我建议所有启停输入都过一遍边沿检测再进入模式控制逻辑。5.4 关于这套程序还能怎么扩展如果做完基础版本后想进阶可以从三个方向延伸增加夜间模式晚间全黄灯闪烁用一个模式切换开关实现状态机新增一个分支即可。增加倒计时显示HMI画面加上数码管或文本域绑定一个递减计时变量。这需要PLC侧计算剩余时间并输出到HMI。增加行人相位增加一组行人灯在特定状态期间放行人行横道状态机需要重新调整相位顺序。我个人在实际操作中的体会是交通灯控制是一个特别适合练手的状态机项目因为它的输入输出关系非常直观出错的反馈几乎即时可见但又完整包含了定时、联锁、模式切换、HMI联动这些工程要点。把这套玩明白后面再去接触机械手臂控制、分拣线这类更复杂的状态机项目思路会顺很多。最后再分享一个小技巧仿真项目里我有意识地把所有时间参数集中放在一个全局数据块或FB接口中并且用带单位后缀的命名比如t_green_ns T#25s这样哪怕过了一个月再打开项目看着变量名就能快速想起设计意图。好的变量命名比好的代码本身更难得。这套交通灯仿真程序做到位后你可以继续往里加东西——它是越改越好玩的项目。