西门子S7-1200 PLC六层电梯控制程序开发实战:从IO规划到调试 一台六层电梯听起来不算复杂但真正从零开始写PLC程序的时候才能体会到什么叫“麻雀虽小五脏俱全”。楼层呼叫的逻辑、平层停车的精度、开关门的时序、安全回路的冗余——每一个环节都直接关系到设备能不能稳定运行、乘客敢不敢坐。这篇文章记录了我用西门子S7-1200和博图V15.1开发单部六层电梯程序的完整过程包括需求拆解、控制算法设计、代码实现和现场调试踩过的坑。全文以实战为主不会只讲空泛的理论而是尽量把我当时的设计思路、程序结构、关键代码片段和调试细节都摊开来讲。无论是刚接触PLC的小白还是准备做类似改造项目的工程师都可以参考这套逻辑结合自己的实际工况进行修改。1. 需求拆解与IO点规划动工之前先算清账很多第一次做电梯项目的朋友容易上来就写程序结果写到一半发现输入输出点不够用或者某个信号不知道接到哪里再回头改硬件布局非常被动。我的习惯是先把需求彻底拆干净算清楚IO点再动博图。1.1 六层电梯到底有多少个信号单部六层电梯先盘一下它有哪些功能需求轿厢内操作每层一个内选按钮共6个带自复位和指示灯楼层外呼每层有上/下呼叫按钮。一层只有上行六层只有下行中间层上下行都有一共10个按钮每个按钮也带指示灯楼层检测每层一个平层感应开关接近开关或永磁感应器共6个轿厢位置显示7段码或点阵显示这里走IO输出不算模拟量开关门控制开门继电器、关门继电器、门锁反馈、光幕/安全触板信号安全类信号急停、超载、上下极限限位、检修开关、变频器故障反馈速度控制给变频器的启动、方向指令和速度给定信号。统计下来需要开关量输入大概在30点上下开关量输出也在25点以上含指示灯和显示再加上模拟量速度给定1路。这个量级用S7-1200自带的集成IO往往不够需要扩展模块。1.2 硬件选型与地址分配我这次用的是CPU 1214C DC/DC/DC集成14DI/10DO外扩一块SM 122316DI/16DO再加上一块SM 1232模拟量输出模块或者直接用S7-1200本体上的模拟量输出1214C本体没有模拟量输出所以必须扩展。实际用下来这样刚好把IO点全部覆盖住还留了两个备用点。分配地址的时候一定要按功能分区不能想到哪接到哪。我的划分规则是这样的功能区域输入地址范围输出地址范围楼层平层与极限保护I0.0-I0.7 优先给平层感应器Q0.0-Q0.3 楼层显示低4位轿厢内选与指示灯I1.0-I1.5Q1.0-Q1.5外呼按钮与指示灯I2.0-I2.7一组Q2.0-Q2.7门系统与安全I3.0-I3.5Q3.0-Q3.5变频器控制I4.0-I4.3Q4.0-Q4.3具体的地址只要自己定一套规则并且写在变量表里注释清楚就行但有个建议平层感应器要优先占用连续地址因为后面做楼层位置判断的时候用字读取或者循环移位会非常方便。我一开始没注意这个结果平层信号分散在I0.0、I0.4、I1.3这些乱七八糟的位置写楼层比较逻辑的时候简直灾难后来重新接线才理顺。2. 方向判定与楼层停靠电梯的大脑怎么设计电梯程序里最容易写乱的就是方向判定。因为电梯不像普通设备那样只靠“启动/停止”就能工作它需要自己在多个楼层呼叫请求中决定先去哪、途径哪些楼层不停地。2.1 三种常见调度策略的取舍我梳理过几种常见策略给大家做个参考最远端呼叫优先电梯响应离当前楼层最远的呼叫跨楼层运行效率高但顺路捎客的效果太差高峰期体验不好先应答同方向呼叫再反向响应也就是“顺向截梯”。电梯上行时只响应上行方向的呼叫下行时只响应下行方向的呼叫直到当前方向的最远端无请求后才换向时间优先/楼层距离加权这是群控才需要玩的东西单梯没必要把算法搞那么复杂。对于单部六层电梯我最终选了第二种顺向截梯。它是民用电梯最主流的逻辑乘客体验好代码实现也不复杂。逻辑上可以概括成两条规则电梯在某方向运行时经过的楼层如果有该方向的呼叫就停靠到达当前方向最远的呼叫楼层后若还存在反方向呼叫则换向继续服务。2.2 用位逻辑实现呼叫登记与顺向截梯在PLC里我专门用了一个DB块存所有呼叫信号每个楼层每方向的呼叫用一个布尔变量保存同时定义两个关键的字变量UpCallWord位0~位5对应1~6层的上行呼叫DownCallWord位0~位5对应1~6层的下行呼叫。为什么用字而不是用一堆Bool因为我可以直接对字做循环右移/左移非常轻松地判断“当前方向前方是否还有呼叫”。这比逐个比较Bool变量省太多事了。上行方向的判断逻辑可以写成// 上行时提取当前层以上所有上行呼叫 FOR i : currentFloor TO 6 DO IF upCall[i] THEN hasUpCallAhead : TRUE; END_IF; END_FOR;不过直接用FOR循环在OB1里扫会有点浪费时间我实际用的是移位方式把UpCallWord右移当前层位数剩下的位里只要非零就说明该方向前方有呼叫。程序更简洁扫描周期也更短。2.3 方向切换与最远端目标的计算换向的判定条件是当前方向的所有呼叫已经全部处理完且另一个方向还有呼叫。具体到程序里我需要实时维护两个变量UpCallsPending上行方向尚未响应的呼叫总数DownCallsPending下行方向尚未响应的呼叫总数。每次电梯平层开门、关门之后就去刷新这两个计数。当电梯正在上行且UpCallsPending变成0同时DownCallsPending大于0就置位换向请求。在换向前要让电梯先停在某一个楼层完成一次完整的开关门再进行方向切换。这里有个容易踩坑的点如果电梯上行过程中有人在一楼按了上行呼叫这时候UpCallsPending会立刻大于0电梯可能会在下完客后直接往下跑响应这单呼叫——但正确的逻辑应该是电梯继续上行把当前方向所有楼层服务完等再换向的时候去响应。所以在换向判定时我额外加了一个“同向服务未结束标志”只有当前方向所有同向呼叫清零后才允许把另一个方向的新呼叫计入换向判断。这个细节不处理好的话电梯很容易在中途频繁变向乘客会觉得电梯“疯了”。3. 平层、开关门与速度曲线从逻辑层落到执行层方向算法只是大脑真正让乘客有感知的是平层精度、开关门节奏和加减速的平滑度。这部分的调试花了我超过一半的时间。3.1 平层信号怎么接才能停得准六层电梯我用的方案是每层装一个独立的平层感应器轿厢侧安装遮磁板。这种方式结构简单、改造成本低很常见。但平层精度完全取决于感应器与遮磁板的相对位置调试。安装要点遮磁板的长度要大于感应器感应面10毫米以上确保停车过程中信号有足够的保持区间感应器输出要接成NPN常开遮磁板进入感应区域时输出1调试时用变频器检修速度低速运行反复调整遮磁板位置以电梯停稳后轿厢地坎与层站地坎误差不超过5毫米为准。如果现场要求更高精度可以考虑旋转编码器加变频器闭环但逻辑程序这块反而比感应器方案好写因为不需要处理“信号保持区间”的问题。我这次用的还是感应器方案平层过程分成两段距离目标楼层还有一个平层感应器间隔时通过当前楼层和目标楼层差判断下发减速信号进入平层感应区域连续检测到感应信号后输出停车指令同时变频器零速给定。3.2 开门关门时序与防夹逻辑开关门看起来简单其实时序对乘客体验影响很大。我定的顺序是电梯平层停车且抱闸动作后延迟300ms确认无溜车输出开门继电器开门到位信号返回后保持开门状态开门保持时间根据是否有内呼或外呼动态调整有呼叫时3秒无呼叫时5秒开门时间到且光幕、安全触板无遮挡输出关门继电器门完全关好后门锁信号闭合电梯才能重新启动。防夹逻辑必须独立于主流程一旦光幕触发立即给出“重新开门”命令同时复位关门继电器。这里要加一个软件防抖光幕信号持续时间超过100ms才认为是真遮挡否则一些飞虫、灰尘干扰就会导致电梯反复开关门。3.3 速度给定与换速点处理速度给定我用的是模拟量输出0~10V对应变频器的0~50Hz。但直接给阶跃给定会让人站着都晃一下所以程序里做了斜坡给定。斜坡的本质就是每次扫描周期把实际给定值朝目标值递增或递减一步。步长要现场调起步和到达前的步长要小一些中间运行可以适当加大步长。实际给定 : 实际给定 速度步长 * 方向;换速点的计算是关键。六层电梯楼层间距可能不一样不能简单地按“距离目标楼层的楼层数”来换速。我是在每次运行前根据当前楼层和目标楼层计算出减速距离当实际运行距离接近减速距离时把给定速度降到低速爬行值。这个距离其实是估算的因为我没有用编码器采用的是“平层感应器计数时间估算”的混合方式。更简单可靠的方案是直接让变频器自己处理S曲线加减速PLC只给启停和方向信号但前提是变频器的多段速或内部斜坡参数设置合理。4. 安全回路设计PLC可以出故障人不能出事电梯是载人设备安全逻辑设计必须比普通设备严格一个量级。这也是我这次开发中强调最多、查资料最多的部分。4.1 哪些保护必须做在硬件上不能只靠程序有个原则必须刻在脑子里涉及人身安全的保护回路必须独立于PLC硬件。PLC死机、程序跑飞、输出模块烧毁的时候硬件安全回路必须能把电梯停下来。我当时的硬件安全回路接法是急停按钮串联在安全继电器回路上上下极限限位开关串联在安全继电器回路上门锁信号直接串在运行接触器线圈回路上门没关好即使PLC输出启动信号接触器也合不上超载信号通过独立继电器切断启动允许回路。PLC程序里的安全逻辑只是给控制系统层面再加一道软件保险不能指望全靠它。这一点我在项目的技术方案评审时特别写过说明现场电工师傅也都认可这个观点。4.2 程序里的互锁与联锁逻辑程序内我做了这么几个核心联锁方向互锁上行接触器和下行接触器不能同时吸合。即便硬件回路已经做了机械互锁程序里依然要双保险。输出的写法是IF upCommand AND NOT downCommand THEN QUp : TRUE; ELSE QUp : FALSE; END_IF; IF downCommand AND NOT upCommand THEN QDown : TRUE; ELSE QDown : FALSE; END_IF;开门禁止运行只要门未关好或者门锁信号断开运行方向输出必须清零检修模式优先检修开关闭合时自动运行逻辑全部旁路只能点动检修速度运行终端限位联锁上楼时如果上极限被触发无论任何条件立即切断上行输出超载联锁超载信号有效时电梯不响应任何运行指令但保持开门并给出门不关的提示。4.3 检修模式与自动模式的切换检修模式是维护电梯时的必要功能极容易被忽略。我专门做了一个“运行模式”变量0代表自动1代表检修。检修模式下内呼、外呼全部失效上下行用长动按钮点动控制按住才动松开即停速度强制为检修速度不允许高速运行平层信号只做参考不做精确停车判断开关门由维护人员手动控制。在博图里我用的方式是在主控制FC前面加一个模式选择分支检修模式直接调用单独的FC_ServiceMode自动模式才走正常流程。这样两个逻辑完全隔离不怕误触发。5. 博图V15.1项目结构与核心代码片段前面讲了不少设计思路这一节把博图项目的实际结构和关键代码贴出来给准备上手的同行一个参考框架。5.1 程序块划分与数据管理我把程序拆成下面这些块程序块用途OB1主循环按顺序调用各功能FCFC_FloorDetect楼层位置检测与更新FC_CallRegister呼叫登记与指示灯刷新FC_Direction方向判定与目标楼层计算FC_SpeedCtrl速度给定与换速处理FC_DoorCtrl开关门时序控制FC_Safety安全联锁与故障停机FC_ServiceMode检修模式独立逻辑DB_Common电梯运行状态共享数据块DB_Calls呼叫登记数据块这种按功能划分的方式后期调试时找问题非常方便。比如现场反馈门关不上直接监控FC_DoorCtrl里的变量就行不用在一大坨程序里翻来翻去。5.2 核心SCL代码呼叫登记与方向判定呼叫登记这段我用的是梯形图SCL混编梯形图处理按钮信号SCL处理逻辑运算。下方是简化版SCL// 内呼登记 IF 1楼内呼按钮 THEN DB_Calls.InnerCall[1] : TRUE; END_IF; // ... 此处省略2~6楼 // 外呼登记 IF 1楼上呼按钮 THEN DB_Calls.UpCall[1] : TRUE; END_IF; // ... 此处省略其他楼层外呼 // 顺向截梯判定电梯上行时检查当前层以上是否有同向上呼或内呼 临时字变量 : 0; FOR i : 当前楼层 TO 6 DO IF DB_Calls.UpCall[i] OR DB_Calls.InnerCall[i] THEN 临时字变量 : 1; END_IF; END_FOR; IF 临时字变量 1 THEN 保持上行方向 : TRUE; END_IF;这段逻辑在六层规模下性能完全够用。层数再多一点比如十层以上建议把FOR循环改成移位运算或者Table寻址保证扫描周期稳定。5.3 平层停车与开关门控制代码平层停车判断这段我额外加了信号保持功能防止感应器在临界位置时信号抖动导致重复判断。用延时接通定时器解决延时时间设为50ms左右// 平层信号防抖 平层防抖输出 : 平层感应器信号; TON_Instance(IN : 平层感应器信号, PT : T#50MS); IF 平层防抖输出 AND 目标楼层 当前位置 THEN 平层到位 : TRUE; END_IF;开关门控制我采用的是状态机写法四个状态空闲、开门中、开门保持、关门中。状态之间的迁移条件前面已经讲过这里提一句状态机写法虽然代码长一点但可读性和稳定性都远超用定时器堆出来的时序逻辑。6. 模拟与现场调试记录坑都在这一步暴露程序写完只是第一步调试才是最考验人的。我用博图的PLCSIM做了很多轮模拟验证但真到了现场还是被现实狠狠教育了几次。6.1 PLCSIM仿真能帮你验证什么不能验证什么PLCSIM能帮你验证逻辑层面的东西比如顺向截梯算法正不正确、换向条件合不合理、呼叫登记有没有遗漏这些用仿真完全可以跑明白。方法是把输入变量虚拟成按钮用“手动修改输入”功能模拟呼叫信号看着监控表里的状态变化来判断逻辑是否正确。但仿真验证不了下面这些现场问题平层感应器实际安装的物理偏移门锁信号接触不良带来的抖动干扰变频器运行时的电磁干扰对模拟量信号的影响机械惯性引起的溜车和过冲。所以别以为仿真跑通了现场就能一次过这两者之间有很长的距离。6.2 现场调试遇到的三类疑难杂症第一类是门锁信号抖动。电梯关门瞬间门锁触点经常出现短暂通断导致PLC误判门开门运行指令被切断电梯“一冲一顿”。我处理的办法是读门锁信号时做了50ms的接通延时只有门锁稳定闭合50ms以上才认为真正关门到位。第二类是模拟量速度给定的干扰。刚开始用屏蔽电缆直接走线槽变频器一启动速度给定就跳动电梯在低速爬行段一顿一顿的。后来把模拟量线单独走金属管且在PLC输出端并联了一个1000pF的滤波电容干扰才基本消除。这个问题在变频器功率较大时尤其明显建议大家从一开始就重视弱电布线的屏蔽和分层。第三类是平层停车冲过头。电梯从高速直接给停车信号因为抱闸机构和负载惯性每次停的位置忽高忽低误差能到3厘米。后来我改成“先减速爬行再停车”的两段式逻辑并且延时200ms给抱闸信号让电梯在零速状态稳定一下再抱闸误差降到5毫米以内。6.3 版本与固件兼容的注意点博图V15.1可以连接S7-1200的绝大多数固件版本但我遇到过一台CPU固件是V4.5的设备在V15.1里下载程序时提示“设备不支持该功能”后来是先把博图升级到V16或V17才解决的。另外1200的PLC程序下载前一定要检查“设备组态”中的硬件型号和固件版本与实际设备一致否则下载时会报“硬件配置不匹配”。具体操作是在博图左侧项目树里找到PLC右键“属性”查看固件版本然后修改设备组态使其匹配。关于版本问题我的经验是项目一开始就确认好现场设备的固件版本并且用对应版本的博图建项目。如果像我们这次是给旧设备改造更要提前确认不然到现场才发现版本不对整个进度都会受影响。还有一个小细节PLC的IP地址和电脑必须在同一个网段下载时如果找不到设备先ping一下PLC地址不通的话检查网线和防火墙。这个坑很多人遇到过其实基本不是PLC坏了就是电脑防火墙拦截了博图的通信端口。最后的个人体会这套电梯程序改到今天前后跑了三个多月最深的感触是电梯项目真正难的从来不是某个复杂的算法而是把所有常规逻辑做得绝对可靠。一次呼叫漏登记、一次换向判断失误、一次门锁抖动没滤掉看着都是小问题但放到载人设备上就是安全隐患。我自己的习惯是每次现场处理完一类问题就在程序注释里写清楚问题出现的前提和解决办法方便下次直接查。程序不是一次写出来的是靠一遍遍调试“磨”出来的。这也是我认为PLC项目最有价值的部分——你踩过的每一个坑都是别人在文档里查不到的实战经验。希望这篇记录能帮到准备做电梯或类似定位控制项目的朋友至少少走几步我们走过的弯路。