ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

西门子S7-1200 Plus博图V15.1六层电梯PLC控制程序全解析

西门子S7-1200 Plus博图V15.1六层电梯PLC控制程序全解析 前阵子刚把一台六层住宅电梯的程序完整跑通用的是西门子1200 PLC加博图V15.1前后断断续续改了三个版本才收工。这次开发记录对我来说挺有代表性因为在电梯控制这个行当里六层看起来是最小配置但“麻雀虽小五脏俱全”内呼、外呼、自动平层、开关门、安全互锁、楼层显示、通讯上屏一样都跑不掉。很多刚接触工控的朋友以为电梯程序很简单无非就是按下按钮灯亮、到了楼层灯灭实际上等你自己开始写逻辑就知道这里面坑不少尤其是电梯在运行中随时可能来新召唤、方向要在运行中动态决策、平层信号带毛刺、按钮信号要消抖、接触器要互锁。这篇文章就把整个开发过程拆开聊聊从整体设计到具体程序块分配从地址规划到UDP组播楼层显示的实战处理给准备用1200写电梯的朋友做个参考。1. 六层电梯控制的核心思路拆解1.1 电梯自己怎么知道站在哪儿写电梯程序的第一件事不是写呼梯而是先把“轿厢位置判断”搞清楚。电梯不像人人一睁眼就知道自己在几楼电梯必须靠传感器去感知。六层电梯最常见的做法是在井道每层平层位置装平层感应开关轿厢上装一个隔磁板或者说遮磁板轿厢走到哪一层隔磁板插入该层的平层开关感应开关动作PLC就知道电梯当前在哪一层。我在这个项目里选用的是常开型接近开关型号是直流三线NPN常开24V供电。每一层装一只所以楼层输入信号是I0.0到I0.5共六个分别对应一楼到六楼。注意一个问题平层开关给出的信号是“该层已到达”但电梯运行过程中经过中间楼层时这个信号也会闪一下所以程序里不能简单地“哪个开关亮就认为在哪层”而是要做成“运行到目标层时触发停止停止后由当前平层开关锁定楼层位置”。也就是说楼层的显示和停车判断要分开处理。位置判断逻辑我做了两层保护一层是减速感应开关在每层目标停靠点上方一段距离安装用于触发低速爬行另一层是平层感应开关用于最终停车。这样做的好处是电梯不会因为高速冲过头而靠撞限位来停车控制更柔和对机械冲击也小。1.2 呼梯信号怎么存、怎么消电梯要处理的呼叫信号分两类轿内选层信号和厅外召唤信号。轿内选层是乘客按目标楼层厅外召唤分上行和下行两种比如二楼有个人要去五楼按上行那上行召唤灯亮电梯路过二楼并且方向向上的话就开门接客。这些信号都需要“记忆保持”。什么叫记忆保持就是你按完按钮电梯没到按钮灯不能灭信号要一直记着直到电梯到达这个楼层并且开门信号才清除。这种“登记—响应—消除”的循环就是电梯呼梯管理的本质。我在博图V15.1里用内部的M点做信号记忆。轿内选层用M1.0到M1.5六个点厅外上行用M2.1到M2.5厅外下行用M3.1到M3.5。为什么不用Q输出点直接记忆因为Q点可能被触摸屏占掉也可能在调试时强制修改用内部M点是纯逻辑映射后面要接到指示灯输出或者HMI显示都方便。信号消除也要讲究时序。很多新手会在电梯“刚到某层”那一刻就清掉呼梯信号这样容易出现一个问题电梯还没完全停稳门还没开信号先灭了乘客一脸懵以为电梯坏了。正确的做法是先识别到目标层然后停车开门到位后再清信号。我甚至加了1秒的延时确保门机已经在动作信号灯才熄灭体验上更像“这层确实服务到了”。2. 博图V15.1环境下的工程规划2.1 I/O点分配与硬件组态写程序之前先把硬件和地址规划好这一步做得越细后面改程序越省事。这台设备用的CPU是西门子S7-1200具体型号是1214C DC/DC/DC自带14路数字量输入和10路数字量输出。六层电梯数字量输入点比较多我简单列一下信号类型数量地址规划平层感应开关1-6层6I0.0-I0.5减速感应开关1I0.6轿内选层按钮1-66I1.0-I1.5厅外上行召唤2-5层4I2.0-I2.3厅外下行召唤2-5层4I2.4-I2.7开门按钮/关门按钮2I3.0-I3.1门联锁/安全回路反馈2I3.2-I3.3上/下运行接触器反馈2I3.4-I3.5这里有个细节值得说底层和顶层只有单方向召唤。一楼外面只有上行按钮六楼外面只有下行按钮这是物理逻辑规定的否则电梯在六楼还有人按上行那基本是瞎按。输出点规划上因为是DC/DC型PLC驱动的负载是中间继电器不直接驱动接触器线圈中间继电器再带接触器这样PLC的输出点寿命会长很多。输出点分配如下上运行接触器、下运行接触器、开门继电器、关门继电器、楼层指示灯用BCD码或者二进制给HMI显示等。楼层指示灯我用了Q4.0-Q4.3做二进制编码输出通过译码驱动数码管显示四个点就能显示六层楼。2.2 程序块怎么划分才能不后悔很多自学者写PLC有个习惯所有逻辑全部堆在OB1里几千行往下写写到后面自己想找某段逻辑都翻半天。我这次是严格按照功能模块去分FB和FC的OB1只负责调用具体逻辑全部封装在功能块里。划分如下OB1主循环扫描周期调度调用各FC和FB监控系统状态FC100“信号采集”把按钮、限位、安全回路的输入信号做滤波和消抖生成中间变量FC200“呼梯管理”登记内呼、外呼处理信号保持与清除逻辑FC300“方向决策”根据当前楼层、目标层集合决策电梯是上行还是下行以及在哪一层停FC400“运行控制”控制接触器启动停止、减速点判断、平层停车逻辑FC500“开门关门”处理开关门请求、开门延时、光幕保护信号FB600“UDP通讯”封装S7-1200的T_SEND_TO指令把电梯状态广播到组播地址FB700“故障处理”超速、限位触发、安全回路断开时跑保护逻辑这样的划分有一个直接好处调试的时候可以单独监控某个FB。比如方向决策不对我只看FC300的输入输出不用把上千行逻辑都拉进监控画面。另一个好处是如果有第二台电梯呼梯管理、方向决策这些块可以直接复制过去修改逻辑基本通用改I/O映射就行。博图V15.1里面创建FB的时候注意选“仅受调用时保存数据”还是“在背景数据块中保存数据”。电梯这种需要跨扫描周期保持状态的逻辑必须选“在背景数据块中保存数据”否则调用结束内部变量就丢了状态没法保持。3. 核心逻辑开发电梯动起来的关键代码思路3.1 平层判断与楼层锁存前面提到了用平层开关判断楼层这里把代码思路展开细说。电梯的六个平层信号是I0.0到I0.5运行中经过中间层会闪一次所以不能“见信号就更新当前楼层”必须做一个锁存逻辑。我定义了一个整型变量CurrentFloor用DB存储同时定义Bool数组FloorNear[1..6]存储六个平层开关的滤波状态。平层信号进入程序后首先做一个50ms的延时滤波防止开关抖动导致误判。滤波之后的信号如果电梯处于运行状态且尚未平层停车则不更新CurrentFloor只有当所有条件满足“电梯停止”“安全回路正常”“开门过程已启动”时才把当前激活的平层层号锁存到CurrentFloor。这个设计的本质是楼层显示值不是实时追随传感器而是“在系统确认自己稳定停靠后”才更新。好处非常明显——电梯从一楼跑到六楼的过程中HMI上显示楼层不会乱跳。如果你让楼层显示实时跟随平层信号电梯经过三四五楼的时候显示屏会疯狂闪乘客体验很差。减速信号也是一样处理。每层楼在平层前一段距离装了减速开关电梯收到减速信号之后切到低速爬行直到平层信号出现就停车。如果电梯是从低速状态去平层的平层瞬间停车准确度很高。3.2 呼梯信号的登记与消除逻辑呼梯登记逻辑内呼和外呼虽然功能不同但框架是一致的输入是按钮上升沿输出是M点记忆置位消除条件是“电梯已到达该层且完成开门动作”。我在FC200里用一个组织起来的逻辑来处理六个内呼、八个外呼而不是写六个完全重复的网络。具体做法是用SCL语言写一个带参数的重用逻辑循环处理每层。SCL的核心代码结构是这样FOR i : 1 TO 6 DO // 内呼登记 IF #innerBtn[i] AND NOT #innerReg[i] THEN #innerReg[i] : TRUE; END_IF; // 开门到位后消除 IF #arriveFloor i AND #doorOpenDone AND #innerReg[i] THEN #innerReg[i] : FALSE; END_IF; END_FOR;外呼处理比内呼多一个方向维度。上行召唤只有当前电梯运行方向向上且未超过该层时有效下行召唤同理。这里我先说登记和消除方向匹配放到方向决策里去讲。按钮信号要不要消抖必须的。现场按钮线比较长而且常开触点闭合瞬间有抖动直接拿来做上升沿检测很容易产生误触发。我用的是“延时滤波沿检测”的组合先把按钮信号接入一个10ms的TON定时器定时器输出再做沿检测。实测下来这个时间挡位对绝大多数机械式按钮都够用如果你现场按钮明显老化可以把时间拉到20ms。有一个小坑要提醒有些电梯控制板用的是“按钮按下置位、松开复位”的逻辑也就是保持型信号只在按住期间存在。但电梯呼梯显然不能这样你按完一亮灯人走了灯必须还亮着所以必须用置位指令去保持。SCL里就是用TRUE赋值梯形图里就是SET指令。3.3 方向决策电梯往哪走、停哪层方向决策是电梯程序里最烧脑的部分尤其是有多个呼梯信号同时存在时。电梯不是“谁先按谁优先”这么简单而是要在同一个方向上把所有顺路呼梯全部响应完然后再换向。这样做既节能又高效乘客等待时间最短。我设计的算法是这样从当前位置出发如果电梯静止先判断有没有上行方向的呼梯。上行方向的目标层包括当前层以上的内呼、当前层以上的上行外呼、以及所有下行外呼中位于当前层以上的。如果当前层以上没有任何呼梯则电梯转为下行。运行过程中电梯在每次经过一个楼层时检查“当前运行方向上是否有该层呼梯且当前层呼梯的方向标签与运行方向一致或者当前层是内呼”如果满足则在这个层停车。当所有同方向呼梯都响应完毕后如果还有反方向呼梯则电梯换向如果没有呼梯电梯回到待命楼层待机。这里合挤成代码就是SCL的方向判断块// 找当前层以上是否有目标 FOR i : CurrentFloor 1 TO 6 DO IF #innerReg[i] OR #upCallReg[i] OR (CurrentFloor i AND #downCallReg[i]) THEN #anyAboveTarget : TRUE; EXIT; END_IF; END_FOR; // 找当前层以下是否有目标 FOR i : 1 TO CurrentFloor - 1 DO IF #innerReg[i] OR #downCallReg[i] OR #upCallReg[i] THEN #anyBelowTarget : TRUE; EXIT; END_IF; END_FOR;注意一个关键细节下行外呼可以被上行运行中的电梯响应但响应条件是“电梯上行经过它所在楼层时它还没有被服务过”。这个逻辑有点像区块链里的“顺路捡人”——我在上行途中路过二楼二楼有人按下行我不停下来接也不行不然他永远等不到。但反过来如果我在上行途中五楼有人按上行五楼比我当前位置高这个信号要等我到达五楼再判断如果五楼的内呼和上行外呼都存在优先做一个。为了把这个处理好我给每个外呼信号加了两个属性响应标记和生效标记。响应标记表示“电梯已经把这个呼梯作为当前运行方向上的候选目标”一旦同一方向上经过该层并开门响应标记和呼梯信号一起清除。生效标记则是防止反方向呼梯在错误方向被提前响应比如电梯下行时三楼下行外呼是有效目标三楼的上行外呼则被暂时屏蔽避免电梯在三楼停两次。3.4 开关门逻辑和安全互锁电梯门的控制是乘客直接感受到舒适度的环节也是出问题最多的环节。开门信号来源有三个到站自动开门、轿内开门按钮、开门状态保持关门信号来源有关门按钮、开门延时到、本层无人且内呼外呼都清零的长时间待机。我用的开关门逻辑是电梯停止且平层成功后自动触发开门开门输出保持直到开门到位限位动作或开门延时默认4秒结束。关门动作必须在“所有呼梯在轿厢内的乘客已上齐”假设下发生所以关门按钮和延时关门是一回事只是在延时关门之前会先响蜂鸣器提醒。关门过程中如果光幕被遮挡立即重新开门并重新计算4秒延时。光幕信号是常闭型遮挡时断开程序设计上要取反处理。最关键的门没有关好、门联锁没有闭合绝对不允许输出运行接触器。这个互锁放在最底层的安全逻辑里任何状态和信号都不能绕过它。具体到博图实现安全互锁我用了一个专门的Bool变量“SafeOK”作为总开关。它是所有安全条件的“AND”急停未按下、上下限位未触发、安全继电器正常、门锁闭合、变频器无故障。这个SafeOK为FALSE时FC400运行控制块里的所有启动条件都直接跳过运行接触器输出强制为FALSE。这样做有一个好处你不需要在每一处运行逻辑里都写一遍安全条件而是集中在底层一票否决非常干净。开门到位和关门到位限位用的是两个常开点门开到顶触点闭合门关到底触点闭合。这里有一个实际经验门机限位开关安装在门机上长期高频动作容易磨损建议程序里对每个限位信号做30ms滤波同时如果开门信号输出超30秒门还没有到位则判定门机故障并解除所有运行输出避免门机卡住但PLC一直给电烧电机。4. 用UDP组播做楼层显示与监控通讯4.1 为什么这个项目用了UDP组播电梯的楼层显示和监控数据传统做法是直接接硬线到数码管或者用一个触摸屏通过Profinet连接PLC读取显示。这台项目的特别之处在于现场有多个显示终端需要同时收电梯状态——轿厢内一块显示屏、每层厅外一块指示屏、监控室上位机也要看而且这些终端不在同一个牌子下有的是嵌入式板、有的是PC机、还有触摸屏。如果每台终端都做一次点对点TCP连接PLC的以太网资源会非常紧张而且TCP建立连接再断开的管理对S7-1200来说并不划算。这时候UDP组播就显示出优势了——组播是发出一个数据包所有加入同一组的终端都能收到天然适配“一台上位、多端显示”的架构。我知道有些朋友会问为什么不直接用PROFINET把所有显示屏都拉成IO设备原因在于终端设备并不都支持Profinet从站协议有的就是一块支持UDP收发的串口屏或者以太网屏用组播通用性最好。另外组播不要求建立TCP会话那种三次握手的开销终端断线、重连也不影响PLC端逻辑很适合这种广播场景。4.2 数据包怎么封装、地址怎么选S7-1200从固件4.0开始就支持开放式以太网指令在博图V15.1里直接调用T_SEND_TO和T_RECV_FROM指令。发送侧我用一个循环中断OB100其实OB100是启动组织块循环中断应该用OB30/OB31这类定时中断组织块每200ms调用一次FB600把电梯状态打包发送。如果发送周期太短比如20ms不仅占用CPU还可能把交换机搞出压力200ms对楼层显示和监控来说足够了HMI上看起来也是实时的。组播地址我选用了239.255.1.100端口是5000。这个地址段属于IPv4组播保留地址在局域网内部使用是标准做法。注意S7-1200发送组播时需要在指令参数里填上组播地址同时CPU本机的网卡要能支持组播发送一般固件版本够高都没问题。打包数据我定义了一个结构体包含以下字段字段数据类型说明HeadWord帧头固定0xAA55用于帧同步FloorByte当前楼层1-6DirectionByte0停止 1上行 2下行DoorStateByte0全关 1开门中 2全开 3关门中SpeedInt当前速度百分比FaultCodeInt故障代码0为正常TailWord帧尾固定0x0D0A结构体长度是固定的接收端解析起来非常方便。我在工控机上用Socket打开同一个组播地址和端口调用WSASocket加IP_ADD_MEMBERSHIP就能收到。如果用嵌入式屏很多支持MQTT或者自定义串口屏的厂家也提供了UDP接收接口只需要把结构体当成二进制数据流处理即可。发送逻辑的代码结构大概是#sendArray[1] : 16#AA55; // 这是示意实际要按字节填充 // 填充楼层、方向、门状态等数据 #data : T_SEND_TO( REQ : #sendFlag, ID : 1, LEN : 14, DEST : #组播IP, DATA : #buffer );调试中我发现一个很隐蔽的问题S7-1200的T_SEND_TO与TCP连接类似需要先建立一个连接描述博图里“连接”类型选择UDP组播的时候要确保连接编号和指令ID一致否则指令一直报busy但不发送。这曾经让我在调试现场耗费了一个多小时排除了MAC地址、IP地址、防火墙所有因素后才发现是连接ID没对上。4.3 组播通讯的不足与替代方案UDP组播当然也有缺点最明显的是不可靠——交换机拥塞时可能丢包终端掉电重连后还需要重新加入组。对于楼层显示这种非核心控制数据来说丢一两个包影响不大下一帧200ms后就到了可接受。但如果要用做电梯运行状态的安全监控我建议还是走Profinet或者TCP会话不要依赖UDP组播。另外要注意交换机的IGMP Snooping功能。默认交换机如果没有开启组播优化组播帧会泛洪到所有端口这在只有几台终端的局域网没问题但如果在大型项目、多台电梯共享网络的场景泛洪会浪费带宽。建议购买支持IGMP Snooping的工业交换机把组播流量限定在需要的端口范围内。5. 调试实录我踩过的坑和排查方法5.1 安全回路断开引发按钮失灵电梯第一次上电调试的时候我遇到一个很诡异的现象按下任何呼梯按钮都没有反应指示灯不亮PLC监控里M点也不置位。查了半天I/O接线按钮信号链路完全正常。后来用变量监控表盯着“SafeOK”这个位看发现它在FALSE状态。为什么安全回路断开会引起按钮失灵因为在调用FC100信号采集时我做的信号滤波只有在SafeOK为TRUE时才把按钮信号送入呼梯登记逻辑。这是出于安全考虑防止在故障状态下电梯带着门开着乱跑但这种“一票否决”导致的副作用就是我在最开始调试时不熟悉业务逻辑不知道检查全局安全位。解决办法是在故障排查时增加一个“检修模式”开关检修模式下SafeOK由检修人员手动确认呼梯信号可以强制登记程序开发调试时这个开关省了很多事。5.2 平层停不准原来是减速点太统一第一次测平层精度时站在轿厢里能明显感觉到停车瞬间的冲击感而且六楼经常出现停过头20mm的情况虽然门还能正常打开但离准确平层差一点。最初我判断是变频器减速时间太短调了变频器参数确实好转但一到六楼走半程、距离不够的时候问题又回来了。后来我才意识到问题出在所有楼层的减速信号都用同一个“减速感应开关”但这个开关安装位置对每一层的有效减速距离是不同的。楼层间距不一样有的楼层路过时速度还没降到爬行段就已经到了平层位置。优化办法是把减速信号做得更精细对底层和顶层增加独立的减速开关同时在程序里引入“预减速”功能如果当前层与目标层的距离小于两个楼层间距提前切低速。这个逻辑改完以后全楼层平层精度都稳定在了±5mm以内坐电梯的感觉舒服很多。5.3 六楼上行电梯被二楼下行召唤“截停”的bug方向决策里最经典的一个逻辑漏洞我在联调中真实遇到了电梯在六楼载人下行二楼有人按下行召唤电梯下行经过二楼时正确停车接人这是对的但有一天测试员按了六楼下行召唤应该是按错结果电梯下行到五楼时突然减速停车程序认为是“二楼下行召唤已响应”但实际停在了五楼。排查方向决策SCL代码才发现我在判断“当前层是否为下行召唤目标层”时用了“只要该层存在下行呼梯信号就停车”没有校验该下行呼梯是否已经被响应过。而遇到五楼有个曾经响应过但M点位还没清掉的残留信号时电梯就被这个“幽灵呼梯”干扰停车了。解决办法是给每个召唤信号增加响应完成标志停车开门后先置完成再用完成状态去抑制重复响应只有信号位和完成位都符合时才触发停车。这个改动之后同类干扰再没出现过。5.4 通讯偶发掉线组播与防火墙的爱恨纠葛UDP组播跑了一个星期期间有两次监控画面卡住不动重启上位机程序又恢复。排查时先怀疑交换机换了个带IGMP Snooping的交换机还是有偶发情况后来把Wireshark抓包打开发现PLC发出的组播帧一直在问题出在上位机的Socket没有正确调用recvfrom原来上位机程序里有个逻辑如果接收超时就关闭Socket结果在系统休眠唤醒后Socket被系统回收导致一直收不到数据。这个问题的解决方法是上位机接收线程增加保活机制每5秒检测一次Socket状态如果异常就重新绑定组播组。同时建议终端收到连续30帧无头帧时自动重启接收线程。这类问题对PLC程序员来说通常不是PLC问题但联调时往往彼此甩锅能快速判断“PLC发送是否正常”才是解决效率的关键——我在PLC里做了一个计数器DB每发一帧加一上位机通过心跳字段核对数据连续性判断掉包是网络还是接收端问题。6. 一些实在的开发经验电梯程序写到现在回头看看最值钱的不是那一堆能跑的代码而是调试中积攒的工程直觉。有几个经验我想单独拿出来分享给准备做电梯项目的朋友第一程序结构千万别省。电梯逻辑的复杂度远超普通机床控制一旦写出通篇梯形图的长篇大论后期维护的人会骂你你自己改起来也会疯。用FC划分功能模块、用SCL写算法、用背景数据块存状态这个模式在博图V15.1下用起来非常顺手。第二安全互锁要写在最底层不要为了调试方便临时短路它。电梯是载人的设备任何突破安全互锁的“捷径”都可能酿成事故我见过有同事调试时为了省事用编程线强制输出点结果差点把门开着电梯开走的操作做出来。这是职业底线没有商量余地。第三通讯协议设计越简单越好。UDP组播的协议栈不难难的是让多个终端在不同语言下解析一致。定一个固定长度的结构体所有字段字节对齐接收方解析就非常省事。千万不要用“浮点数直接传”不同机器的大小端差异会让你怀疑人生。第四电梯运行体验的关键在加减速曲线。PLC程序再完美如果变频器的加减速曲线设成直线乘客照样会晕。这个问题预留的调试时间要足够实测下来S型加减速曲线在低速电梯里效果最好但S型曲线的拐点参数需要和三段速逻辑配合微调。电梯控制这个项目做好一遍之后你会发现它几乎是PLC入门到进阶最好的练手项目——逻辑复杂度适中、IO点数恰到好处、通讯和运动控制都有涉及尤其用西门子1200配上博图V15.1整个开发环境对中小型项目非常友好。希望这篇记录里的思路和踩坑经验能让你少走几段弯路。
返回列表