先说明一点:这类“十字路口交通灯”项目,在自动化教学和工程入门里属于经典中的经典。它不复杂,但恰好把PLC编程、IO地址规划、上位机组态这三件最基础也最容易被新手搞乱的事串在了一起。我这次用西门子S7-200 SMART配合组态王6.55来做完整实现,全程按实际做项目的顺序走一遍,包括时序逻辑怎么拆、IO地址怎么编、组态王变量怎么跟PLC对上,最后再说说仿真调试时最容易踩的坑。
1. 先搞清楚交通灯要“做什么”:控制需求与控制时序拆解
很多人一上来就写梯形图,IO表也不画,时序也不算,写到一半发现输出乱套、红绿灯打架。做这类项目的第一步不是打开软件,而是拿张纸把交通灯的动作顺序理清楚。这个环节省了,后面全是坑。
1.1 一套标准十字路口有哪些基本信号状态
十字路口交通灯不是简单的“东西绿、南北红”两个状态来回切。以最常见的四相位控制为例,一个完整周期里至少包含:
- 东西方向绿灯、南北方向红灯
- 东西方向绿灯闪(有的城市省略,直接切黄灯)
- 东西方向黄灯、南北方向红灯
- 东西方向红灯、南北方向绿灯
- 东西方向红灯、南北方向绿灯闪
- 东西方向红灯、南北方向黄灯
如果你做的是带左转箭头灯的款式,状态会更多,东西左转绿、对向直行红这类相位都要拆出来。不过咱们先从基础版入手:每个方向一组红、黄、绿,共6个输出点。
这里有个新手特别容易犯的错误:直接用TON定时器去延时置位、复位线圈。比如“10秒后把绿灯关掉、点亮黄灯”——逻辑上看没错,但一旦牵扯到多个定时器互相嵌套、扫描周期和定时器刷新次序不一致,现场就会出现“该灭的灯没灭、该亮的灯提前亮”这种诡异问题。更稳的做法是:用一个自由运行的秒脉冲发生器,通过计数或者比较的方式,推导出当前处于哪个时间段,再根据时间段去映射灯的亮灭。这个思路后面写程序时还会展开。
1.2 时间配时设计:从车流量倒推绿灯周期
配时不是拍脑袋定的。虽然是演示项目,但配时的逻辑得合理。工程上通常依据一个路口的各方向车流量、车道数、行人过街时间来估算周期。
我这边按一个相对均衡的十字路口来设计,参数如下:
| 相位 | 动作 | 持续时间 |
|---|---|---|
| 相位1 | 东西直行绿灯 | 25秒 |
| 相位2 | 东西方向黄灯 | 3秒 |
| 相位3 | 南北直行绿灯 | 25秒 |
| 相位4 | 南北方向黄灯 | 3秒 |
| 附加 | 全红清空(可选) | 2秒 |
东西和南北各占25秒直行绿灯,加3秒黄灯,一个完整周期56秒。为什么加全红清空?因为上一相位的车辆可能还在路口中间,下一相位马上放行会撞车。城市里一些大路口确实会插入2到3秒的全红,让路口“清空”。咱们项目中可以把它做进去,作为一个可选参数,这也是一个加分点。
如果某个方向车流量明显更大,比如东西方向是主干道,可以把东西绿灯拉到40秒,南北压到15秒,总周期相应变成40+3+15+3+2=63秒。这个比例没有绝对正确,但你要能在项目说明里讲出依据。面试或者答辩时,这点非常加分。
2. IO 分配表:接线之前必须想清楚的“工厂地图”
IO分配表这东西,看着就是一张表,实际上它是整个控制系统里所有信号的唯一“字典”。PLC程序里用到的每一个地址、组态王里映射的每一个变量,最终都要落到这张表上。表没理清,后面程序写得再漂亮也白搭。
2.1 输入输出清单与地址映射
这次项目我用的是西门子S7-200 SMART CPU SR30,自带18路数字量输入和12路数字量输出。做交通灯是绰绰有余的,甚至可以说杀鸡用牛刀。选它的原因主要是方便后面扩展(比如加倒计时数码管、加按钮控制),而且和组态王走以太网通信非常顺。
输出点分配:
| 地址 | 功能 | 说明 |
|---|---|---|
| Q0.0 | 东西方向红灯 | 接中间继电器 |
| Q0.1 | 东西方向黄灯 | 接中间继电器 |
| Q0.2 | 东西方向绿灯 | 接中间继电器 |
| Q0.3 | 南北方向红灯 | 接中间继电器 |
| Q0.4 | 南北方向黄灯 | 接中间继电器 |
| Q0.5 | 南北方向绿灯 | 接中间继电器 |
输入点分配:
| 地址 | 功能 | 说明 |
|---|---|---|
| I0.0 | 启动按钮 | 常开点,按下启动系统 |
| I0.1 | 停止/急停按钮 | 常闭点,切断输出 |
| I0.2 | 夜间模式开关 | 拨到ON时黄灯闪烁运行 |
| I0.3 | 手动/自动切换 | 手动时可通过按钮单步切换相位 |
这里我需要专门说一个实操经验:PLC输出点不要直接驱动220V的交通灯。S7-200 SMART的输出继电器触点容量一般是2A,对于白炽灯或者LED交通灯来说,冲击电流很容易把触点烧掉。正确做法是PLC输出先驱动中间继电器(比如24V线圈的MY2NJ),再由中间继电器的触点去控制接触器或交通灯电源。现场检修也方便——中间继电器烧了换一个几块钱,PLC输出点烧了就只能修模块了。
2.2 分配表的三个实战原则:余量、防错、检修友好
第一,留余量。IO分配不要挤得满满当当。这次项目正好12个输出点全用完了(东西3 + 南北3 = 6个,还有6个空着),输入点也留着好几个空余。如果日后要加倒计时驱动、加蜂鸣器、加感应线圈输入,就不需要换PLC,直接填进空余地址就行。
第二,预留易混淆的地址。S7-200 SMART的输入输出地址是八进制编号,I0.0到I0.7之后是I1.0,没有I0.8和I0.9。新手在分配地址时经常想当然地写I0.8,编译直接报错。这个在画接线图时就要避开。
第三,检修友好。IO分配表的备注栏一定要写得足够详细。比如“东西方向绿灯”和“南北方向绿灯”从名字上看很像,容易混淆。我自己的习惯是备注栏里写清楚“位于路口东北角立杆,从上往下数第三盏灯”,这样电工去现场排查时不用再翻图纸慢慢猜。这种细节是纯书本上学不到的,但做项目时特别有用。
3. 西门子 PLC 程序:用梯形图把时序逻辑变成代码
程序是整个项目的核心。我用的是STEP 7-MicroWIN SMART软件,编程语言选梯形图。下面把核心逻辑完整拆开讲。
3.1 三种程序写法的取舍
交通灯时序逻辑常见有三种写法:第一种是置位复位法,只用SET/RST指令配合多个定时器实现状态跳转;第二种是状态寄存器法,用一个字节变量表示当前状态,每条定时器完成时状态值加一,输出由状态值译码得到;第三种是秒脉冲计数法,用SM0.5(S7-200 SMART自带的1秒脉冲)作为时钟,计数器累加,通过比较指令确定当前时间段。
三种方法里,置位复位法最直观,但状态多了之后程序会非常乱,线圈重复输出还容易出双线圈错误。状态寄存器法思路清晰,调试时看状态值就知道系统走到哪一步了,是工程里用得比较多的方案。秒脉冲计数法虽然代码稍微绕一点,但时间参数特别好改,全部挪到定时器或变量里就能实现配时修改。
我这次用的是状态寄存器法。核心思想是:M0.0到M0.3四个中间变量表示四个相位,某个时刻只有一个是ON。每个相位对应的定时器计时结束后,把当前状态复位,把下一个状态置位。这样写出来的程序逻辑清楚,而且不会出现双线圈问题。
3.2 核心逻辑模块:启动、脉冲、时序输出
先说启动逻辑。I0.0按下后,系统进入自动运行状态,用M10.0作为“运行允许”标志位。停止按钮I0.1接到常闭触点,一旦断开,M10.0复位,所有输出强制关闭。
然后是相位切换。以东西绿灯相位为例,程序大致是:
// 东西绿灯相位:M0.0 // T37 为东西绿灯持续定时器(25秒) LD M0.0 // 当前处于东西绿灯相位 AN M10.0 // 未按下停止 TON T37, +250 // 25秒定时(S7-200 SMART时基为100ms) LD T37 // 定时时间到 S M0.1 // 切换至东西黄灯相位 R M0.0 // 退出当前相位其他相位的写法完全同构:T38负责东西黄灯3秒、T39负责南北绿灯25秒、T40负责南北黄灯3秒。这个结构有个天然的好处:想要调整配时,只需要改TON的预设值;想要调整相位顺序,只需要改SET/RST的目标位。
输出映射部分更加直接:
// 东西方向红灯输出 LD M0.2 // 南北绿灯相位 O M0.3 // 南北黄灯相位 = Q0.0 // 东西红灯点亮 // 东西方向绿灯输出 LD M0.0 // 东西绿灯相位 = Q0.2 // 南北方向绿灯输出 LD M0.2 = Q0.5这就是状态译码的思路。好处是任何时刻,每个输出线圈只有一条路径能够导通,双线圈问题从根上杜绝了。
3.3 手动模式、夜间模式这些“附加题”怎么落位
做完基本功能,我建议把该加的附加功能都加上。不单是为了演示效果,更主要是练习“模式切换”这种实际工程里天天见、但书本教程里很少讲的东西。
夜间模式逻辑比较简单:I0.2拨到ON时,屏蔽正常相位切换流程,让东西、南北两个方向的黄灯以1秒为周期交替闪烁。程序上就是利用SM0.5秒脉冲,直接驱动Q0.1和Q0.4:
LD M10.0 // 系统运行 AN I0.2 // 夜间模式未启用时走正常流程 CALL 正常相位处理子程序 LD M10.0 LD I0.2 // 夜间模式启用 A SM0.5 // 1秒脉冲 = Q0.1 // 东西黄灯闪 = Q0.4 // 南北黄灯闪注意这里我用了AN I0.2来封锁正常流程分支,这样夜间模式时不会出现“黄灯在闪、绿灯还在亮”的冲突。
手动模式更直接:I0.3为ON时,系统不自动计时,每按一次I0.4,状态寄存器前进一格。这功能在调试阶段特别好用——你可以慢慢观察每一盏灯的状态,不用等一个周期56秒跑完。没有这个功能,你要在组态王里验证画面效果,得干等一分钟才能看到一轮完整切换。
4. 组态王上位机:把人机界面和设备状态“联”起来
PLC程序做得再好,没有一个“看得见”的界面,演示效果就差很多。组态王在这里的作用,是把PLC内部的位状态、定时器剩余时间、当前相位这些不可见的东西,变成屏幕上能看懂的动态画面。
4.1 组态王与 S7-200 SMART 的通信配置
组态王和S7-200 SMART通信,走的是以太网,用S7协议。打开组态王7.5(我这边用的是6.55版本,两个版本在基本配置上区别不大,7.5界面布局略有变化),新建一个工程后,第一步是配置设备。
流程是:设备COM口 -> 新建 -> 选择“PLC” -> “西门子” -> “S7-200(TCP)” -> 输入设备名称“PLC_交通灯” -> 填写IP地址。S7-200 SMART的默认IP地址是192.168.2.1,如果你用PC连接,需要把电脑的本地连接IP配成同网段,比如192.168.2.10,子网掩码255.255.255.0。
这里有一处容易翻车:组态王里S7-200(TCP)驱动要求PLC侧的“允许远程访问”选项打开。S7-200 SMART默认是允许的,但如果之前有人改过系统块设置,这个选项被关掉了,组态王会一直报通信超时,但你看PLC上的以太网指示灯又正常闪。排查方式是用STEP 7-MicroWIN SMART软件的“通信”功能先ping一下PLC,能ping通、能上传程序,但组态王连不上,十有八九就是这个远程访问开关的问题。
4.2 变量定义与画面组态
通信配好之后,组态王里的核心工作是定义变量。组态王变量分为内存变量和I/O变量。I/O变量的数据类型、读写属性必须和PLC里的实际存储区一一对应。
我定义了以下关键变量:
| 组态王变量名 | 连接设备 | 寄存器 | 数据类型 | 读写 |
|---|---|---|---|---|
| 东西红灯 | PLC_交通灯 | Q0.0 | Bit | 只读 |
| 东西黄灯 | PLC_交通灯 | Q0.1 | Bit | 只读 |
| 东西绿灯 | PLC_交通灯 | Q0.2 | Bit | 只读 |
| 南北红灯 | PLC_交通灯 | Q0.3 | Bit | 只读 |
| 南北黄灯 | PLC_交通灯 | Q0.4 | Bit | 只读 |
| 南北绿灯 | PLC_交通灯 | Q0.5 | Bit | 只读 |
| 当前相位 | PLC_交通灯 | M0.0 | Bit | 只读 |
这里有个非常关键的细节:组态王里的寄存器地址要写成Q0.0、M0.0、I0.0,不是VB0、VW0那种V区地址。很多从WinCC转过来的人习惯性写DB块,在组态王里就蒙圈了。组态王S7-200驱动对I、Q、M、V区都支持,但格式必须是“区名+偏移量”,比如Q0.0、M0.2、VB100,不能写成DB1.DBX0.0这种S7-300的格式。
画面组态方面,我从图库里拖了两个方向的路口示意,每个方向放三盏灯(红、黄、绿),用椭圆工具画好,填充颜色设为对应颜色。然后对每个灯做“动画连接”——选择“隐含”或“填充属性”连接,表达式填对应的I/O变量名。
这里我推荐用“隐含”连接而不是“填充属性”:隐含连接的条件表达式为“\本站点\东西红灯==1”时显示,为0时隐藏。这样做的好处是,灯灭时彻底消失,画面更接近真实指示灯效果,而不是灰暗色的“假灯”。画面效果在项目演示和答辩时非常加分。
4.3 报表、报警与运行趋势的实用做法
组态王除了做画面,还有一个很实用的功能是运行趋势曲线和报表。交通灯项目虽然简单,但也可以加上实时趋势图,用来显示当前相位状态变化和周期时长。
具体做法:在画面里画一个“实时趋势曲线”控件,绑定变量“当前相位状态”(在PLC里用MB1存储当前相位编号,范围0到3,组态王里定义为BYTE类型I/O变量)。趋势曲线就会把相位的跳变过程画出来,一眼能看出一个周期里各相位的时间分配是否正常。
报警功能可以做成这样:定义一个内存变量“运行状态”,PLC在正常运行、夜间模式、急停三种状态下分别写入0、1、2,组态王对运行状态做报警配置——不等于0时报警“系统非正常运行”。这样演示时可以故意拨一下急停按钮,画面上立刻弹出报警窗口,非常直观地体现监控功能。
5. 仿真调试与现场排查:从组态王到真实设备
写程序的时候不觉得,真正联调的时候一推问题,你会发现百分之七十的时间都花在排查“为什么状态对不上”“为什么灯不亮”这些破事上。这一节我把最容易出问题的地方集中说一下。
5.1 纯软件仿真:没有实体PLC也能验证逻辑
如果你手头没有S7-200 SMART实物,但想先把程序逻辑验证一遍,有两个办法。
第一个是S7-200 SMART的仿真器。网上有第三方仿真软件支持S7-200系列指令仿真,但需要注意的是,第三方仿真器对定时器、计数器、通信指令的支持并不完整,交通灯这种纯逻辑控制还好,一旦涉及通信、模拟量或者高速脉冲,仿真结果就不可信了。
第二个是组态王本身结合PLC逻辑在PC端模拟。组态王支持“仿真PLC”功能,在设备配置时选择仿真类型,不连真实PLC,直接用内存变量模拟运行。你可以用脚本程序模拟PLC的梯形图逻辑:在组态王命令语言里写一个事件脚本,每秒钟修改一次内存变量值,模拟相位切换。这种做法的价值在于,组态王画面和变量绑定关系的验证不需要依托PLC,至少能确认画面本身没问题。
我个人的建议是:逻辑验证靠仿真、通信验证靠实物。仿真过了只能说明程序逻辑没错,不能说明通信链路和IO接线没问题。项目演示前,必须用实物跑一遍。
5.2 常见故障与排查链路
我在做联调时遇到过几次非常典型的故障,排查过程分享一下。
故障一:组态王按钮能控制PLC输出,但画面状态不刷新。
这个现象的根源是变量的“采集频率”设置问题。组态王每个I/O变量都可以单独设置采集频率,默认是1000ms。如果你PLC程序的输出部件响应速度极快(比如急停后几十毫秒就复位输出),而组态王每秒才采集一次,就可能漏掉状态变化。解决办法是把相关变量的采集频率改到100ms,或者在做快速状态监控时用“变化时采集”模式。原理很简单:组态王不可能每个扫描周期都去抓所有变量,它有自己的采集调度机制,频率太低就会丢状态。
故障二:PLC运行正常,但某个输出点接上负载后不动作。
这个十有八九是接线问题,不是程序问题。我遇到过最离谱的一次,是中间继电器线圈电压搞错了,用了DC24V的继电器,结果现场接线给的是AC220V,线圈当场烧掉。后来我养成了一个习惯:每次接完线,用万用表量一下线圈两端电压是否正确,再上电。这是电工操作的基本素养,但很多人会跳过这步直接上电,烧了才后悔。
故障三:组态王显示通信超时,但PLC侧正常。
上面提到了“允许远程访问”选项,还有一种可能是防火墙拦了组态王的端口。Windows防火墙默认会拦掉S7通信使用的一些端口,解决方法是把组态王安装目录下的程序添加到防火墙白名单,或者临时关闭防火墙测试。关闭防火墙前确认一下项目所在网络环境的安全性,不要为了调试把安全机制全关了。
故障四:两个方向的绿灯同时亮了。
这是最严重的安全问题,通常原因不是程序,而是输出点接线错位。比如Q0.2(东西绿灯)和Q0.5(南北绿灯)在端子排上接反了,PLC程序输出正确,但物理线缆把信号送到了错误的路灯上。排查方法是在PLC程序里强制点亮一个输出点,去现场看对应灯是否亮起,逐个点位做“点动”测试。这一步在IO分配表做完之后就应该做,不要等程序写完再查。
5.3 在线监控与强制输出技巧
调试阶段必须熟练使用STEP 7-MicroWIN SMART的在线监控功能。把程序下载到PLC后,切换到运行状态,点击“调试”按钮,可以在梯形图里实时看到每个触点的通断状态、每个线圈的得电状态。绿色虚线表示导通,灰色表示断开。
这个功能最有用的一点是:定位状态停滞问题。比如程序运行到东西绿灯相位,T37的定时器却没有计时,在线监控里一眼就能看到T37的使能端不满足条件。接着往上游查,发现M0.0没有置位,再查启动标志位M10.0……这样一步一步就能把逻辑链路里断掉的那一环找出来。这比对着程序干瞪眼快得多。
强制输出功能要慎用。调试LED灯组时,可以用强制功能直接把Q0.0置ON,验证输出点和灯泡是否正常。但调试完必须取消所有强制,否则下次上电可能出现“PLC没运行但灯一直亮”的怪异现象。
6. 这个项目还能怎么扩展?一段西门子1200与迁移笔记
最后多说一句关于项目扩展。十字路口交通灯作为教学项目,它的价值恰恰在于“麻雀虽小五脏俱全”。很多人做完就扔了,其实它完全可以往好几个方向继续深化。
最直接的扩展是加倒计时显示。在PLC里用定时器计算当前相位剩余时间,通过BCD码或十六进制输出到数码管驱动,或者直接把剩余秒数通过MODBUS通信发给下方LED显示屏。这个扩展涉及数值运算、数据类型转换、通信协议,难度上一个台阶,对理解PLC数据存储非常有帮助。
再复杂一点,可以做感应式交通控制,在路口四个方向埋设地感线圈,接入PLC的输入点。当检测到某个方向有车等待时,适当延长绿灯时间,无车时缩短绿灯时间。这涉及优先级判断和动态配时算法,已经非常接近实际城市智能交通系统的简化版了。
另外,很多学校和企业现在用西门子S7-1200/1500配合博途(TIA Portal)做这套项目。S7-200 SMART的程序迁移到S7-1200,在编程思路上是通的(状态寄存器法到哪都好用),但具体指令有差异。S7-1200用的是IEC定时器TON/IEC TOF这类,数据类型必须显式声明,不像S7-200 SMART这么“散养”。组态王连接S7-1200时,驱动选择也不同,要选S7-1200(TCP)驱动,且S7-1200侧需要在组态里开启“PUT/GET通信”允许。热词里也有人搜“西门子v20 put和get”“c#和西门子plc通讯”,说明这类通信问题确实是大家的共同痛点。
迁移的经验就一个:先理清数据流,再动代码。交通灯的数据流非常简单——启动信号、相位状态、输出映射、上位机监控。无论平台怎么换,这四个环节的逻辑不会变,变的只是指令表达形式。把这个骨架稳住,迁移只是体力活。
我自己做这类项目最大的体会是:控制逻辑的设计能力,永远比背指令重要。指令不会可以查手册,逻辑一塌糊涂,换什么PLC都白搭。十字路口交通灯的项目虽然小,但它把“需求分析 -> IO规划 -> 程序实现 -> 上位机组态 -> 联调验证”这条完整的工程链路走了一遍,这才是它真正的价值所在。