我第一次接触这类控制项目时,心里想得比较简单:红绿灯嘛,无非是东西一组、南北一组,定时器来回切换就行。直到真正接手一个带左转专用车道、要求分高峰平峰方案、还希望支持夜间黄闪和车检器感应的路口,才发现“PLC道路交通灯控制系统”这几个字里藏着不少讲究。这篇文章以一个四相位路口为对象,从需求拆解到时序设计、梯形图实现、再到现场调试问题排查,完整走一遍“基于PLC的复杂道路交通灯控制系统”的设计实现过程。内容偏工程实操,适合正在做交通灯课设、比赛项目或准备接手类似小型交通控制项目的朋友。
1. 先理需求:这个红绿灯路口到底要解决什么问题
1.1 课程设计里的交通灯和真实路口的差距在哪里
很多人最早接触的PLC交通灯课题都是简化版——一个十字路口,东西方向一组灯,南北方向一组灯,时间一到就切。这种模型只能说把“定时循环”练明白了,离真实控制还差得很远。
实际的路口往往比这个复杂,至少要面对四个层面的问题。第一是相位需求,如果一个路口左转车流量大,光靠直行绿灯时对向车流里穿插左转是很危险的,需要单独给左转车一个放行相位,这就从两相位变成了四相位,程序逻辑量直接翻倍。第二是多模式运行,交通流量在一天里面波动很大,早晚高峰和平峰时期的绿灯时间如果完全一样,要么高峰期路口堵死,要么平峰期绿灯空放,所以要能按时间段切换不同的配时方案。第三是非正常工况,比如半夜车流量很小时如果还按128秒大周期跑,所有方向都在白等,这时候若能把主路方向改成黄闪、支路方向改成红闪,通行效率和安全性能同时兼顾。第四是人工干预,交警在现场疏导时可能需要手动放行某个方向,或者有急救车通过时需要特殊优先,这个“人的需求”必须压过自动程序。
课程设计只让你证明PLC能做定时循环,而真实项目是在做一台小型交通信号控制机。理解了这个差距,后面每一步才不会走偏。
1.2 把控制模式先列成一张表,再谈编程
动手写梯形图之前,最忌惮的就是直接开写。工控项目里有个习惯叫“先列需求清单再动程序”,交通灯也一样。我习惯把整个系统要支持的控制模式整理清楚,每一条都对应到输入信号、输出动作和切换条件。
以这次做的四相位路口为例,我整理出了五类工作模式。自动定周期模式是默认状态,程序按交通量设置好的四相位时序循环运行;多时段切换模式是在自动模式基础上做的高峰平峰方案切换,比如早高峰用周期140秒的方案,平峰用128秒,晚高峰再用另一个参数,切换时机可以靠时钟或外部拨码开关实现;夜间模式则是在深夜把某个方向切到黄闪加红闪;手动干预模式是在交警操作台把系统切到手动,可以按方向控制放行,多用在早晚高峰的路口疏导或事故处理;紧急优先模式相对特殊,属于“按一下就让指定方向尽快放行”的模式,往往配合急救车或消防车通过场景,不常用但必须预先安排。
实际需求清单出来后,程序结构就会很清晰。这个清单同样是后面做功能测试的验收依据。我见过不少新手一上来就编梯形图,最后东补一个点西加一个输出,程序一团乱麻,根源就是没有先把控制模式和边界条件理清楚。
1.3 根据需求和I/O点数选型,别一上来就买大PLC
控制模式确定之后,I/O点数就能估算出来了。这里说的I/O点不是随便拍脑袋的数,而是把输入信号和输出负载逐项列出来。
输入侧我这边安排了这些信号:启动运行信号X0、高峰/平峰方案切换开关X1、夜间模式开关X2、自动/手动模式切换开关X3,手动模式下操作台还会给两个方向放行按钮X4和X5。另外车检器信号也要进PLC,比如主路方向检测到有排队车辆的输入X6、支路方向检测到有等待车辆的输入X7。急救车优先用X10。输出侧则主要是信号灯组,因为四相位路口东西方向和南北方向各有直行、左转两组灯,每组红黄绿三色,再加上夜间黄闪提示和蜂鸣器报警,大致需要十多个输出点。
选PLC的时候,我建议按估算I/O点数再加20%~30%的余量来选。比如需要14个输入、16个输出,就最好选一台输入输出都够、还带一定扩展能力的主机。实际方案里我用的是一台24点规模的国产PLC,输入输出数量正好有余量。需要特别提醒的是输出类型,交通灯通常都接220V交流灯具,我优先推荐继电器输出型PLC,或者用晶体管输出型PLC外接中间继电器,再由继电器触点去控制220V灯。千万不要直接用晶体管输出点去接220V负载,那基本是烧点事故的源头。
2. 相位与时序设计:128秒一个周期的推导过程
2.1 先定“相位”,再谈红黄绿
“相位”这个词很多初学者会绕晕,用一个生活化的例子解释就非常清楚。路口的交通流就像舞台上的演员,你不能让所有人都同时上场,必须把人分成几组,按顺序让每组上台表演,这个“组”就是一个相位。在信号控制里,相位就是“某一组互不冲突的车流同时获得通行权的时间窗口”。
我给这个路口定的是四相位方案。第一相位是东西方向直行,也就是东西双向直行车一起放行;第二相位是东西方向左转,放行东西双向左转到对向的车辆;第三相位是南北方向直行;第四相位是南北方向左转。四个相位轮流执行,每个方向的车流都有自己的专用放行时间,不会出现直行和左转在路口中间打架的情况。
实际路口也常见两相位或三相位方案,比如不设左转专用相位,左转车跟着直行车一起依空隙穿过路口。两相位方案的周期短、等灯时间短,但左转车与对向直行冲突明显,安全性和通行效率都要打折扣。我这个案例因为路口左转车流量较大,才采用了更稳妥的四相位。这个取舍本身就是一个典型的控制策略选择问题,不是越复杂越好,而是要看车流特征。
2.2 每个灯的持续时间怎么定,经验加现场标定
定了四个相位后,需要给每个相位分配绿灯、黄灯和全红时间。绿灯时间并不是越长越好,因为一个方向绿得久,另一个方向就得等得更久,整条路的总周期会拉长;周期太长,红灯方向排队的人容易失去耐心,实际通行效率反而下降。
在这个案例里,我初始参数是这样定的:
| 相位 | 方向 | 绿灯时间 | 黄灯时间 | 全红时间 | 相位合计 |
|---|---|---|---|---|---|
| 相位一 | 东西直行 | 40秒 | 3秒 | 2秒 | 45秒 |
| 相位二 | 东西左转 | 20秒 | 3秒 | 2秒 | 25秒 |
| 相位三 | 南北直行 | 30秒 | 3秒 | 2秒 | 35秒 |
| 相位四 | 南北左转 | 18秒 | 3秒 | 2秒 | 23秒 |
完整的信号周期就是45+25+35+23=128秒。为什么加全红时间?黄灯是告诉正在路口内的车“马上红灯了,能过就快过,不能过就准备停”,但黄灯结束时,路口内可能还有来不及完全清空的车,所以再加一个“所有方向全红”的时间,让路口彻底清空,避免下一相位放行的车冲进来撞上上一相位来不及离开的车。全红时间通常按路口尺寸和过街距离标定,一般不小于2秒。
这套参数不是一拍脑袋来的,而是根据早晚高峰和平峰时段的路口流量做了初步设计,然后再到现场观察实际排队长短微调。做好项目后,程序里还保留了定时器参数修改入口,方便现场不用改程序就能把绿灯时间数值调成想要的值。
2.3 时序逻辑里不可突破的几条红线
时序设计看似只是时间分配,其实里面藏了几条安全红线。我自己在做的时候把这些红线当成“硬件联锁”和“软件联锁”的双重约束来落实。
第一条是互锁条件:在任何一秒内,东西方向的绿灯不能和南北方向的绿灯同时亮,左转绿也不能与对向直行绿同时亮,只有当某个方向在放行时,冲突方向必须保证红灯。第二条是全红清空时间不可缺少,尤其是从直行切左转或从东西切南北的瞬间,如果全红时间去掉,上一波车和下一波车很容易在交叉路口相遇。第三条是黄灯的过渡角色不能被程序覆盖,部分调试场景下为了赶时间,人会想跳过黄灯直接切红灯,这对已经接近路口、正加速准备通过的驾驶员非常危险,程序逻辑上不能留下这种漏洞。第四条是任何模式切换、手动干预、急车优先动作,都要平滑过渡到安全状态,而不是瞬间改变灯色。
如果把这几条放在程序逻辑的后面做统一约束,前面的状态计时再怎么自由切换,最终输出层的安全条件也会兜住。
3. 梯形图实现:用状态机把复杂时序拆成接力棒
3.1 为什么我不用一堆定时器互锁,而是选择状态机
很多新手做交通灯时,常用的写法是一排定时器首尾相接,东西直行定时器时间到触发东西左转定时器,再触发南北直行,类似链条。这种方式写出来的程序在课后练习里看起来没问题,可一旦要支持多模式切换、手动干预,或者中间要插一个紧急优先分支,定时器链条就会变得极其难维护——加了新模式后你往往要动一整串定时器逻辑,很容易改动一个地方就带来新的时序冲突。
我更推荐用“状态机”的思路来写,业内有些工程师也叫“步进控制法”,本质就是把整个运行周期拆成若干个固定的状态,每个状态对应一个或几个灯色组合,同一时刻永远只有一个状态处于激活状态,时间到了就交出“接力棒”,让给下一个状态。用一个形象的比喻就是,状态机像一场接力赛,每个状态是一段赛道,只有当前拿着接力棒的人可以跑,到他交棒之前别人都不能抢跑。这就让任意瞬间的灯色组合变得可预测,排查问题的时候也容易定位到底卡在哪个状态。
3.2 状态迁移的梯形图框架,掌握这一套就够用
四相位加黄灯和全红时间,相当于把这个信号周期拆成了12个状态,分别用M0到M11表示,每个状态代表一种灯色组合和时间窗口,对应的逻辑是:M0东西直行绿灯40秒,时间到跳M1;M1东西直行黄灯3秒,时间到跳M2;M2全红2秒清空路口,时间到跳M3;M3东西左转绿灯20秒,时间到跳M4;M4东西左转黄灯3秒,时间到跳M5;M5全红2秒,时间到跳M6;M6南北直行绿灯30秒,时间到跳M7;M7南北直行黄灯3秒,时间到跳M8;M8全红2秒,时间到跳M9;M9南北左转绿灯18秒,时间到跳M10;M10南北左转黄灯3秒,时间到跳M11;M11全红2秒,完成后跳回M0,开始下一轮循环。
状态迁移代码框架其实不大,核心就是“状态激活时驱动对应定时器,定时时间到后置位下一个状态,同时复位当前状态”。我这里以三菱FX系列为例写一小段,其他PLC只要把定时器号、状态位号换成自己的软元件表就行。
; 状态M0激活,东西直行绿灯计时40秒 LD M0 AND M100 ; M100为自动运行总标志 OUT T0 K400 ; 定时器时基0.1秒,K400表示40秒 ; T0时间到,激活M1并复位M0,完成状态切换 LD T0 SET M1 RST M0同理,M1状态激活时驱动T1,T1时间到后SET M2,RST M1,一路做到M11状态结束再跳回M0。采用这种框架后,每个状态的时间修改只需调整对应定时器的常数,不需要去翻一大串互锁逻辑,维护成本低很多。
3.3 状态位不能直接驱动灯,输出层要过互锁
有人可能觉得,状态机搞清楚了,那直接把M0对应东西直行绿灯,M1对应东西直行黄灯不就可以了吗?如果只是演示模型或许够用,但真实交通灯控制不能这么做,原因在于状态位一旦出现异常,比如多个状态同时置位或者程序被在线修改时扫描出现问题,输出会直接跟着乱套,现场就会变成危险场景。
更稳妥的方法是把状态位和灯输出分开,状态位只表示“当前逻辑运行到哪里”,真正的灯输出由一组独立的“输出映射逻辑”来生成。只有到位状态和模式条件都满足时,某个灯才允许点亮,且输出互锁在最终继电器回路里再兜一层,保证冲突方向的灯不能同时亮。东西方向绿灯的输出条件,我会写成状态机在M0、自动运行标志有效、并且南北方向没有绿色放行状态,条件全部满足才输出。类似地,对应方向黄灯条件则在M1等黄灯状态,红灯则在非本方向绿、黄的其余状态亮。
梯形图里如果全用“非”的逻辑去驱动红灯会显得很长,但在产品化程序里这种冗余是值得的。最终还有一个“物理输出互锁”在配电柜层面兜底,把东西方向绿灯的继电器常闭触点串联到南北方向绿灯继电器回路中,反过来也一样,这就是硬件层面的安全保证。
3.4 程序整体架构:循环、模式和输出三层分离
整套程序的架构如果画成示意,会分成三层。最内层是状态循环层,负责M0到M11的状态迁移;外层是模式判断层,负责判断当前是自动、夜间、手动还是急车优先,为内部循环输出使能信号;最外层是最终灯输出映射层,负责把状态和模式翻译成真正点亮哪个灯,并集中做互锁。
这种“状态循环、模式判断、灯输出映射”分离的好处非常多。一是加模式不用改状态机本体,比如夜间模式只是在模式判断层多了一个分支,不需要把状态机里的定时器换掉。二是做故障排查时能快速定位,信号灯不亮可能是状态被卡住、模式条件不满足、输出映射点错误或外部继电器故障,好定位。三是别人接手项目看程序时也不会陷入大段大段的定时器嵌套。
4. 多模式扩展:高峰、夜间、感应、手动优先怎么融进去
4.1 多时段方案切换:别让绿灯在切换瞬间突变
自动定周期模式里,我设置了高峰、平峰两套配时参数,本质上就是让状态机循环时的定时器常数可以按当前方案改变。这个改动不需要改状态机结构,只需要给每个状态配一个“当前方案对应的计时值”,方案切换时更新这些值。
但有一个坑值得注意:如果早晚高峰切换发生在一个方向的绿灯才刚起步时,直接把时间改成新方案,会出现本来刚亮起的绿灯变成红灯,后面排队的车完全没时间通过,容易引发急刹车。所以我做的方案切换不是“立即生效”,而是“等当前相位完整走完这个绿灯、黄灯、全红结束后,从下一个循环开始使用新参数”。实现的时候可以加一个“切换请求位”,用主循环在回到M0之前检查这个请求位,再把实际时间参数换成目标方案,这样路口车流不会在切换瞬间被打乱。
4.2 夜间黄闪加红闪:直接输出会闯祸
夜间模式的设计和白天自动模式差异很大,核心思想不再是按顺序放行车辆,而是提醒主路司机注意观察、谨慎通过。在这个项目里,我按当地交管部门的习惯设置了“主路方向黄灯闪烁、支路方向红灯闪烁”的方案,如果你们有实际需求,请务必以当地可执行的交通组织要求为准。
黄闪和红闪都不能直接给输出置位,必须用周期脉冲信号去驱动灯,通常是1秒一周期、0.5秒亮0.5秒灭。以三菱FX系列为例,M8013就是1秒脉冲特殊继电器,只需要把它串到黄灯或红灯输出回路里,灯就会自动闪起来。
进入夜间模式时我会同时做两件事:一是把自动状态机的主允许位关掉,让M0到M11不再前进,相当于“废掉”白天顺序逻辑;二是由模式判断层接管灯输出,按“夜间模式输出”去点亮黄闪和红闪。从夜间切回白天时同样要注意,先把状态机强制复位到M0并保证全红状态至少持续一小段时间,然后再开始自动循环,避免早晨模式切换瞬间出现冲突方向同时变绿的情况。
4.3 车检器“半感应”控制:有车才延,没车不空放
如果路口支路车流量很不均匀,高峰时段有排队,平峰时段则可能连续几分钟都没一辆车,这时候定周期站在支路方向就会一直空放绿灯,主路方向却白白等红灯。为了减少这种浪费,这个项目里我加了一个“半感应控制”逻辑,方向是“主路常绿、支路按需放行”。
实现思路是这样:当支路方向车检器检测到有车等待时,程序会在主路绿灯剩余时间差不多时提前结束主路绿灯,转入支路方向的放行相位;如果支路方向长时间没有车来,那么主路绿灯会保持到最大绿灯时间,不轻易切换。感应控制的参数涉及最小绿灯时间、最大绿灯时间和单位延长绿时间,典型设置是支路方向车检器一旦触发,每次给支路绿灯延长5秒,直到达到最大绿灯时间后强制切换,且切换前黄灯和全红时间不做任何省略。
梯形图里的实现要在状态机外增加一个“延长请求”标志,状态机在支路绿灯时间快结束时检查这个标志,有车就再给当前状态增加一次计时,没有就直接跳到下一状态。这个标志的采集要加滤波,避免车检器信号抖动造成频繁延长,一般可以用PLC内部定时器做一个0.2秒左右的确认。
4.4 急救车优先:抢时间的前提是先把路口清空
急救车优先功能平常不用,真到用的时候就要求快速、安全地让指定方向获得放行。我设计了一个“急车请求”按钮,按下后程序不直接跳到目标方向绿灯,而是先进入全红清空,让所有方向的车都停下来,路口清空后再把指定方向放行。
这个“先清空再放行”的顺序非常关键,绝不能省略。比如急救车从东往西行驶,系统检测到请求后,会先强制让全路口进入2秒左右的全红状态,然后置位东西直行绿灯并保持20秒到30秒。放行结束后,如果模式选择的是自动恢复,则从东西直行状态之后的位置继续接力;如果现场交警还需要继续疏导,也可以由交警保持在手动干预状态。紧急优先分支虽然平时不跑,但它在程序里必须放在最高优先级,任何自动状态都不能把它的方向灯抢走。
5. 现场调试与故障排查手册
5.1 上电前的检查:先干完这三件事再送电
现场调试最容易出的问题不是程序逻辑,而是接线和供电。我每次上电前都雷打不动做三件事。
第一,对照I/O分配表逐一检查每根线。PLC输入端子和输出端子经常会被接错位,尤其输出侧有十几个灯点的时候,把红、黄、绿接到错位输出点上的概率非常大。送电前用万用表电阻档或通断档逐根校验,比送电后发现两方向同绿再断电要安全得多。第二,检查输入公共端接法。这个坑在感应车辆检测器时经常出现,传感器如果是NPN输出,PLC输入公共端就需要接电源正极,输出导通时拉低电平;如果公共端接反了,信号状态会一直不对。接之前一定先查PLC手册确认输入模块是漏型输入还是源型输入。第三,检查输出公共端和负载电源隔离。如果PLC是继电器输出型,输出公共端为COM端,务必要确认现场信号灯采用的是哪个电源系统。我的做法是PLC输出点统一接DC24V中间继电器,再由中间继电器触点控制220V信号灯,PLC部分和动力部分完全隔离,既保护了PLC输出点,又让现场检修更安全。
5.2 没有真实信号灯,怎么在实验室把逻辑调明白
不是所有人一开始都有条件在真实路口调试,实验室阶段用模拟灯板完全可以把逻辑验证到足够充分。我使用的是DC24V的LED信号灯模拟板,每组红黄绿都接到对应的PLC输出端子,再用开关模拟启动信号、模式切换信号和车检器信号。
调试时重点观察几个截面:一是状态是否按M0到M11依次推进,可以在PLC编程软件的监控表里直接看M0到M11的状态,也可以看编程软件里的元件监控,哪个状态位为ON,信号灯应该呈什么颜色,完全能对上。二是每个相位的时间是否准确,可以用秒表计时,连续观察三个完整周期,绿灯秒数在允许误差范围内才算通过。三是模式切换是否平滑,切换高峰方案要验证“当前周期结束后才生效”;切夜间模式要验证指示灯是否按1秒脉冲闪烁。四是手动和急车优先后能否恢复正常自动运行,尤其要验证恢复正常时不会出现冲突方向绿灯同亮的情况。
5.3 现场调试常见问题速查表
现场遇到的问题五花八门,把比较典型的几个现象和对应排查思路整理成一张表,可以帮同行在调试时少走弯路。
| 现象 | 可能原因 | 排查与处理方法 |
|---|---|---|
| 信号灯不亮,PLC输出指示灯有输出 | 中间继电器线圈没得电或损坏,接线端子松动 | 查DC24V电源,用万用表量中间继电器线圈两端电压,确认触点动作 |
| 两个方向的绿灯同时亮 | 程序状态位异常或输出互锁条件被绕过 | 立即断开输出电源,检查状态位是否多状态同时为ON,检查最终输出互锁逻辑 |
| 一个方向黄灯亮完后直接变红,看不到黄灯过程 | 状态切换过快,定时器值设错或误用了常开触点立即触发下一状态 | 查该黄灯状态定时器设定值和触发器逻辑 |
| 夜间模式切换后黄灯常亮,不闪 | 输出逻辑没有接1秒脉冲,直接置位黄灯 | 用PLC内部特殊继电器脉冲信号替代置位输出 |
| 手动干预结束后自动程序从错误相位开始 | 自动状态机没有进行安全复位 | 增加全红清空状态,从M0重新开始或从当前相位合理位置开始 |
| 车检器信号时有时无,绿灯延长不稳定 | 输入信号没有滤波,车检器信号受干扰 | 在梯形图中加输入滤波,检查信号线是否与动力电缆平行敷设 |
| 某一路灯常亮无法熄灭 | 输出触点粘连或外部继电器卡死 | 断电后检查该路中间继电器触点,必要时更换继电器 |
5.4 现场调试时最容易暴露的几个认知误区
调试过程里没有一次是顺顺当当走完的,很多问题不是程序算不出来,而是对现场条件下的设备行为缺乏预判。第一是输出触点容量和负载冲击电流问题,LED信号灯虽然单灯功率不高,但驱动器内部有电容,上电瞬间的冲击电流可能是稳态电流的数倍,如果中间继电器触点容量选得过小,用几个月后就会出现触点粘死,灯永远处于点亮状态,非常危险,所以每路输出最好串一个合适的熔断器,继电器容量适度放宽。第二是“黄灯期间方向红灯到底亮不亮”的问题,很多人写程序时习惯把红灯定义为黄的逻辑非,结果黄灯一亮,同一组红灯也同时点亮,实际灯色瞬间从绿变成红加黄,这不符合驾驶员的预期,正确信号灯状态应当是每时每刻每组红黄绿灯只亮一盏,黄灯期间红灯必须灭,等黄灯结束红灯才亮起来。第三是感应控制不要做得过于灵敏,随便一辆自行车压过车检器就延长绿灯,会造成主路频繁被支路打断,影响主干线绿波带