1. 项目概述与背景
作为一名在工业自动化领域摸爬滚打多年的工程师,我最近用西门子TIA Portal V16(博图)完成了一个单部八层电梯的PLC控制项目。这个项目不仅实现了电梯基础控制逻辑,还整合了WinCC可视化界面,使用S7-1200 PLC作为控制核心。在实际操作中,我发现电梯控制程序的编写远比想象中复杂,需要考虑各种异常情况和优先级处理。今天我就把这个项目的完整开发过程拆解给大家,特别是那些在教科书上找不到的实战经验。
电梯控制系统本质上是一个典型的状态机,需要处理楼层呼叫、轿厢内选层、运行方向判断、开关门控制等多个并行事件。与简单的流水线控制不同,电梯系统对实时性和安全性要求极高——比如在电梯门未完全关闭时绝对不能启动电机,这就是我们在程序中必须严格遵守的安全联锁逻辑。
2. 硬件配置与软件环境
2.1 硬件选型解析
选择S7-1214C DC/DC/DC型号PLC主要基于以下考量:
- 数字量输入需求:8个楼层的外呼按钮(上下行分开需16点)+8个轿厢内选层按钮=24点输入
- 数字量输出需求:电机正反转控制2点+门机开关2点+楼层指示灯8点=12点输出
- 实际配置了SM1223 16DI/16DO扩展模块,预留了20%的I/O余量
特别提示:实际项目中务必考虑按钮的硬件防抖,我在初期测试时就遇到过因机械按钮抖动导致的误触发问题。解决方法是在PLC程序里添加20ms的软件防抖延时。
2.2 软件环境搭建
TIA Portal V16的安装有几个关键注意事项:
- 必须关闭所有杀毒软件,特别是实时防护功能
- 安装路径不要包含中文或特殊字符
- 建议单独安装WinCC Runtime组件以便本地测试
- 安装完成后务必运行"Totally Integrated Automation Portal"而非单独的STEP7或WinCC
我推荐使用Windows 10 Enterprise LTSC 2019作为开发环境,这个版本系统干净稳定,不会因系统更新导致博图软件异常。
3. PLC程序架构设计
3.1 变量定义规范
在OB1主程序中,我采用了结构化变量定义方式:
pascal复制// 输入变量区
"HW_Inputs"
{
"CallButtons" : Array[1..8] of Bool; // 外呼按钮,1-8层
"CarButtons" : Array[1..8] of Bool; // 轿厢内选层按钮
"DoorClosedLS" : Bool; // 门全关限位
"DoorOpenLS" : Bool; // 门全开限位
"Overload" : Bool; // 超载信号
}
// 输出变量区
"HW_Outputs"
{
"MotorUp" : Bool; // 上行接触器
"MotorDown" : Bool; // 下行接触器
"DoorOpen" : Bool; // 开门命令
"DoorClose" : Bool; // 关门命令
"FloorIndicators" : Array[1..8] of Bool;// 楼层指示灯
}
// 内部变量区
"InternalVars"
{
"CurrentFloor" : Int; // 当前楼层(1-8)
"TargetFloors" : Array[1..8] of Bool; // 目标楼层寄存器
"MovingDirection" : Int; // 0-停止 1-上行 2-下行
"DoorState" : Int; // 0-关闭 1-打开 2-运动中
}
这种结构化定义方式比传统的绝对地址访问更易维护,特别是在大型项目中优势明显。变量名前缀HW表示硬件直接关联变量,便于区分。
3.2 核心控制逻辑实现
3.2.1 楼层呼叫处理
采用"扫描-注册-清除"三步处理机制:
pascal复制// 扫描所有呼叫按钮
FOR #i := 1 TO 8 DO
// 外呼按钮上升沿触发
IF "HW_Inputs".CallButtons[#i] AND NOT "InternalVars".CallReg[#i] THEN
"InternalVars".CallReg[#i] := TRUE; // 注册呼叫
"InternalVars".TargetFloors[#i] := TRUE;
END_IF;
// 轿厢内选层按钮
IF "HW_Inputs".CarButtons[#i] THEN
"InternalVars".TargetFloors[#i] := TRUE;
END_IF;
END_FOR;
3.2.2 运行方向决策算法
这是电梯控制的核心算法,我采用了"同向优先"策略:
pascal复制CASE "InternalVars".MovingDirection OF
0: // 停止状态
// 查找最近的目标楼层
#UpDist := 9; #DownDist := 9;
FOR #i := 1 TO 8 DO
IF "InternalVars".TargetFloors[#i] THEN
IF #i > "InternalVars".CurrentFloor THEN
#UpDist := MIN(#UpDist, #i - "InternalVars".CurrentFloor);
ELSIF #i < "InternalVars".CurrentFloor THEN
#DownDist := MIN(#DownDist, "InternalVars".CurrentFloor - #i);
END_IF;
END_IF;
END_FOR;
// 决策运行方向
IF #UpDist < #DownDist THEN
"InternalVars".MovingDirection := 1;
ELSIF #DownDist < #UpDist THEN
"InternalVars".MovingDirection := 2;
END_IF;
1: // 上行状态
// 检查上方是否还有目标
#HasTargetAbove := FALSE;
FOR #i := "InternalVars".CurrentFloor + 1 TO 8 DO
#HasTargetAbove := #HasTargetAbove OR "InternalVars".TargetFloors[#i];
END_FOR;
IF NOT #HasTargetAbove THEN
"InternalVars".MovingDirection := 0;
END_IF;
2: // 下行状态
// 检查下方是否还有目标
#HasTargetBelow := FALSE;
FOR #i := 1 TO "InternalVars".CurrentFloor - 1 DO
#HasTargetBelow := #HasTargetBelow OR "InternalVars".TargetFloors[#i];
END_FOR;
IF NOT #HasTargetBelow THEN
"InternalVars".MovingDirection := 0;
END_IF;
END_CASE;
4. WinCC人机界面开发
4.1 画面布局设计
采用分层设计理念:
- 背景层:电梯井道静态示意图
- 动态元素层:
- 轿厢位置指示器
- 门状态动画
- 内外呼叫指示灯
- 操作层:
- 外呼按钮面板
- 轿厢内操作面板
我特别添加了"急停按钮"和"维护模式开关"这两个安全相关控件,它们直接关联PLC的硬件中断输入点。
4.2 关键动画实现技巧
轿厢移动动画采用"画面窗口+变量绑定"的方式:
-
创建包含轿厢图形的画面窗口
-
设置窗口的Y坐标属性绑定到PLC变量:
pascal复制Y = 720 - ("CurrentFloor" * 80) + ("PositionOffset" / 10.0)其中PositionOffset是用于平滑移动的中间变量
-
在PLC中编写移动插补算法:
pascal复制IF "MotorUp" THEN "PositionOffset" := "PositionOffset" + 1; IF "PositionOffset" >= 10 THEN "CurrentFloor" := "CurrentFloor" + 1; "PositionOffset" := 0; END_IF; ELSIF "MotorDown" THEN "PositionOffset" := "PositionOffset" - 1; IF "PositionOffset" <= -10 THEN "CurrentFloor" := "CurrentFloor" - 1; "PositionOffset" := 0; END_IF; END_IF;
5. 仿真调试与问题排查
5.1 PLCSIM Advanced使用技巧
在调试过程中,我发现几个实用技巧:
- 使用"强制表"功能模拟按钮输入,比手动点击更高效
- 创建"楼层位置监视"窗口,实时查看CurrentFloor变量
- 启用"轨迹记录"功能,回放异常时的变量变化过程
5.2 典型问题解决方案
问题1:电梯在目标楼层不停车
现象:电梯经过目标楼层时未停止
排查:
- 检查楼层位置传感器信号是否正常
- 验证TargetFloors数组对应位是否置位
- 确认MovingDirection与CurrentFloor的逻辑关系
解决:发现是楼层位置传感器信号抖动,添加了50ms的滤波时间
问题2:门反复开关无法闭合
现象:门开启后刚要闭合又立即打开
排查:
- 检查门机力矩参数是否设置过小
- 查看光幕信号是否误触发
- 确认DoorState状态机转换条件
解决:实际是WinCC画面中门状态动画与PLC程序不同步导致
6. 安全功能实现细节
6.1 安全联锁逻辑
在OB35循环中断组织块中实现关键安全检测:
pascal复制// 急停按钮优先级最高
IF "EmergencyStop" THEN
"MotorUp" := FALSE;
"MotorDown" := FALSE;
"DoorOpen" := TRUE; // 紧急情况下开门
RETURN; // 跳过后续所有逻辑
END_IF;
// 门锁联锁
IF NOT "DoorClosedLS" AND ("MotorUp" OR "MotorDown") THEN
"MotorUp" := FALSE;
"MotorDown" := FALSE;
"Alarm" := TRUE;
END_IF;
// 超载保护
IF "Overload" AND "DoorState" = 0 THEN
"DoorOpen" := TRUE;
END_IF;
6.2 故障自诊断系统
建立故障代码体系:
- 0x01:门异常(超过10秒未完成开关动作)
- 0x02:电机堵转(位置10秒无变化)
- 0x04:通信超时(与变频器)
- 0x08:电源异常
在DB中创建故障历史记录区,采用FIFO方式保存最近10条故障记录。
7. 性能优化实践
7.1 扫描周期优化
通过以下措施将主循环周期从15ms降低到8ms:
- 将模拟量处理移到OB30(100ms周期)
- 使用"间接寻址"替代数组遍历
- 禁用非必要的诊断功能
7.2 内存优化技巧
- 将不频繁变化的变量移到单独的DB中并设置"仅存储"属性
- 使用"优化块访问"方式编译FB块
- 对大型数组启用"压缩"属性
8. 项目总结与扩展建议
经过两周的开发和调试,这个八层电梯控制系统已经稳定运行。实测数据显示:
- 平均响应时间:<1.5秒
- 定位精度:±5mm
- 故障率:<0.1次/周
几个值得分享的经验:
- 在编写复杂逻辑时,先画出完整的状态转换图再编码
- WinCC画面更新频率不要超过10Hz,否则会导致通信负载过高
- 重要安全信号建议采用硬件接线而非通信传输
这个系统还可以进一步扩展:
- 增加群控功能实现多梯协同
- 集成能源监测模块记录能耗数据
- 添加远程监控接口支持手机APP查看状态
在实际部署时,建议先用PLCSIM Advanced进行72小时连续压力测试,模拟各种异常操作场景。我在测试阶段就通过这种方法发现了3个潜在问题,提前规避了现场故障风险。