
简介四层电梯PLC仿真程序是一套基于西门子博途V15.1环境的四层电梯控制工程面向自动化专业学生、PLC入门者及电梯控制工程师适用于高校实验教学、岗前培训和个人自学。程序覆盖楼层呼叫响应、内外呼梯、状态显示、安全保护、调度算法和故障模拟等核心逻辑可在无实际硬件的情况下进行仿真验证与调试。资源包共95个文件、大小5.93MB包含qml界面文件、xml配置信息、png说明图片以及cfs、del等工程辅助文件内部按系统程序、用户文件、日志与附加文件分区便于分块查阅。目前已有888人学习浏览借助该仿真程序可快速掌握博途V15.1从建项、组态到PLC在线仿真的完整流程深入理解电梯控制原理通过工程内的交叉引用和用户文件还能梳理变量与程序块之间的对应关系形成模块化编程思路为后续扩展调度策略、安全机制或完成课程设计、毕业设计提供基础。1. 四层电梯PLC仿真到底在仿什么四层电梯PLC仿真程序不是让你用PLC去控制一部真电梯而是把电梯的“呼梯-选层-运行-开关门-停靠”这一套逻辑抽象成数字量输入输出在PC上完整跑一遍。它解决的核心问题是在没有机械部件、没有井道、没有门机的情况下怎么验证控制程序在边界条件下不出错。比如两层同时呼梯方向相反、电梯在运行中被重新截停、开门延时与超时报警这些真实场景只有靠仿真才能低成本复现。这个程序适合两类人一类是刚接触PLC编程的工程师想用一个小项目把梯形图、定时器、边沿指令和状态机串起来另一类是做毕业设计或课程设计的学生需要一套能演示、能答辩、能改参数的完整案例。四层是刻意选的——它比两层多出换向判断和同方向顺路截停又不像十几层那样需要复杂的调度表。下面从模型设计开始逐步给出能直接落地到仿真器的方案。2. 把电梯控制拆成状态机与信号表2.1 四层电梯的最小I/O清单做仿真之前先把物理信号和程序里的变量分开。四层电梯最简配置需要6个楼层传感器一层到四层的平层信号、5个外呼按钮一层上行、二层上行/下行、三层上行/下行、四层下行、4个轿内选层按钮再加门开到位、门关到位、门锁信号这些安全条件。仿真器里没有物理接线我用内部变量代替外部I这样可以在PLCSIM或GX Works里直接强制值。下面是仿真程序里用的I/O映射表也是后续写代码时的变量命名依据变量名数据类型含义仿真中如何赋值FloorSensor[1..4]Bool各楼层平层传感器手动置位或由运动模型置位UpCall[1..3]Bool一楼到三楼的上行外呼触屏按钮或变量表强制DownCall[2..4]Bool二楼到四楼的下行外呼触屏按钮或变量表强制CabinCall[1..4]Bool轿内选层按钮触屏按钮或变量表强制DoorOpenCmdBool开门命令程序输出可监控DoorClosedBool门关闭到位信号手动模拟延时后置位MotorUpBool电机上行输出程序输出MotorDownBool电机下行输出程序输出提醒一下真实电梯的门锁、安全钳信号在仿真里必须用简化模型否则程序永远跑不起来。我一般把DoorClosed和门锁捆绑成一个变量仿真时用定时器模拟门开关的耗时。2.2 用“楼层方向”做状态机而不是把每个楼层写成独立逻辑很多初学者会把四层电梯写成四个独立的“到层就停”分支比如“如果在一层且有人叫去四层就一路上行”。这个写法在两层时成立四层就会出问题当电梯从一层上行去三层途中二层有人按上行那么二层应该顺路停但如果二层是按下行而电梯的目的地是四层那它应该先到四层再返回来接。这些逻辑用独立分支写条件会爆炸。正确做法是把电梯看作一个“状态对象”它有当前楼层、运行方向、目标楼层三个核心状态。程序每个扫描周期要做的事只有三件合并新的呼叫、检查当前方向是否还有更近目标、没有目标时换向。这样不管楼层加到几层核心逻辑都不会膨胀。在仿真里这个状态机用SCL写比梯形图更直观因为SCL支持数组和FOR循环楼层循环判断非常自然。2.3 用SCL描述运行模式与换向条件以西门子S7-1200为例我在OB1里调用一个FBFB内部定义静态变量表示状态机。核心代码如下// FB4_Elevator 四层电梯状态机 VAR_INPUT FloorSensor : ARRAY[1..4] OF Bool; UpCall : ARRAY[1..3] OF Bool; DownCall : ARRAY[2..4] OF Bool; CabinCall : ARRAY[1..4] OF Bool; DoorClosed : Bool; END_VAR VAR_OUTPUT MotorUp : Bool; MotorDown : Bool; DoorOpenCmd : Bool; END_VAR VAR CurrentFloor : INT : 1; RunDirection : INT : 0; // 1上行, -1下行, 0停止 DestFloor : INT : 0; // 当前目标楼层 IsRunning : Bool; END_VAR这段代码声明了状态机需要的全部变量。CurrentFloor是当前停靠楼层RunDirection用1和-1表示方向0表示待机。注意这里没有“运行时间”“速度”这些物理量仿真阶段只关心逻辑位置不关心速度曲线。换向条件放在一个单独的FC里逻辑是先确认当前方向再扫描同方向所有楼层是否有呼叫如果同方向没有就反向扫描所有楼层。这个“扫描”用FOR循环完成回头给梯形图写冗余判断时可以少写一半触点。3. 在TIA Portal里写四层电梯PLC控制程序3.1 组织块与函数块分配在TIA Portal里我建议这样分配资源OB1负责调用主控FBOB10或OB20里放仿真用的脉冲发生器用于模拟电梯移动时的楼层变化FB块里只写控制逻辑不写运动模拟。这样以后接真实电机时只要删除OB10把FloorSensor接到物理输入点就行。仿真用的“运动模型”是另一个FB它根据MotorUp/MotorDown输出每隔一段时间把当前楼层往下或往上挪一下。这相当于把真实井道的减速、平层过程简化为“逻辑跳变”。我在PLC里用定时器实现一个1秒的脉冲每1秒检查一次电机方向并修改一个内部的Position变量当Position变化时把对应的FloorSensor置位。3.2 呼叫登记与清除逻辑呼叫登记不能用简单的“按一下就置位”因为仿真里按钮是电平信号如果一直按住程序会重复登记。必须在按下沿上升沿时登记呼叫。S7-1200里有R_TRIG指令SCL里可以用一次辅助变量存储上一次的状态。// 呼叫登记只在信号上升沿写入 CALL_MEM FOR i : 1 TO 3 DO IF UpCall[i] AND NOT UpCall_Old[i] THEN UpCallMem[i] : TRUE; // 上行呼叫记忆 END_IF; UpCall_Old[i] : UpCall[i]; END_FOR; FOR i : 1 TO 4 DO IF CabinCall[i] AND NOT Cabin_Old[i] THEN CabinMem[i] : TRUE; END_IF; Cabin_Old[i] : CabinCall[i]; END_FOR;代码里的UpCallMem和CabinMem是FB的静态数组变量记录已经登记但还没响应的呼叫。为什么要做边沿检测因为TIA Portal的仿真器里外部输入如果是按钮触摸屏变量它可能会保持True一段时间如果不加边沿一个呼叫会被重复登记多次到站后永远清不掉电梯就会在同一层反复开关门。清除逻辑放在停靠动作里当电梯到达目标楼层并开门后要同时清掉这一层的轿内呼叫、上行呼叫和下行呼叫。注意四层电梯有个细节二层和三层是双向外呼到站时只清与当前方向一致的呼叫。比如电梯上行到三层停靠三层如果同时有上行和下行呼叫那么上行呼叫要清下行呼叫应该保留等电梯换向下行时再响应。3.3 方向生成与到站停靠逻辑方向生成是这个程序里最容易被抄错的部分。我用一个变量NextTarget表示扫描后得到的下一目标楼层扫描规则如下// 判断是否要停当前方向上行时目标楼层必须大于当前楼层 IF RunDirection 1 THEN NextTarget : 0; FOR i : CurrentFloor 1 TO 4 DO IF CabinMem[i] OR UpCallMem[i] OR DownCallMem[i] THEN NextTarget : i; EXIT; // 找到最近目标 END_IF; END_FOR; // 如果上行找不到目标换向下行扫描 IF NextTarget 0 THEN FOR i : 4 DOWNTO 1 DO IF CabinMem[i] OR UpCallMem[i] OR DownCallMem[i] THEN NextTarget : i; EXIT; END_IF; END_FOR; IF NextTarget 0 THEN RunDirection : -1; END_IF; END_IF; END_IF;这里有一个电梯控制的经典规则同方向优先最近目标优先。上行时只扫CurrentFloor1到四层不回头扫楼下如果楼上没有呼叫才换向。这段代码在仿真里特别重要因为仿真器里所有呼叫都是人工随机给的如果不做最近优先电梯会来回跑冤枉路看起来像“晕头转向”。到站停靠的条件是“当前楼层等于NextTarget”但直接比较浮点数或整数会有一个坑仿真里位置脉冲和楼层传感器可能不同步。我一般用一个辅助变量LastFloor记录上一周期的位置当FloorSensor当前位置不同于LastFloor时说明电梯进入了新楼层。只有新楼层等于NextTarget且方向正确时才置位开门。3.4 电梯仿真用的定时器与运动模型为了让仿真可视化需要在程序里加一个“虚拟电机模型”。真实电梯是变频器控制仿真里没有机械惯性只能定时跳变。我在FB里用TON和TOF组合模拟运行// 运动模型每运行1秒位置变化0.5层到达整层时更新传感器 IF MotorUp THEN PulseTon(IN : NOT PulseTon.Q, PT : T#1S); IF PulseTon.Q THEN VirtualPos : VirtualPos 0.5; // 四舍五入找最近楼层 CurrentFloor : ROUND(VirtualPos); FloorSensor[CurrentFloor] : TRUE; FloorSensor[LastFloor] : FALSE; END_IF; END_IF;为什么用0.5而不是1因为四层电梯层间距离如果取1那么从一层到二层只需要一秒看起来太突兀而且无法模拟在中间层的状态。取0.5步进每2秒走完一层这样点动测试时能清楚看到每一层的中间状态。真实程序中应该用PID或斜坡信号控制伺服电机但仿真阶段这个简化足够。定时器要注意PLC扫描周期通常在10ms以内TON的PT精度足够但如果你把PT写成100ms位置跳变会非常快摄像头录屏都看不清。我建议每层运行时间设为2秒这样总运行周期大约是8到10秒调试时眼睛能跟上。这里没有标准答案以自己观察方便为准。4. 跑仿真PLCSIM、GX Works与倍福的常见做法4.1 S7-1200用PLCSIM跑程序西门子仿真要用两个软件TIA Portal做的项目和PLCSIM虚拟PLC。网上很多人卡在“S7-1200不支持仿真”的旧观点上其实TIA Portal V13以后S7-1200/1500都可以在PLCSIM里跑。做法是先把项目编译下载到“仿真PLC”选择框弹出的虚拟地址里然后保持在线打开“仿真表”手动强制输入变量。常见的一个坑是PLCSIM里IO变量如果直接用I0.0这种地址仿真表可以强制但程序里要用%I强制输入不能靠触摸屏脚本赋值。我一般把仿真输入全部映射到M区和DB块这样既能用仿真表也能用HMI的IO域。具体做法是写一个OB30中断块每100ms把DB里的HMI按钮变量复制到I地址对应的内部变量上。// OB30循环中断用于HMI与仿真信号同步 #hmi_open_btn : #sim_door_open_cmd; FOR i : 1 TO 4 DO #FloorSensor_Array[i] : #HMI_FloorSensor[i]; END_FOR;这段代码放在循环中断里目的是让HMI上的按钮状态每100毫秒刷一次到控制逻辑。注意赋值方向HMI按钮的“按下瞬间”要转成边沿检测不能直接等于否则前面说的重复登记问题会再次出现。4.2 三菱GX Works仿真器与FXTRN的差别如果你选择三菱FX系列GX Works2自带仿真器但注意它的仿真模式和FXTRN不同。GX Works的仿真是在PC上解析梯形图逻辑没有真实扫描周期逻辑块执行速度极快如果你的程序里有脉冲定时器仿真时间与真实时间可能不同步。FXTRN是带3D动画的教学软件画面里有一座电梯但它的PLC逻辑是固定封装好的不能导入自己写的程序。我见过很多学生在GX Works里写好了梯形图然后在FXTRN里找不到导入入口因为FXTRN是独立学习工具不是编译执行环境。正确做法是用GX Works2的“PLC仿真”模式跑自己的程序观察软元件监控表里的M0、M100这些变量同时用内置的时序图功能查看输出波形。三菱仿真器的定时器T0常数为K100表示100毫秒这个在仿真器里是真实时间可以用来计时开门时长。4.3 倍福TwinCAT仿真怎么跑起来倍福的TwinCAT 3里仿真本质是激活配置时选择“Local本地运行”不需要额外硬件。和PLC的区别是倍福用的是Windows实时扩展默认每个循环周期跑定时任务程序是ST语言。如果你把四层电梯的程序写到PRG里注意类型是“Program”而不是Function Block。很多从西门子转来的工程师在倍福里找错对象其实倍福的程序可以嵌套调用FB。TwinCAT里跑电梯仿真还需要一个可视化界面。常见做法是配一个HMI拖控件或者在TwincAT中直接建立“PLC Visualization”用按钮连接变量。这里有个关键倍福仿真器默认的任务周期是10ms如果定时器要求1秒要自己写累加变量因为TON在倍福里虽然存在但使用时要绑定TimeOut变量不能像三菱那样直接给常数。4.4 用变量表强制值模拟传感器不管用哪个品牌仿真核心调试手段都是“强制输入”。在PLCSIM里你可以在仿真表的“强制”列给变量输入TRUE/FALSE。模拟电梯运行的步骤一般是先强制一层平层传感器为TRUE其他为FALSE然后强制轿内四层按钮为TRUE看输出MotorUp是否为TRUE再把一层平层改成FALSE二层平层改成TRUE依次往上移动。这个过程中最需要注意的是强制的值不会自动消失。如果你强制了一层平层为TRUE它就一直为TRUE当你把四层平层也置为TRUE时两个信号同时为TRUE电梯会认为自己在两个楼层。所以每次移动楼层前要把前一层的传感器强制回FALSE顺序是先置新楼层TRUE再置旧楼层FALSE或者用“软传感器”由程序内部变量更新而不是手动强制。5. 四层电梯仿真调试技巧先防抖再对坐标5.1 数字量滤波与消抖仿真程序里最容易被忽略的是输入抖动。触摸屏按钮和鼠标点击产生的信号在PLC里可能由于扫描周期原因产生多次边沿导致呼叫登记重复或丢失。虽然上一章用边沿检测解决了重复问题但边沿检测无法解决“接触抖动”——即信号在TRUE/FALSE之间快速跳变。我自己的处理方式是在FB输入前加一个10ms的延时确认当输入信号变化后先启动TON计时只有计时结束且信号状态保持不变才更新内部变量。这个滤波函数在S7-1200里可以直接用“FilterTime”参数或自己写// 数字量滤波输入信号持续稳定超过5ms才认为有效 TON_Filter(IN : raw_signal, PT : T#5MS); IF TON_Filter.Q THEN filtered : raw_signal; END_IF;注意TON的Q是延时接通如果输入在5毫秒内又变回FALSEQ永远不会为TRUE滤波自然生效。仿真时这个延时可能看不到效果但接真实按钮时作用很大。如果仿真器是倍福TwinCAT可以在输入变量上配置“Filter”属性从0到9级我一般用2级就够。5.2 楼层定位的误差容忍运动模型里用VirtualPos加上0.5步进最大误差是0.5层。但在调试时你会发现电梯在停靠后当前楼层的脉冲可能停在1.5层ROUND后变成2层和实际方向不一致。这是因为程序判断到达目标楼层的条件是“CurrentFloor NextTarget”而CurrentFloor是ROUND结果ROUND遵循四舍五入2.5会变成33.5会变成4导致电梯还没到目标层就提前停。解决办法是自己控制误差范围。比如定义“到达区间”为目标楼层±0.2层只要VirtualPos在区间内就认为到站。用代码表达IF ABS(VirtualPos - NextTarget) 0.2 THEN // 进入平层区触发停车 MotorUp : FALSE; MotorDown : FALSE; DoorOpenCmd : TRUE; END_IF;这段逻辑放在运行模型之后代替直接比较CurrentFloor。这样可以容忍位置脉冲的跳动仿真效果也更接近真实电梯的平层感应器动作范围。5.3 用轨迹表验证完整跑一趟的时间最后给一个我常用的验证技巧不要直接看梯形图而是画一张“位置-时间”表。启动仿真后记录每次电梯达到新楼层的时间点和方向手动输入到Excel或直接用一个全局数组记录。四层电梯标准测试场景是初始在一层依次按下四层、二层、三层并随机插入外部按钮。正确行为是先上行到四层然后下行到二层停靠再上行到三层停靠。如果程序输出变成“上行到三层”“下行到二层”“上行到四层”说明顺路截停逻辑没有生效。记录这组数据能快速判断方向扫描算法是否有问题。最后一步检查超时如果电梯在一层开门后DoorClosed信号在5秒内没有到达程序应该输出报警并重新尝试关门。仿真中我通常设置100ms的开门时间然后手动把DoorClosed置为FALSE用TON计算等待时间超过时间则复位输出。这个功能不需要额外硬件运行一趟约20秒就能测完所有边界。本文还有配套的精品资源点击获取