
1. 项目整体设计与思路拆解1.1 为什么选博途V15.1和S7-1200系列做电梯控制这个领域的老工程师都知道TIA Portal版本迭代快得让人头疼从V13一路到现在的V21每个版本都有各自的脾气。但如果你让我推荐一个最稳妥、最适合做中小型PLC项目参考设计的版本我仍然会首选博途V15.1。V15.1不像V13/V14那样对Win10系统兼容性差也不像V16之后的版本那样动辄占用十几个G内存、打开项目卡半天。V15.1在功能完整度、系统资源占用、硬件支持范围之间找到了一个很舒服的平衡点。再来看硬件选型。S7-1200系列是西门子中小型PLC的主力产品特别是1214C和1215C这两款CPU在处理六部十层电梯这种规模的控制任务时资源完全够用。一台电梯的逻辑控制量大概需要多少资源我大致估算过十层楼的厅外召唤信号最多19个一楼只有上行、顶楼只有下行中间楼层上下各一个轿内楼层按钮10个再加上开关门、平层、门区、安全回路、检修、消防等辅助信号单梯的数字量输入点大约在40点左右数字量输出点大约在20点左右。六个梯加起来需要240点DI、120点DO。1215C本体自带14点DI和10点DO剩下的通过扩展SM1221/SM1222模块就能解决成本可控逻辑清晰。1.2 六部十层电梯的参考程序定位标题里最关键的是“参考程序设计方案”这七个字。很多人拿到一个程序就急着往下翻想找到现成的梯形图直接抄这不叫参考方案这叫闭眼复制。真正的参考程序设计应该是把六部十层电梯的控制逻辑抽象成一套可复用的框架厅外召唤如何分配到具体电梯、顺向截梯怎么判断、反向截梯怎么处理、平层消除内选、端站校正楼层计数、多梯联动时的调度策略——这些核心算法搞清楚了你换成八部十五层、五部八层改的只是数据范围逻辑框架完全不用动。这个方案面向的读者我是这样设想的第一类是刚入行两三年、接触过博途基础操作但没完整做过电梯项目的电气工程师第二类是在设备厂工作、需要快速搭建电梯控制样机的调试工程师第三类是职业院校里教PLC课程的老师可以把这套框架用在自己的教学项目中。1.3 控制逻辑的架构拆解六部十层和单梯十层最大的区别在于“群控”。单梯只要管自己六梯就得管分配。厅外的上行/下行召唤信号来了之后系统需要判断哪部电梯去响应最合理。我采用的是分区调度最小等待时间结合的方案六部电梯分成三组每组两部分别负责低层区一层到四层、中层区五层到七层、高层区八层到十层层区之间有交叉重叠高峰时段可以跨区支援。这样既避免了所有电梯都涌向同一个召唤点的问题又不会像单双层分配那样僵化——单双层在上下班高峰期经常出现某部电梯被叫到顶楼、另一部在底楼闲着的尴尬局面。整个参考程序的PLC架构分四层第一层是信号采集层处理所有数字量输入和模拟量输入第二层是运行状态层用状态机管理每部电梯的当前状态第三层是调度分配层接收厅外召唤信号并分配给各梯第四层是执行输出层控制接触器、变频器、门机等设备。这四层在程序中解耦清晰调试的时候可以逐层排查不会出现牵一发动全身的情况。2. 核心细节解析与实操要点2.1 楼层检测和平层逻辑的设计十层电梯的楼层检测业界主流有两种方式一种是纯平层开关楼层计数井道里每层装一个平层隔磁板轿厢经过时平层开关动作一次PLC计数增减另一种是旋转编码器绝对位置校正编码器实时计算轿厢位置平层开关只做减速点和停靠点的校正。既然是参考程序我推荐用第二种方案原因很简单第一种方案在平层开关间距不均匀的时候计数的可靠性完全取决于安装精度而旋转编码器方案抗干扰能力强得多。具体做法是在曳引机轴端安装增量式编码器PLC用高速计数器通道采集脉冲。电梯从首层出发时计数器清零每上升一层累加的脉冲数通过井道高度除以层间距计算得出。由于钢丝绳打滑、机械误差的存在编码器计算的位置会漂移所以必须用平层开关做硬校正——轿厢到达某层平层区时以平层开关信号为准把当前楼层值直接写入数据块。这里有一个细节很多人第一次做会踩坑编码器脉冲方向。电梯上行和下行时脉冲计数的方向相反如果只用加法计数下行时脉冲数会越减越乱。我的做法是在OB100初始化时将高速计数器设置为双向计数模式通过方向信号确定加/减。SCL伪代码如下// 楼层计数校正逻辑SCL IF HSC_Status.Direction TRUE THEN #CurrentPulse : #CurrentPulse 1; // 上行累加 ELSE #CurrentPulse : #CurrentPulse - 1; // 下行累减 END_IF; // 平层校正当平层开关动作时用当前楼层覆盖计算值 IF IO_Inputs.LevelSwitch TRUE THEN #CurrentFloor : #CalculatedFloor; #CurrentPulse : #FloorPulseBase[#CalculatedFloor]; END_IF;2.2 电梯运行状态机的组织方式六部电梯每部都有七个基本状态空闲、运行、减速、平层停靠、开门、关门、故障。参考程序中我建议为每部电梯创建一个独立的FB函数块FB内部用CASE语句实现状态机跳转。这里要强调一个原则状态机只做状态切换的判断不直接执行输出。输出动作应该由状态本身去驱动这样逻辑才清晰。CASE #State OF 0: // 空闲状态 IF #CallUp OR #CallDown OR #CallCar THEN #State : 1; // 进入运行状态 END_IF; 1: // 运行状态 // 顺向截梯判断逻辑 IF #TargetFloor #CurrentFloor THEN #State : 2; // 进入减速状态 END_IF; 2: // 减速状态 IF #LevelSwitch TRUE THEN #State : 3; // 平层停靠 END_IF; 3: // 平层停靠 #Brake : TRUE; #State : 4; // 开门状态 4: // 开门状态 #DoorOpenCmd : TRUE; #OpenTimer(IN : TRUE, PT : T#5S); IF #OpenTimer.Q THEN #State : 5; // 关门状态 END_IF; 5: // 关门状态 // 检测门锁信号 IF #DoorLock TRUE THEN #State : 0; // 回到空闲状态 END_IF; 6: // 故障状态 // 故障处理逻辑 END_CASE;2.3 安全回路与信号采集电梯行业的安全标准非常严格作为参考程序安全逻辑绝对不能做成“意思一下”的摆设。急停按钮、限速器开关、安全钳开关、上下极限开关、断绳保护开关这些信号必须串联接入安全继电器回路安全继电器的常开触点再进入PLC的数字量输入。PLC程序里只负责监视安全回路状态并做出相应处理绝对不能替代硬件安全回路。这个边界必须清晰调试时也要提醒甲方PLC程序只是软件层面真正的安全保护靠硬件。厅外召唤信号的处理也是关键。每个厅外召唤按钮按下后信号需要保持直到被响应并完成停靠后才能消除。如果是顺向截梯电梯到达该层并开门后对应的厅外召唤才清零如果是反向截梯需要等到电梯完成转向后再次到达该层才能清除。这个逻辑做不好就会出现“电梯明明停过了厅外按钮还亮着”的尴尬情况。3. 实操过程与核心环节实现3.1 在博途V15.1中创建项目和硬件组态新建项目后第一步是添加CPU。我以1215C DC/DC/DC为例在设备视图中拖入CPU 1215C然后根据实际硬件配置添加信号板SB1232模拟量输出用于变频器速度给定和通信模块CM1241RS485用于和变频器Modbus通信——但现在主流变频器都支持PROFINET建议直接用PROFINET组态更省事。组态时有两个小细节容易被忽略第一时钟存储器字节务必开启。在CPU属性-系统和时钟存储器中勾选“启用时钟存储器字节”默认是MB100。这个字节的各个位会输出固定频率的脉冲信号0.5Hz、1Hz、2Hz等门机闪烁指示灯、检修蜂鸣器都可以直接引用省去自己写定时器的麻烦。第二高速计数器的组态。在CPU属性中启用HSC1作为编码器计数输入输入类型选择“计数”计数模式选择“双向”参考电压根据编码器型号选择24V或5V。把方向信号也配置好——通常编码器的A/B相分别接两个输入点通过比较A/B相相位差判断方向。硬件组态完成后需要在PLC变量的系统常量中找到HSC1的地址通常是ID1000供程序中使用。3.2 标签表和UDT数据结构的建立六部十层的标签量很大如果不建UDT用户自定义数据类型编程时会疯掉。我建了一个名为“Elevator_Data”的UDT包含以下主要字段状态字State_Word当前状态机状态命令字Cmd_Word启动、停止、检修、消防等命令故障字Fault_Word各个故障标志位当前楼层Current_Floor目标楼层Target_Floor上下行指示Direction_Up/Down各层内选呼叫Call_Car_Array: Array[1..10] of Bool各层厅外上行召唤Call_Up_Array: Array[1..9] of Bool各层厅外下行召唤Call_Down_Array: Array[2..10] of Bool平层状态Level_Status开关门状态Door_Status运行速度给定值Speed_Setpoint: Real创建UDT后在全局DB中建立一个数组Elevators: Array[1..6] of “Elevator_Data”。这样每一部电梯的数据都集中在一个DB里管理监控调试时打开DB就能看到全部信息非常直观。有人问为什么不用多重背景DB我的经验是对于参考程序用全局DB数组更直观不同水平的人接手都能快速看懂多重背景DB适合程序封装性要求更高的大型项目调试反而不方便。3.3 主程序OB1和循环中断的组织OB1里调用三个主要FBFB_IO_ScanIO扫描与滤波、FB_Elevator_Ctrl六部电梯的实例调用、FB_Dispatch_Alloc厅外召唤分配。OB100初始化里做数据初始化各楼层平层脉冲基准值写入DB、所有召唤信号清零、电梯复位到首层。这里说一个实操建议不要把所有的厅外召唤分配逻辑都写在OB1里。我在设计参考程序时把分配逻辑放在一个单独的FB_Dispatch_Alloc中每50ms执行一次通过OB32循环中断触发。为什么不用OB1连续扫描因为分配逻辑需要“稳定”的信号状态连续扫描时信号抖动的瞬间可能导致重复分配——某层召唤被分配给两台电梯造成两台电梯同时去响应。循环中断强制执行间隔相当于加了时间滤波稳定性好很多。FB_Elevator_Ctrl内部采用多实例调用方式每个电梯实例共享同一套控制逻辑但背景数据相互独立。这里用FOR循环遍历六部电梯每一轮的当前电梯索引作为数组下标就能复用一套逻辑处理六台电梯。SCL伪代码如下FOR #i : 1 TO 6 DO #ElevatorData : Elevators[#i]; // 调用电梯控制FB #EleCtrl_Instance( Data : #ElevatorData, IO_In : #IO_In_Array[#i], IO_Out : #IO_Out_Array[#i] ); END_FOR;3.4 厅外召唤的分配逻辑实现这是整个参考程序最核心的算法。当某层厅外上行召唤信号为TRUE时系统需要从六部电梯中选一部去响应。我采用“投票打分”机制每部电梯根据当前状态和位置计算一个分值得分最高或最低根据定义的电梯获得该召唤。评分维度包括电梯当前楼层与召唤楼层的距离、电梯当前运行方向是否与召唤方向一致、电梯当前是否处于故障/检修状态、电梯当前是否已有大量内选任务。距离越近加分越多、方向一致加分更多、故障检修状态直接排除。如果有两部电梯得分相同则优先选择上一次分配次数最少的电梯实现负载均衡。这个打分算法用SCL写起来很简单但需要反复推演的边界情况很多。我实测中发现最容易出错的是“空闲电梯”的处理如果一部电梯完全空闲它的得分是否应该比正在下行但顺路的上行电梯高我的做法是空闲电梯加一个较大的基础分但如果上行电梯能在同一方向截梯额外加分超过空闲基础分这样效果更好。这个系数需要在现场实际调整参考程序中我把它做成一个可调参数放在DB里方便调试时在线修改。4. 常见问题与排查技巧实录4.1 博途V15.1在Win10/Win11下老是需要重启这个问题我遇到得太多了群里有同行新装了V15.1打开软件后提示“需要重启计算机”重启完还是提示能把人逼疯。排查顺序是这样的先看杀毒软件西门子的License服务Automation License Manager Service会在启动时检查授权文件杀毒软件拦截授权服务就会导致异常。解决办法是把整个安装目录、授权目录加入杀毒软件白名单然后重启服务。如果还不行大概率是Windows Installer缓存问题用“msiexec /unregister”和“msiexec /register”重新注册Windows Installer服务再重启。还有一种情况是V15.1和Office插件冲突特别是Visio和Project的许可证服务会抢占西门子授权服务端口。如果你电脑装了这两个软件建议把Visio的许可证服务设为手动启动实测能解决大部分“需要重启”的奇怪问题。4.2 博途卸载重装时注册表残留问题很多项目上需要把V15.1升级到V16或者V18卸载不干净是重装失败的第一大原因。V15.1卸载后注册表里至少残留几十个相关项手动清理不现实。我的经验是分三步先用控制面板正常卸载然后下载西门子官方的Uninstall Tool在Support网站可以找到不需要账号它会扫描所有西门子软件并强制清理。最后打开注册表编辑器搜索“Siemens Automation”和“TIA Portal”两个关键字删除残留项——注意只删和西门子相关的别手滑删了其他软件的项。这个办法我用了很多次重装成功率接近百分百。4.3 博途密钥过期怎么办打开项目提示“许可证密钥缺失或过期”是最常见的授权问题。先打开Automation License Manager开始菜单里搜索检查STEP 7 Professional和WinCC的许可证状态。如果显示过期需要重新下载对应版本的许可证密钥Sim_EKB的授权方式在工程圈里很普及但正规渠道还是联系西门子销售申请试用授权。有一个细节要注意V15.1的许可证和V16不通用如果电脑上装过多个版本最好把旧版本的授权文件全部删除只保留当前版本对应的否则License Manager会混乱。4.4 触摸屏字符串显示旧值的问题标题热搜词里有一条“博途字符串里面的值已经为0但是触摸屏为什么还是显示原来的字符”这个问题我详细说一下。在WinCC Comfort面板中字符串变量的显示和普通整数/实数变量的机制不同字符串类型在HMI中默认带有缓冲区如果PLC端把字符串清空了但HMI的画面帧没有主动刷新该区域就会一直保留旧内容。解决办法有三个一是在HMI变量属性中把字符串变量的“采集周期”从默认的1s改为100ms刷新频率越高越不容易缓存二是做两个字符串变量一个作为数据源一个作为显示缓存PLC写入新值后先写显示缓存清空数据源时把显示缓存也同步清空三是如果字符串只是在报警/日志界面显示检查该画面组件的“刷新周期”是否设置为“永久”。实测中最有效的是第二种从逻辑上杜绝了缓存不一致的问题。4.5 SCL中TON定时器怎么用用SCL写TON定时器很多人第一次会报错因为SCL中定时器需要先声明一个TON的实例。正确写法如下// TON使用示例 #Open_Timer_Instance(IN : #DoorOpenCmd, // 输入条件 PT : T#5S, // 定时5秒 Q #DoorOpenDone, // 输出 ET #OpenTimeElapsed); // 已计时时间重点是定时器实例必须在FB接口区或DB中声明不能直接在OB1的临时变量区声明。因为TON需要保持状态临时变量区每次循环后会被覆盖。常见的报错“OB的临时区不能用于存储定时器实例”就是这个原因。我在参考程序中所有定时器都在FB的Static区声明。4.6 V16/V18有授权打不开项目的问题最近有同行装的是V18下载了参考程序结果打不开——版本不兼容。TIA Portal的工程文件版本是向下不向上兼容的V15.1的项目可以用V16/V18打开V17以后的版本支持直接打开低版本项目会弹出升级提示但V18的项目V15.1打不开。如果你用的是V15.1需要眼尖一点下载项目前确认对方保存时是什么版本。另外升级项目时会有个选择是否保留原有项目版本Multi-User模式可以在服务器上保留多版本我建议不要盲目升级参考程序一般是框架性的直接在低版本里重建工程量也不大。5. 六部十层调度策略与消防联动设计5.1 多梯群控的分区策略前面提到我把六部电梯分成三个区很多同行拿到参考程序后第一反应通常是“分区分组是不是固定的”我给的这套参考方案做了个灵活的配置区程序启动时读取一个配置DB或HMI上的设置页面可以自由选择“统一调度模式”“分区调度模式”“单双层调度模式”。不同使用场景下切换方便——写字楼早高峰适合分区商场全天候适合统一调度住宅小区错峰时段适合单双层。分区分组时最需要考虑的是“跨区支援”条件当A区两部电梯都忙碌、B区有一部空闲时A区的召唤应该被B区电梯响应。这个功能实现起来不复杂只需在分配打分算法中增加一个“跨区使能”标志当某区电梯占据率超过80%时自动把该区的召唤信号开放给相邻区域。我这里说的占据率不是真正的百分比而是已分配任务数和内选数的加权和。这个加权值可以根据项目现场情况调整参考程序里我初始设为“内选外呼分配总数超过6时触发跨区支援”。5.2 并行内选和外呼的处理逻辑十层楼的内选和外呼最怕的是“顺向不拦、反向盲冲”的乱逻辑。参考程序中内选和外呼被分成三类顺向截梯电梯运行方向上前方楼层有召唤、反向截梯电梯运行方向反方向有召唤电梯会在完成当前方向的所有顺向任务后再转向响应、本层外呼电梯停在某层该层有召唤且方向一致直接开门。顺向截梯是最优先的。电梯从第3层上行第5层有上行召唤第7层有内选。这时电梯应该在第5层停靠开门并消除外呼再继续上行到第7层。反向截梯放在最后处理电梯从3层上行去7层第2层有上行召唤电梯到7层后会改变方向下行到2层响应召唤。这个“先同向再反向”的顺序必须通过程序强制否则就会出现电梯被反向召唤“拽”得来回乱跑。5.3 消防联动和基站返回消防信号是整个电梯控制系统中优先级最高的外部信号。参考程序中消防信号接入PLC的数字量输入点一旦为TRUE所有电梯立即进入消防模式正在运行的电梯不在当前层停靠而是直接返回基站层通常是一层开门并停梯途中忽略一切内选和外呼。电梯在消防模式下不允许自动响应任何召唤只允许消防员通过轿内的专用开关消防员钥匙手动控制。这个逻辑难在“立即返回”的路径规划如果电梯正在上行去7层消防信号来时电梯在第4层程序应该让电梯在最近顺向可停层停靠后换向还是直接继续上行到顶层再返回按照国内规范的要求消防返回时电梯应保持当前运行方向运行到最近层站停靠然后换向下行回到基站。参考程序中我严格按这个规范实现安全第一。5.4 防捣乱与满载直驶功能满载直驶是防止资源浪费的关键。轿厢内加装称重装置或超载开关当载重达到额定载重的90%以上参数可调时电梯自动取消所有顺向外呼响应只保存已登记的内选。这样做有两个好处一是减少了高峰期电梯频繁停靠的浪费二是保护曳引机和制动器避免频繁启停。慢速满载/超载报警信号在参考程序中分别用两个DI点采集程序里做了20ms的滤波去抖避免瞬时波动导致误判。防捣乱功能是针对恶意多次按键的当电梯在某个方向运行时如果某个内选层站被登记后超过三次重复选择比如乘客反复按某个楼层按钮又取消系统自动屏蔽重复内选避免电梯被无效指令拖累。这个防捣乱逻辑很多商业电梯系统有但参考程序中做到这个深度的不多。取值阈值我放在了DB中可调整现场根据实际客流情况微调。5.5 数据统计与监控接口扩展六部十层的参考程序不需要像商业系统那样做复杂的后台管理但预留一份数据监控接口非常有必要。我在程序里把每部电梯的运行次数、开门次数、故障次数、累计运行时间做成统计字段通过PROFINET通信或Modbus TCP接口开放给上位机或云平台。你可以直接接个组态软件或者用简单的MQTT网关把这些数据推送到云端做电梯健康度分析。实际项目里这个接口帮过我大忙——某项目甲方反馈5号梯老是无故停梯但现场又没有报警记录我通过历史数据看到5号梯“无故障运行次数”和实际运行记录不匹配进一步排查发现是抱闸微动开关间隙调整不到位偶发信号抖动导致控制器误判。有了数据统计这种偶发问题就好定位很多。6. 实操心得与调试建议项目做完电气设计、程序写好真正的战场在调试。六部十层的电梯调试我一般会按这个顺序做先单梯调试再群控联调先慢车调试再快车调试先手动运行再自动运行。单梯调试时重点验证楼层计数是否准确电梯从首层开始慢车向上每经过一个平层开关监控DB里的当前楼层值是否递增。如果递增异常优先检查编码器脉冲方向和平层开关信号是否抖动。这一步做好了后面快车运行基本不会出大问题。信号测试用强制表最快。在博途的监控表中把每部电梯的厅外召唤、内选、平层、门锁信号一一强制置位观察控制器的响应是否正确。重点测试以下场景同方向召唤穿越响应、最远端反向召唤、本层外呼开门、超时关门保护关门过程中门锁信号长时间不反馈程序应自动开门重新关门防止夹人事故。群控联调是整个项目最耗时也最容易出问题的地方。六部电梯同时运行时大厅外呼的分配是否合理、会不会两部电梯同时响应同一个召唤、会不会出现“楼道空车跑”的现象某电梯被分配去响应召唤但到之前又被更近的电梯抢先了这些都要反复试验。我的经验是准备一个20分钟的脚本模拟上班高峰期大量上行召唤集中在一层、下班高峰期大量下行召唤集中在顶层、闲时随机召唤三种场景每种场景跑两遍记录每部电梯的响应时间和等待时间对照评分算法参数调整。最后想说的是做电梯控制参考程序核心不是把代码写对更重要的是把边界情况想清楚。比如“电梯正在开门时被分配了新的厅外召唤”按我的设计要等门完全关闭后才能执行新的任务“电梯检修模式下所有召唤无效”但消防信号仍然有效这些优先级和互锁关系看着不起眼调试时都能让人头疼半天。我在博途V15.1下用S7-1200写这套六部十层参考程序前后打磨了大约一个多月中间改过的版本不下十稿。现在拿出来重新整理这套设计方案不是为了给一套能直接跑的程序——每个项目的井道尺寸、楼层高度、变频器型号都不一样照抄没有意义。有价值的是一整套可复用的设计思路状态机怎么划、数据结构怎么建、算法参数怎么调、故障怎么排查。你拿着这套思路去做五部八层、八部十二层无非是数组维度改一下参数重新标定一遍核心逻辑完全不用动。这就是参考程序设计的意义所在。