1. 项目概述
最近在车间折腾老式洗衣机的自动化改造项目,选用了西门子S7-1200 PLC作为主控制器,搭配博图V15.1开发环境。这个看似简单的洗衣机控制系统,在实际调试过程中遇到了不少时序控制方面的挑战。本文将详细分享整个控制系统的设计思路、实现细节以及调试过程中积累的实战经验。
洗衣机控制系统主要实现以下功能流程:
- 启动后自动进水至高水位
- 正转洗涤15秒后暂停3秒
- 反转洗涤15秒后暂停3秒
- 重复正反转洗涤3次后开始排水
- 水位降至低位时开始脱水
- 完成3次大循环后触发报警
- 支持手动排水和紧急停止功能
2. 硬件选型与配置
2.1 PLC选型考虑
选择西门子S7-1200系列PLC主要基于以下几个因素:
- 性价比高,适合中小型自动化项目
- 集成PROFINET接口,便于后期扩展
- 支持博图(TIA Portal)开发环境,编程方便
- 具备足够的I/O点数满足洗衣机控制需求
具体型号选用的是1214C DC/DC/DC,主要配置如下:
- 14点数字量输入
- 10点数字量输出
- 2路模拟量输入(用于水位检测)
- 工作内存75KB
2.2 外围设备连接
洗衣机控制系统需要连接以下主要设备:
- 进水电磁阀(数字量输出控制)
- 排水电磁阀(数字量输出控制)
- 洗涤电机正反转接触器(两个数字量输出)
- 脱水电机接触器(数字量输出)
- 水位传感器(模拟量输入)
- 操作面板按钮(启动、停止、手动排水等)
特别注意电机控制部分需要使用中间继电器进行隔离,避免PLC输出点直接驱动大功率负载。
3. 软件设计与实现
3.1 变量定义与数据块
首先在DB块中定义洗衣机控制所需的全局变量:
pascal复制// 洗衣机控制变量
"Cycle_Counter" : INT; // 大循环计数(0-3)
"Wash_Count" : INT; // 正反转次数计数(0-3)
"High_Water" : BOOL; // 高水位信号
"Low_Water" : BOOL; // 低水位信号
"Manual_Drain" : BOOL; // 手动排水按钮信号
"Start_Button" : BOOL; // 启动按钮信号
"Stop_Button" : BOOL; // 停止按钮信号
3.2 主程序状态机设计
采用状态机架构实现洗衣机工作流程,主要状态包括:
- 待机状态
- 进水状态
- 正转洗涤状态
- 暂停状态
- 反转洗涤状态
- 排水状态
- 脱水状态
- 报警状态
每个状态之间的转换条件通过PLC程序实现,使用梯形图编程。
3.3 关键控制逻辑实现
3.3.1 进水控制
进水控制逻辑需要考虑防震荡问题,采用带滞环的模拟量检测:
pascal复制// 进水控制逻辑
IF NOT "Start_Button" AND "Inlet_Valve" THEN
"Inlet_Valve" := 0; // 停止条件
ELSIF "High_Water" = 0 AND "Drain_Valve" = 0 THEN
"Inlet_Valve" := 1; // 开启进水
END_IF;
3.3.2 洗涤控制
正反转洗涤使用定时器控制,注意使用TP脉冲定时器防止多次触发:
pascal复制// 正转洗涤定时
"Forward_Timer"(IN:= "Wash_Forward", PT:=T#15S);
IF "Forward_Timer".Q THEN
"Wash_Forward" := 0;
"Pause_Timer1".IN := 1; // 触发暂停
END_IF;
// 反转洗涤定时
"Reverse_Timer"(IN:= "Wash_Reverse", PT:=T#15S);
IF "Reverse_Timer".Q THEN
"Wash_Reverse" := 0;
"Pause_Timer2".IN := 1; // 触发暂停
END_IF;
3.3.3 循环次数控制
在每次反转洗涤结束时自增计数器,并判断是否达到3次:
pascal复制// 洗涤次数统计
IF "Reverse_Timer".Q THEN
"Wash_Count" := "Wash_Count" + 1;
IF "Wash_Count" < 3 THEN
// 跳转回正转逻辑
"Wash_Forward" := 1;
ELSE
// 触发排水
"Drain_Valve" := 1;
"Wash_Count" := 0; // 重置计数器
"Cycle_Counter" := "Cycle_Counter" + 1; // 大循环计数
END_IF;
END_IF;
4. 特殊功能实现
4.1 手动排水功能
手动排水功能通过中断实现,优先级高于自动流程:
pascal复制// 手动排水中断处理
IF "Manual_Drain" THEN
"Drain_Valve" := 1;
"Inlet_Valve" := 0;
"Alarm" := 0;
// 复位所有洗涤状态
"Wash_Forward" := 0;
"Wash_Reverse" := 0;
END_IF;
4.2 脱水控制
脱水环节需要与排水阀联锁,使用低水位信号作为启动条件:
pascal复制// 脱水控制
IF "Drain_Valve" AND "Low_Water" THEN
"Spin_Motor" := 1;
"Spin_Timer".IN := 1;
END_IF;
// 脱水完成判断
IF "Spin_Timer".Q THEN
"Spin_Motor" := 0;
// 判断是否完成3次大循环
IF "Cycle_Counter" < 3 THEN
// 返回进水状态
"Inlet_Valve" := 1;
ELSE
// 触发报警
"Alarm" := 1;
END_IF;
END_IF;
4.3 报警处理
报警处理需要考虑停止按钮的优先级,在功能块中实现强制复位:
pascal复制// 报警处理块
IF "Stop_Button" THEN
"Alarm" := 0;
"Alarm_Timer".IN := 0;
// 复位所有输出
"Inlet_Valve" := 0;
"Drain_Valve" := 0;
"Wash_Forward" := 0;
"Wash_Reverse" := 0;
"Spin_Motor" := 0;
ELSIF "Cycle_Counter" >=3 THEN
"Alarm" := 1;
"Alarm_Timer"(IN:=1, PT:=T#10S);
IF "Alarm_Timer".Q THEN
"Alarm" := 0;
// 复位所有计数器和状态
"Cycle_Counter" := 0;
"Wash_Count" := 0;
END_IF;
END_IF;
5. 调试经验与问题解决
5.1 定时器精度问题
在初期调试中发现,博图V15.1的定时器实际精度与程序扫描周期相关。对于时间敏感的控制逻辑(如洗涤暂停的3秒间隔),单纯使用软件定时器可能导致动作不同步。
解决方案:
- 使用硬件中断OB30,设置10ms的周期检测
- 在中断组织块中处理关键时序控制
- 软件定时器仅用于非关键时序
5.2 水位检测防抖动
水位传感器信号容易受到水流波动影响,导致误动作。采取的解决措施包括:
- 在模拟量输入通道增加软件滤波
- 设置合理的滞环区间(如高水位±5%)
- 采用延时确认机制,避免瞬时波动触发动作
5.3 电机切换保护
正反转电机切换时需要注意:
- 正转停止后必须延时才能启动反转
- 使用互锁逻辑防止正反转同时接通
- 增加过载保护功能
实现代码示例:
pascal复制// 电机正反转互锁
"Wash_Forward" := NOT "Wash_Reverse" AND "Forward_CMD";
"Wash_Reverse" := NOT "Wash_Forward" AND "Reverse_CMD";
// 切换延时保护
"Forward_To_Reverse_Delay"(IN:=NOT "Wash_Forward", PT:=T#500MS);
"Reverse_To_Forward_Delay"(IN:=NOT "Wash_Reverse", PT:=T#500MS);
6. 项目优化建议
6.1 程序结构优化
- 将不同功能模块封装为独立的FB功能块
- 使用UDT(用户自定义数据类型)组织相关变量
- 增加详细的注释和变量说明
6.2 操作界面改进
- 增加触摸屏显示当前工作状态
- 提供洗涤参数设置功能(如洗涤时间、循环次数等)
- 增加故障诊断显示
6.3 扩展功能考虑
- 增加能耗监测功能
- 实现远程监控接口
- 添加洗涤程序选择功能
7. 关键代码总结
7.1 主程序结构
pascal复制// 主程序OB1
NETWORK 1: 进水控制
// 进水逻辑代码...
NETWORK 2: 洗涤控制
// 正反转控制代码...
NETWORK 3: 排水脱水控制
// 排水脱水逻辑...
NETWORK 4: 报警处理
// 报警控制代码...
7.2 中断程序示例
pascal复制// 循环中断OB30
// 每10ms执行一次
NETWORK 1: 更新系统时间
// 更新时间计数器...
NETWORK 2: 关键定时处理
// 精确的定时控制...
7.3 功能块调用
pascal复制// 调用电机控制功能块
"Motor_Control_FB"(
Forward_CMD := "Wash_Forward_CMD",
Reverse_CMD := "Wash_Reverse_CMD",
Forward_OUT => "Wash_Forward",
Reverse_OUT => "Wash_Reverse",
Fault => "Motor_Fault");
8. 项目文档建议
- 使用博图自带的交叉引用功能生成变量引用报告
- 为每个程序块添加详细的功能描述
- 记录所有I/O点的物理连接信息
- 保存完整的硬件配置文档
在实际项目中,我发现为每个电机控制变量添加详细注释特别重要。三个月后回看代码时,清晰的注释能快速帮助理解哪个输出点对应哪个阀门或电机。建议采用统一的命名规范,如:
- Q0.0: 进水电磁阀
- Q0.1: 排水电磁阀
- Q0.2: 正转接触器
- Q0.3: 反转接触器
调试过程中还发现,使用博图的"监控与强制表"功能可以大大提高调试效率,特别是在排查复杂逻辑问题时。建议在项目初期就建立完善的监控变量表,将关键状态变量和计数器都包含在内。