西门子1200博途三部十层电梯程序案例,加Wincc RT Professional画面三部十层电梯程序,版本V14及以上。 程序仅限于参考资料使用。
"最近在翻硬盘发现个有意思的案例——三台十层电梯联控。虽然项目是几年前用博途V14做的,但里面的联锁逻辑和HMI交互设计思路现在看还挺实用。今天就带大家拆解几个关键模块,手头有1200 PLC的朋友可以跟着试试。
先看硬件配置:三台1200 CPU(1215C DC/DC/DC)各带一台电梯,WinCC RT Pro做集中监控。重点在于电梯间的协同算法,比如当两部电梯同时响应同一楼层呼叫时,要自动分配最近的那台。
核心算法在SCL里写得挺有意思,比如这个方向判断函数:
FUNCTION_BLOCK FB_ElevatorDirection
VAR_INPUT
currentFloor : INT;
targetFloor : ARRAY[1..10] OF BOOL;
END_VAR
VAR_OUTPUT
direction : INT; //-1=下行 0=停止 1=上行
END_VAR
VAR
i : INT;
hasAbove, hasBelow : BOOL;
END_VAR
hasAbove := false;
hasBelow := false;
FOR i := 1 TO 10 DO
IF targetFloor[i] THEN
IF i > currentFloor THEN
hasAbove := true;
ELSIF i < currentFloor THEN
hasBelow := true;
END_IF;
END_IF;
END_FOR;
CASE currentFloor OF
1: direction := hasAbove ? 1 : 0;
10: direction := hasBelow ? -1 : 0;
ELSE
direction := (hasAbove AND hasBelow) ? (direction) : (hasAbove ? 1 : -1);
END_CASE;
这段代码的巧妙之处在于处理中间楼层的"方向保持"逻辑。当电梯处于移动状态且有上下两层都有呼叫时,会延续之前的运行方向。通过布尔数组记录各层呼叫状态,循环检测时采用线性扫描而非复杂算法,虽然时间复杂度是O(n),但对十层电梯完全够用。
WinCC画面里有个容易被忽视的细节——用全局脚本实现了轿厢位置的平滑移动动画。在图形对象的位置属性绑定这个表达式:
Dim actualFloor
actualFloor = SmartTags("Elevator1/CurrentFloor")
If actualFloor > 0 Then
PositionY = 460 - (actualFloor -1)*40 + (SmartTags("Elevator1/Moving") * 20 * Sin(Time/100))
End If
这里用Sin函数生成振动效果模拟电梯运行时的轻微晃动,Time/100控制振动频率。不过实际项目中要注意别让动画效果影响操作响应速度。
同步问题处理是另一个亮点。当多个电梯同时到达某层时,这个互锁逻辑确保只有最先响应的电梯开门:
IF #DoorOpenCmd[1] THEN
#DoorLock[2] := 1;
#DoorLock[3] := 1;
ELSIF #DoorOpenCmd[2] THEN
#DoorLock[1] := 1;
#DoorLock[3] := 1;
...
这种硬互锁虽然增加了安全性,但要注意在紧急模式下需要解除互锁。建议在OB100初始化时重置所有互锁信号,避免异常断电导致的状态混乱。
调试时发现个有趣现象:如果直接用MOVE指令更新目标楼层,可能因扫描周期导致呼叫信号丢失。后来改用SET_BIT指令操作楼层请求数组才解决:
//错误写法
floorRequests[callFloor] := true;
//正确写法
SET_BIT(arr:=floorRequests, bitIdx:=callFloor-1, value:=true);
因为SCL数组索引从1开始,而SET_BIT的位索引从0开始,这个偏移量坑了不少新人。建议封装个自定义函数统一处理这类转换。
这个案例虽然不算复杂,但把状态机、动画绑定、设备协同这些工业场景的典型需求都覆盖到了。特别适合作为从单机控制转向分布式的练手项目。代码里有些看似’笨拙’的设计(比如用数组代替更高级的数据结构),反而体现了工控编程的务实哲学——稳定大于炫技。"
电梯控制这玩意儿看起来简单,搞过的人才知道坑有多深。今天拆解一个基于西门子1200的三梯十层项目,带WinCC上位机监控的那种。别急着复制代码,重点是理解处理逻辑的思路。
先说核心——状态机。电梯最怕的就是逻辑打架,用状态机划分运行阶段最稳。看这段:
//电梯运行状态枚举
TYPE E_ElevatorState :
(
IDLE,
DOOR_OPENING,
DOOR_CLOSING,
MOVING_UP,
MOVING_DOWN,
EMERGENCY_STOP
);
END_TYPE
这枚举把电梯可能的状态框死了,后面编程就像搭积木。比如处理开门动作时:
CASE #elevatorState OF
IDLE:
IF #callButtonPressed THEN
#elevatorState := DOOR_OPENING;
#doorTimer(IN:=TRUE, PT:=T#2S);
END_IF;
DOOR_OPENING:
IF #doorTimer.Q THEN
#elevatorState := DOLE_CLOSING;
#doorTimer(IN:=FALSE);
END_IF;
每个状态都有明确的进入/退出条件,用定时器控制门动作时长比死等靠谱多了。
再说说呼叫调度这个头疼问题。三部电梯的呼叫分配要玩点算法,这里用了个简化版最近优先级:
//计算电梯与目标楼层的距离差
FOR i := 1 TO 3 DO
#distance[i] := ABS(#currentFloor[i] - #targetFloor);
END_FOR;
//选择距离最短且空闲的电梯
IF #distance[1] <= #distance[2] AND #distance[1] <= #distance[3] THEN
#selectedElevator := 1;
ELSIF #distance[2] <= #distance[3] THEN
#selectedElevator := 2;
ELSE
#selectedElevator := 3;
END_IF;
实际项目得考虑运行方向、满载判断这些,但核心思路就是动态计算最优解。
WinCC画面设计别整太花哨,重点在状态可视化。电梯井道动画用多层矩形叠加,颜色绑定PLC变量:
//电梯位置显示脚本
if(GetTagBit("Elevator1_Moving")){
SetBackColor(0, 255, 0); //运行中亮绿色
} else {
SetBackColor(150, 150, 150); //静止灰色
}
按钮组态注意楼层编号和电梯编号的绑定关系,建议用面板实例化省得重复劳动。
调试阶段最常遇到的坑——方向锁死。比如电梯在4楼向上运行时要能响应更高楼层的下行呼叫,但不响应低楼层的上行呼叫。这个判断逻辑得写在移动状态的处理分支里:
IF #elevatorState = MOVING_UP THEN
FOR i := #currentFloor TO 10 DO
IF #callQueue[i].active THEN
//响应同方向呼叫
#targetFloor := i;
BREAK;
END_IF;
END_FOR;
END_IF;
最后提醒下版本问题,V14开始支持ProDiag功能,可以用来做电梯故障预测。但老项目升级记得检查指令兼容性,特别是运动控制相关的FB块容易报错。代码别直接照搬,理解处理逻辑自己重写更靠谱。
西门子1200博途三部十层电梯程序案例,加Wincc RT Professional画面三部十层电梯程序,版本V14及以上。
程序仅限于参考资料使用。





被折叠的 条评论
为什么被折叠?



