1. 项目背景与核心需求
去年参与某食品厂污水处理系统改造时,我们选用了西门子S7-1215C PLC搭配KTP1200触摸屏作为控制核心。这个日均处理量800吨的污水处理站,需要实现液位连锁控制、双泵交替运行、变频调速等典型工业控制功能。现场环境潮湿且存在电磁干扰,这对PLC系统的稳定性和抗干扰能力提出了严苛要求。
项目中最关键的三个技术难点在于:
- 模拟量信号(如液位、流量)的精确采集与处理
- 通过Modbus RTU协议实现变频器群控
- 设备运行数据的长期可靠记录
2. 硬件配置与信号处理
2.1 硬件组态方案
采用SM1231模拟量输入模块(8通道)采集液位、流量信号,搭配WAGO 857系列信号隔离器。数字量输出模块选用SM1222继电器型,通过OMRON MY2N中间继电器驱动现场设备。特别要注意的是:
- 模拟量输入通道必须配置1:1隔离器
- 继电器线圈需并联续流二极管
- 动力线(变频器输出)与信号线分槽敷设
2.2 模拟量处理技巧
在博途V17中建立通用量程转换函数块:
FUNCTION "SCALE_Custom" : REAL VAR_INPUT RAW : INT; RAW_MIN : INT := 0; RAW_MAX : INT := 27648; ENG_MIN : REAL := 0.0; ENG_MAX : REAL := 100.0; END_VAR VAR_TEMP Ratio : REAL; END_VAR BEGIN Ratio := (RAW - RAW_MIN) / (RAW_MAX - RAW_MIN); "SCALE_Custom" := ENG_MIN + (ENG_MAX - ENG_MIN) * Ratio; END_FUNCTION实际调试中发现三个关键点:
- 4-20mA信号在断线时会低于4mA,需在程序里做断线检测
- 压力变送器量程0-0.6MPa时,MAX参数要设为0(对应27648)
- 触摸屏上应保留量程修正系数(如0.95-1.05)
3. 设备控制逻辑实现
3.1 双泵交替运行策略
在OB35循环中断组织块(100ms周期)中实现运行时间累计:
// 在DB中定义运行时间累计变量 #MainPump_Runtime := #MainPump_Runtime + T#100MS; #StandbyPump_Runtime := #StandbyPump_Runtime + T#100MS; // 切换条件判断 IF #MainPump_Runtime - #StandbyPump_Runtime > "Switch_Threshold" THEN #ActivePump := 2; #StandbyPump_Runtime := 0; "Alarm_Log"(EventID := 16#1001, Message := '主备泵切换'); END_IF现场操作建议:
- 切换阈值设为8-12小时为宜
- 触摸屏上增加手动强制切换按钮
- 每次切换后应复位另一台泵的运行计时
3.2 变频器Modbus控制
建立Modbus主站通讯DB块,包含以下关键字段:
- 通讯状态字(0=正常 1=超时 2=校验错误)
- 重试计数器
- 频率给定值(0.0-50.0Hz)
- 运行状态反馈
在OB1主循环中调用MB_MASTER指令:
// 变频器1控制 IF "MB1_Req" THEN "MB_MASTER"( REQ := TRUE, MB_ADDR := 1, // 站地址 MODE := 1, // 写入模式 DATA_ADDR := 40001, // 频率给定寄存器 DATA_LEN := 1, DATA_PTR := @"DB_Modbus".Frequency_Set); IF "MB_MASTER".DONE THEN "MB1_Req" := FALSE; ELSIF "MB_MASTER".ERROR THEN "DB_Modbus".Retry_Counter := "DB_Modbus".Retry_Counter + 1; END_IF; END_IF4. 系统可靠性设计
4.1 通讯故障处理
在DB中建立通讯状态机:
TYPE Comm_State : (IDLE, ACTIVE, RETRY, FAULT); END_TYPE // 通讯恢复逻辑 IF "DB_Modbus".State = FAULT AND "Auto_Recovery" THEN IF "Reset_Timer".Q THEN "DB_Modbus".State := IDLE; "DB_Modbus".Retry_Counter := 0; END_IF; END_IF配套措施:
- 变频器参数P2140设为1(通讯超时自由停车)
- 触摸屏显示最后一次错误代码
- 自动恢复尝试间隔设为5分钟
4.2 报警事件记录
采用循环缓冲方式存储报警事件:
// 报警记录数据结构 TYPE Alarm_Record : STRUCT TimeStamp : DT; EventID : WORD; Param1 : REAL; Param2 : REAL; END_STRUCT END_TYPE // 在DB中定义100条记录的数组 "Alarm_Buffer" : ARRAY[1..100] OF Alarm_Record; "Alarm_Index" : INT := 0; // 记录函数 FUNCTION "Log_Alarm" : VOID VAR_INPUT Event : WORD; Value1 : REAL; Value2 : REAL; END_VAR BEGIN "Alarm_Index" := "Alarm_Index" + 1; IF "Alarm_Index" > 100 THEN "Alarm_Index" := 1; END_IF; "Alarm_Buffer"["Alarm_Index"].TimeStamp := "LOCAL_TIME"; "Alarm_Buffer"["Alarm_Index"].EventID := Event; "Alarm_Buffer"["Alarm_Index"].Param1 := Value1; "Alarm_Buffer"["Alarm_Index"].Param2 := Value2; END_FUNCTION5. 触摸屏人机界面设计
KTP1200基本屏配置要点:
- 建立与PLC的HMI连接时,循环周期设为500ms
- 报警视图绑定到报警DB的数组变量
- 关键参数设置界面增加权限控制(分操作员、工程师两级)
- 趋势图采样间隔建议设为10秒
特别实用的两个功能实现:
- 设备运行统计:通过屏脚本计算每日/每周运行率
Dim totalTime, runTime totalTime = 24 * 60 * 60 ' 24小时秒数 runTime = SmartTags("Pump1_RunSec") + SmartTags("Pump2_RunSec") SmartTags("Operation_Rate") = (runTime / totalTime) * 100- 数据导出:通过CSV文件记录关键参数
// 导出按钮脚本 Dim fso, file Set fso = CreateObject("Scripting.FileSystemObject") Set file = fso.CreateTextFile("\Storage Card\DataLog.csv", True) file.WriteLine "Time,Level,Flow,Frequency" file.WriteLine FormatDateTime(Now) & "," & SmartTags("Tank_Level") & "," & SmartTags("Inlet_Flow") & "," & SmartTags("Freq_Set") file.Close6. 现场调试经验总结
接地问题:曾遇到Modbus通讯随机中断,最终发现是PLC与变频器接地电位差超过1V。解决方案:
- 所有设备共接同一接地极
- 通讯线屏蔽层单端接地(PLC侧)
- 增加RS485隔离器(推荐ADM2483芯片方案)
信号干扰:液位计信号受变频器干扰出现跳变,采取的措施:
- 信号线改用双绞屏蔽电缆
- 在AI模块输入端并联0.1μF电容
- 软件增加移动平均滤波(采样8次取平均)
程序优化:原OB1循环周期波动大(15-50ms),通过以下调整稳定在20ms:
- 将模拟量处理移到OB35(100ms周期)
- Modbus通讯改用状态机控制
- 报警记录改为异步处理
这个项目让我深刻体会到,工业现场的程序设计必须考虑:
- 至少20%的冗余处理能力
- 关键参数的可调性(通过HMI)
- 异常情况的自动恢复能力
- 操作人员的思维习惯(如报警文本要通俗)