最近做了一套三层电梯的联机程序,上位机用组态王6.55,控制端用S7-1200 PLC,逻辑部分全部在博途V15.1里完成,两边通过工业以太网直连。整套东西跑通以后,我特意录了一段运行效果视频,画面里轿厢走动、呼梯灯亮灭、开关门动作都很直观。很多朋友看到视频后问我,组态王和S7-1200到底怎么把变量对上、怎么才能不掉线、画面又是怎么跟着PLC动的。这篇就把项目的完整思路、程序结构、通信配置和排查经验一次说清楚。不管你是刚接触组态王的新手,还是在现场调过联机但总被地址问题折腾的电气工程师,这套三层电梯的完整闭环都值得照着搭一遍。
1. 项目整体设计与控制思路
1.1 三层电梯的控制需求拆解
虽然三层电梯在所有电梯项目里算最简单的,但电梯控制该有的核心逻辑一个都跑不掉。我在动手前先把控制需求列成一张清单,后面照着写程序才不会漏项:
- 楼层范围:1F、2F、3F,共三层,轿厢初始停在1F。
- 内呼按钮:轿厢内设置1F、2F、3F三个目的地按钮,按下后登记呼梯,到达目标楼层后自动复位。
- 外呼按钮:1F只有一个上行按钮,3F只有一个下行按钮,2F同时有上行和下行两个按钮。
- 输出状态:当前楼层、运行方向(上行/下行/停止)、开关门状态、各呼梯指示灯。
- 顺序规则:电梯空闲时响应第一个呼梯;运行过程中优先响应顺向呼梯,完成当前方向所有任务后再处理反向呼梯。
- 门控要求:到站后自动开门,开门到位延时自动关门,开关门超时要有保护。
三层电梯看起来简单,但“顺向响应、反向保持”这个原则如果没想清楚,程序很容易跑着跑着就乱套。把这些需求先在纸上理清楚,比直接打开博途拖梯形图靠谱得多。
1.2 为什么选组态王6.55加S7-1200这个组合
组态王6.55在国内工控项目里占有率很高,资料多、授权好找,画面对新手也友好。S7-1200 PLC体积小、联网能力强,自带以太网口,非常符合这种小规模实训和演示项目。关键是组态王有对应的S7-1200 TCP驱动,可以直接读写PLC的DB块,不需要额外买OPC网关或者转接模块,成本低、链路短。
有人问怎么不用WinCC或者直接用触摸屏。WinCC和博途集成的确好,但授权成本高,而且组态王在做自定义图形、模拟量报表、历史曲线方面其实更灵活。触摸屏适合生产现场,但用来做教学演示或验收项目时,画面共享和录屏都不如PC版组态软件方便。所以这个项目用组态王6.55做上位机,S7-1200做控制核心,算是性价比很高的组合。
2. PLC程序设计与博途实现
2.1 先建一张变量表再动手写程序
在博途V15.1里新建项目、添加好CPU之后,我建议第一步不是拖梯形图,而是把所有输入输出和中间变量整理成表格。我把电梯的核心状态统一放到一个DB块里,这样组态王只需要针对这一个数据块配置地址,不用东找一个M点西找一个Q点,后续调试也轻松。
我设计的DB1变量布局大致如下:
| 变量名 | 地址 | 数据类型 | 说明 |
|---|---|---|---|
| InternalCall_1F | DB1.DBX0.0 | Bool | 1F内呼登记 |
| InternalCall_2F | DB1.DBX0.1 | Bool | 2F内呼登记 |
| InternalCall_3F | DB1.DBX0.2 | Bool | 3F内呼登记 |
| UpCall_1F | DB1.DBX0.3 | Bool | 1F上行外呼 |
| UpCall_2F | DB1.DBX0.4 | Bool | 2F上行外呼 |
| DownCall_2F | DB1.DBX0.5 | Bool | 2F下行外呼 |
| DownCall_3F | DB1.DBX0.6 | Bool | 3F下行外呼 |
| CurrentFloor | DB1.DBD2 | DInt | 当前楼层 |
| DirUp | DB1.DBX2.0 | Bool | 上行方向标志 |
| DirDown | DB1.DBX2.1 | Bool | 下行方向标志 |
| DoorOpenCmd | DB1.DBX2.2 | Bool | 开门指令 |
| DoorCloseCmd | DB1.DBX2.3 | Bool | 关门指令 |
| DoorOpenDone | DB1.DBX2.4 | Bool | 开门到位反馈 |
| DoorCloseDone | DB1.DBX2.5 | Bool | 关门到位反馈 |
地址排布要留够余量,别把Bool和双字挤在一起引起字节错位。这里CurrentFloor用DInt是因为组态王里对应Long类型比较好映射,而且楼层值不会为负,用双字更稳。
有一点必须提醒:S7-1200默认新建的数据块带“优化的块访问”,这种DB块没有固定的字节偏移地址,组态王想直接按DB1.DBX0.0这种地址去访问是读不到的。我后面在通信章节会专门讲怎么处理,这里先记着。
2.2 呼梯登记与复位逻辑
呼梯信号本质上是典型的置位复位逻辑。我在程序里统一用置位指令来登记,用复位指令来清除,而不是用普通线圈保持。因为PLC扫描周期很快,按钮按下只有一瞬间,如果用普通线圈,松开按钮之后信号就会消失,根本保持不住。
以1F内呼为例:
- 触发条件:轿厢内1F按钮按下,置位InternalCall_1F。
- 复位条件:电梯到达1F,开门到位后,复位InternalCall_1F。
外呼的复位条件要更细致。电梯上行过程中到达某层,只应该复位该层的上行外呼;如果这一层还有下行外呼,不能顺手消掉,必须等电梯真正下行到该层时再复位。同理,电梯下行时只复位下行外呼,上行外呼保持。这一步是新手最容易写错的地方,一旦提前复位外呼,乘客在楼层等着却不停,项目验收时很难看。
2.3 方向决策:电梯控制的灵魂
方向判断我单独写成了一个功能块,输入是所有呼梯信号和当前楼层,输出是上行标志、下行标志。用SCL写起来很直观,核心思路是把呼梯需求折算成“该不该向上走”和“该不该向下走”。
简化后的判断逻辑如下:
// 上行需求:有上行外呼,或有高于当前层的内呼 #NeedUp := (#UpCall_1F OR #UpCall_2F) OR (#InternalCall_2F AND #CurrentFloor < 2) OR (#InternalCall_3F AND #CurrentFloor < 3); // 下行需求:有下行外呼,或有低于当前层的内呼 #NeedDown := (#DownCall_2F OR #DownCall_3F) OR (#InternalCall_2F AND #CurrentFloor > 2) OR (#InternalCall_1F AND #CurrentFloor > 1); IF #NeedUp AND NOT #NeedDown THEN #DirUp := TRUE; #DirDown := FALSE; ELSIF #NeedDown AND NOT #NeedUp THEN #DirUp := FALSE; #DirDown := TRUE; ELSE #DirUp := FALSE; #DirDown := FALSE; END_IF;但实际工程里还需要增加一个保持条件:电梯正在上行时,如果当前还有上行目标,即使这时候出现了下行呼梯,也不能立刻换向,必须等上行方向所有目标都完成之后才能转下行。所以我在功能块里加了一个“当前方向是否有剩余目标”的判断。这步不做,电梯就会在2层和3层之间反复横跳,看着像抽风一样。
为了处理这个逻辑,我在DB里增加了一个“目标楼层表”,用一个整型数组记录每个楼层是否需要停靠。每次跑完一层就清除对应标记,当上行方向不再有更高层目标时,才允许切换到下行方向。
2.4 运行、到站与开关门逻辑
电梯运行时靠楼层反馈信号来更新当前楼层。我这里没有实际的门禁或限位传感器,所以用模拟方式处理:上行时,当运行到某一层的位置信号到来,CurrentFloor加1;下行时减1。真正的现场项目则要接平层感应器和上下限位开关,逻辑是一样的。
到站停靠条件要满足两点:
- 当前方向上的目标楼层等于当前楼层;
- 该楼层对应的呼梯信号有置位。
满足后立即清除方向输出,触发开门指令。开门到位信号反馈回来后,开始定时延时,我设置的是4秒,延时结束自动关门。关门到位后,重新检查还有没有其他呼梯,有就继续走。
延时功能用IEC定时器TON实现:
#TonOpenHold(IN := #DoorOpenDone, PT := T#4S); #OpenHoldDone := #TonOpenHold.Q;S7-1200里面建议用TON这种IEC定时器,不要在OB1里直接拖老式定时器线圈,因为新版博途对实例化和背景数据块的要求比较严格,用得不规范很容易编译报错。
2.5 先仿真再联机,省一半调试时间
我个人的习惯是,PLC侧程序写完以后,先不急着跟组态王联机。在博途里启动仿真,用程序内部的模拟输入把三层可能出现的呼梯组合全部测一遍。比如一楼呼叫去三楼、二楼同时按上下行、电梯上行过程中二楼突然插一个下行呼梯,这些情况都要在仿真里跑干净。
仿真能直接看到方向切换、目标楼层表和开关门时序是否正确。等PLC逻辑确认没问题,再开组态王联调,基本上不会出现“画面里电梯乱跑”这种尴尬情况。
3. 组态王6.55画面设计与变量关联
3.1 画面布局怎么画才实用
组态王6.55的画面是用图元拼出来的,不需要多华丽,关键是信息一眼能看明白。我的布局分成三大块:
- 左侧是电梯井道示意:画出三个楼层边框,中间放一个轿厢矩形,轿厢位置随楼层变量上下移动。
- 右侧上方是轿厢内呼面板:1F、2F、3F三个内呼按钮,还有开门和关门按钮。
- 右侧下方是各楼层外呼按钮和状态灯:1F上行、2F上行、2F下行、3F下行。
图元工具用矩形、椭圆、文本就够了。想做得好看一点,可以给轿厢加个边框,给按钮加个变色效果。组态王自带的图库管理器里也有电梯相关图形,但自己画出来的图元更清楚,变量映射也不容易错。
3.2 数据词典与I/O变量定义
打开组态王工程浏览器的“数据词典”,新建变量时要注意几个关键选项:
- 变量类型选“I/O变量”,连接设备选择你新建的S7-1200设备。
- 寄存器地址按DB块地址填写,比如DB1.DBX0.0对应DB1的0号字节第0位。
- 数据类型要跟PLC侧完全一致,否则数值会变样。
我用过的变量映射示例如下:
| 组态王变量名 | 设备地址 | 类型 | 对应PLC变量 |
|---|---|---|---|
| InternalCall_1F | DB1.DBX0.0 | Bit | InternalCall_1F |
| CurrentFloor | DB1.DBD2 | Long | CurrentFloor |
| DirUp | DB1.DBX2.0 | Bit | DirUp |
| DoorOpenCmd | DB1.DBX2.2 | Bit | DoorOpenCmd |
变量一旦配错,最常见的现象是画面某个按钮按下没反应,或者数值读出来是乱的。这里要把组态王里的“Long”对应博途的“DInt”,“Int”对应“Int”或“Word”,别搞混。
3.3 动画连接与按钮事件设置
轿厢垂直移动是整个画面最核心的动画。我给轿厢矩形添加“垂直移动”动画连接,表达式指向组态王里的“轿厢位置”变量。这个变量直接用当前楼层换算成像素坐标。
换算脚本可以放在“命令语言”的应用程序脚本里:
\\本站点\CarPos = 150 - (\\本站点\CurrentFloor - 1) * 40;假设1F轿厢的Y坐标是150,3F的Y坐标是70,每层间隔40像素。CurrentFloor=1时,CarPos=150;CurrentFloor=3时,CarPos=70。这样轿厢矩形就能跟着楼层变量平滑移动。要注意脚本的刷新频率,如果画面卡顿,可以把数值变化放在变量变化事件里触发。
按钮事件用组态王的“弹起”动画连接。以1F内呼按钮为例,在“弹起”事件里写入:
\\本站点\InternalCall_1F = 1;弹起时把变量置1,PLC收到后保持登记。呼梯响应后,再由PLC复位该变量,画面中的按钮状态灯会自动恢复颜色。
3.4 显示与指示灯的颜色逻辑
呼梯指示灯我用的是“颜色变化”动画连接。当I/O变量的值为真时,颜色变成红色;为假时,颜色变成灰色。这样按钮按下去以后灯会亮,电梯到站响应后灯自动灭,整个流程非常直观。
状态灯和方向箭头也一样,DirUp为真时让上行箭头变绿色,DirDown为真时让下行箭头变绿色。加一个当前楼层数字显示,直接用文本连接CurrentFloor变量,类型选Long即可。
4. 通信联调与配置
4.1 PLC侧隐藏的“允许PUT/GET”开关
S7-1200和组态王联机,最容易卡死的一个点,就是电脑明明能ping通PLC,但组态王设备状态一直是故障,变量全部读不到。遇到这个情况,先检查PLC的远程通信权限。
在博途V15.1里打开CPU属性,找到“防护与安全” > “连接机制”,把“允许来自远程伙伴(PLC、HMI、OPC、PUT/GET)的通信访问”勾上。默认情况下这个选项在一些版本里是关闭的,不打开就相当于把数据块的门锁死了,组态王从外部无论如何都访问不到。
勾选后要重新编译并下载到PLC。这一步不做,后面配置组态王驱动就算IP、机架号全对,也照样白搭。
4.2 数据块必须取消优化访问
前面提到过,S7-1200默认创建的DB块带“优化的块访问”。这种块没有固定偏移量,组态王无法用绝对地址去访问。解决方法是去掉这个选项。
在博途项目树里右键DB1,打开属性,在“属性”选项卡里取消“优化的块访问”,然后重新编译下载。这样组态王才能用DB1.DBX0.0、DB1.DBD2这样的标准地址正常读写。
如果项目为了某些原因必须保留优化访问,那就只能绕道OPC通道,不能直连组态王。对于这个三层电梯项目来说,直接用非优化DB最省事,没必要跟自己过不去。
4.3 组态王驱动建立与参数填写
在组态王工程浏览器的“设备”里新建驱动,选择S7-1200 TCP。设备地址填PLC的IP地址,比如192.168.0.1。端口默认102,机架和插槽号S7-1200一般填机架0、插槽0,少数驱动版本写Slot 1,以实际驱动说明为准。
电脑网卡的IP地址必须和PLC在同一网段,比如PLC是192.168.0.1,电脑就设192.168.0.10。电脑防火墙如果开着,一定要放行组态王运行系统对外的网络访问,否则端口102会被拦掉,设备还是会报故障。
4.4 联机调试顺序与视频录制技巧
联机调试我有一套固定的流程,新手可以直接照搬:
- 第一步:ping通PLC的IP,确认物理链路。
- 第二步:打开组态王的“设备测试”工具,看连接状态是否正常。
- 第三步:先建一个简单变量,比如M0.0,在画面上放一个按钮和一个指示灯,先证明变量能读写。
- 第四步:再关联DB块里的所有电梯变量,跑通整幅画面。
- 第五步:录运行效果视频,录制时最好把组态王画面和博途在线监控变量表同时开在屏幕上,分屏展示。这样观众能同时看到按钮触发时PLC内部的位变化,联机效果一目了然。
5. 常见问题与排查技巧
5.1 通信故障速查表
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 设备状态显示故障 | 网段不一致、IP冲突 | 两端固定IP,用ping确认 |
| 能ping通但变量读不了 | PLC未勾选PUT/GET访问 | 打开“连接机制”选项 |
| DB数据读出来乱码 | DB块用了优化访问 | 取消优化访问并重编译 |
| 只有部分变量刷新 | 变量类型或偏移地址不一致 | 对照博途离线DB表逐一核对 |
| 画面长时间卡死 | 刷新周期太短或脚本死循环 | 调整采集周期,优化脚本 |
5.2 地址不对齐的经典翻车现场
组态王里地址按字节偏移,博途的DB也是按字节偏移,但两者的Bit位和数据类型长度要格外小心。比如DB1.DBX2.0是第2个字节的第0位,而DB1.DBD2是从第2个字节开始的双字。在同一个DB里,如果Bool和DInt交错排列,很容易因为字节对齐导致后续变量全部错位。
我遇到过一个问题:变量表里前面排了四个Bool,后面直接放DInt,结果DInt的地址被对齐到了DBD8而不是DBD2。组态王里填DBD2就怎么都读不对。解决办法是给Bool变量单独集中放在一块,或者每个DInt前面预留完整的字节区间,不要贪省空间。
5.3 电梯逻辑乱跑的几种原因
逻辑乱跑最常见的原因有三个:
第一,外呼复位条件写错。电梯上行经过2楼时,把2楼的下行外呼也复位了,结果下行时不再停靠,乘客就傻等。解决方法是复位时必须判断当前运行方向和呼梯方向一致。
第二,方向判断没有“当前方向任务未完成禁止换向”的保持逻辑。电梯上行响应3楼内呼时,2楼有人按下行外呼,如果程序立即切换方向,电梯会在半路掉头。这种问题仿真阶段就会暴露,别偷懒跳过仿真测试。
第三,定时器实例冲突。在OB1里连续调用同一个TON背景数据块去控制开门和关门两个延时,第二个调用会不断覆盖第一个的运行时间,导致门根本不按预期动作。解决办法是给开门、关门分别建两个不同的TON实例。
5.4 组态王脚本常见的语法坑
组态王命令语言是类C语法,但变量名一定要带“\本站点\”前缀,否则运行时报“找不到变量”。脚本里如果做浮点运算,要把变量类型定义成Float或Double,别拿Long直接算除法,否则结果永远是整数。
我一般把位置换算这类计算放在“应用程序脚本”的启动时执行一次,再用变量变化事件去更新轿厢位置。别把计算放在每周期都扫描的脚本里,那样会造成画面刷新负担,电梯动起来一顿一顿的。
6. 运行效果与个人体会
整套联调跑通以后,组态王画面里能看到轿厢按照呼梯顺序来回走,按钮按下时指示点亮,到站以后自动复位,开门延时几秒再关门。方向箭头一直跟实际运行方向保持一致,视频录出来很有说服力。
我个人做这类组态王加S7-1200的联机项目最大的体会是,真正的难点从来不是PLC逻辑本身,也不是组态王画图技巧,而是两边变量映射关系的梳理。只要前期把DB块的变量表设计清楚,组态王每个I/O变量的地址和类型都能和PLC侧一一对上,联机基本就是顺理成章的事。
最后分享一个实战小技巧:做完画面主体后,我会在组态王里额外做一张“调试面板”,把DB里所有关键变量用列表形式一屏排出来。联调时一边操作电梯,一边盯调试面板上每个Bool和数值的变化,哪一步没触发一目了然。定位完问题再切回主画面看动画效果,效率比在工程树里反复翻变量快太多了。这套三层电梯项目虽然不大,但闭环走一遍,组态、PLC、通信、联动这几个环节的功夫都能练到,值得仔细做一次。