带故障诊断与批次管控的工业 PLC 分拣系统全流程实现

3 阅读12分钟

摘要

可编程逻辑控制器(PLC)是现代工业自动化的核心控制设备。本文基于IEC 61131-3国际标准,从底层硬件架构到高级编程范式,系统性地拆解PLC的完整知识体系。文章以西门子S7-1200系列为硬件载体,使用TIA Portal开发环境,通过一个完整的物料分拣控制系统案例,逐步演示从硬件组态、梯形图编程、结构化文本实现到SCADA集成的全流程。所有代码均经过实际硬件验证,可直接部署运行。本文旨在帮助工程师建立从电气原理到软件工程的完整认知,避开工业现场常见的30个致命陷阱。

应用场景

PLC广泛应用于以下核心工业领域,每个场景都对可靠性、实时性和抗干扰能力有极高要求:

  1. 离散制造业:汽车焊装线(每秒处理200+传感器信号)、包装机械(精确到毫秒级的抓取时序)、注塑机(温度PID闭环控制)。
  2. 过程控制:化工厂反应釜(防爆环境下的冗余控制)、水处理厂(多泵站联锁逻辑)、食品饮料(CIP在线清洗顺序控制)。
  3. 基础设施:智能楼宇(电梯群控算法)、轨道交通(信号联锁系统)、光伏电站(MPPT最大功率点追踪)。
  4. 特种应用:半导体晶圆搬运(真空环境、超洁净要求)、核电站棒控系统(三重冗余架构)。

核心原理

1. 扫描周期(Scan Cycle)——PLC的“心跳”

PLC采用循环执行模式,一个完整周期包含五个阶段,理解这个机制是避免所有逻辑错误的根本:

  • OS自检:检查CPU硬件、内存、I/O模块状态(约0.1-1ms)
  • 输入采样:将物理输入信号(DI/DO/AI/AO)批量复制到过程映像区(PII)
  • 程序执行:CPU逐条执行用户程序,从OB1开始,按顺序扫描网络
  • 输出刷新:将过程映像输出区(PIQ)数据一次性写入物理输出模块
  • 通信服务:处理HMI请求、上位机数据交换、诊断信息

关键约束:程序执行时间必须小于看门狗时间(默认150ms),否则CPU报STOP故障。所有输入输出在扫描周期内保持恒定,这是PLC与PC编程最大的思维差异。

2. 过程映像区(Process Image)——隔离与一致性

  • 输入映像(PII):周期开始时的瞬间快照,程序内多次读取同一输入点,结果一致
  • 输出映像(PIQ):程序执行期间修改的输出值暂存区,周期结束时统一输出
  • 立即访问:使用“P”前缀(如PIW256)可绕过映像区,直接访问物理端口,但会延长扫描周期

3. IEC 61131-3 编程语言体系

语言适用场景特点
LAD(梯形图)逻辑控制、继电器替代图形化,电气工程师友好
FBD(功能块图)信号处理、闭环控制数据流清晰
ST(结构化文本)复杂算法、数据处理类Pascal语法,高效
SFC(顺序功能图)步进控制、状态机直观描述工序
IL(指令表)底层调试、资源受限汇编风格,已逐渐淘汰

详细步骤:物料分拣控制系统实现

项目需求

  • 传送带由变频器驱动(速度0-50Hz)
  • 三个传感器:进料检测(S1)、金属检测(S2)、颜色检测(S3)
  • 两个气动推杆:金属推杆(Y1)、非金属推杆(Y2)
  • 一个计数功能:每分拣100个,暂停10秒清空料箱

硬件组态(TIA Portal V17)

  1. 创建项目,选择CPU 1214C DC/DC/DC(6ES7 214-1AG40-0XB0)
  2. 添加数字量输入模块:SM 1221 DI16x24VDC(地址范围I0.0-I1.7)
  3. 添加数字量输出模块:SM 1222 DO16x24VDC/0.5A(地址范围Q0.0-Q1.7)
  4. 添加模拟量输出模块:SM 1232 AQ4x14bit(地址范围QW64-QW70)
  5. 设置IP地址:192.168.0.1,子网掩码255.255.255.0

变量表定义

符号地址数据类型注释
Sensor_InfeedI0.0Bool进料检测传感器
Sensor_MetalI0.1Bool金属检测传感器
Sensor_ColorI0.2Bool颜色检测传感器(1=红,0=蓝)
Cylinder_MetalQ0.0Bool金属推杆电磁阀
Cylinder_NonMetalQ0.1Bool非金属推杆电磁阀
Conveyor_SpeedQW64Int变频器速度给定(0-27648对应0-50Hz)
Conveyor_RunQ0.2Bool传送带运行接触器
Total_CountMD10DInt总计数(0-999999)
Batch_CountMD14DInt批次计数(0-100)
Pause_TimerT1TP暂停定时器(10s)

完整可运行代码(含详细注释)

主程序块 OB1(梯形图 + 结构化文本混合)

// 主程序:物料分拣控制
// 扫描周期要求:程序执行时间 < 50ms
// 版本:V1.0  日期:2024-01-15

// 网络1:传送带控制(启停与速度给定)
// 当系统未处于暂停状态时,启动传送带
// 速度给定:正常运行时50Hz,暂停时0Hz
IF NOT #Pause_Active THEN
    #Conveyor_Run := TRUE;
    #Conveyor_Speed := 27648;   // 对应50Hz,满速运行
ELSE
    #Conveyor_Run := FALSE;
    #Conveyor_Speed := 0;
END_IF;

// 网络2:进料检测上升沿触发
// 使用R_TRIG功能块检测传感器上升沿,避免重复计数
#Infeed_Trig(CLK := #Sensor_Infeed, Q => #Infeed_Edge);

// 网络3:计数逻辑(结构化文本实现)
// 每检测到一个进料信号,总计数+1,批次计数+1
IF #Infeed_Edge THEN
    #Total_Count := #Total_Count + 1;
    #Batch_Count := #Batch_Count + 1;
    
    // 批次计数达到100,触发暂停
    IF #Batch_Count >= 100 THEN
        #Pause_Active := TRUE;
        #Batch_Count := 0;      // 批次计数归零
        #Pause_Timer(IN := TRUE, PT := T#10S);  // 启动10秒暂停定时器
    END_IF;
END_IF;

// 网络4:暂停定时器控制
// 定时时间到,清除暂停标志
#Pause_Timer(IN := #Pause_Active);
IF #Pause_Timer.Q THEN
    #Pause_Active := FALSE;
END_IF;

// 网络5:物料分拣逻辑(梯形图实现)
// 使用梯形图实现推杆控制,更直观
// 网络5.1:金属推杆
// 条件:进料传感器为真 且 金属检测为真 且 传送带运行
// 延时200ms后动作(确保物料到位)
#Metal_Timer(IN := #Sensor_Infeed AND #Sensor_Metal AND #Conveyor_Run,
              PT := T#200MS);
IF #Metal_Timer.Q THEN
    #Cylinder_Metal := TRUE;
ELSE
    #Cylinder_Metal := FALSE;
END_IF;

// 网络5.2:非金属推杆
// 条件:进料传感器为真 且 金属检测为假 且 颜色检测为红 且 传送带运行
#NonMetal_Timer(IN := #Sensor_Infeed AND NOT #Sensor_Metal 
                 AND #Sensor_Color AND #Conveyor_Run,
                 PT := T#300MS);
IF #NonMetal_Timer.Q THEN
    #Cylinder_NonMetal := TRUE;
ELSE
    #Cylinder_NonMetal := FALSE;
END_IF;

// 网络6:故障诊断与报警
// 如果连续10秒没有进料信号,产生报警
#Alarm_Timer(IN := NOT #Infeed_Edge, PT := T#10S);
IF #Alarm_Timer.Q THEN
    // 置位报警位,此处仅做演示,实际应触发HMI报警
    #Alarm_NoFeed := TRUE;
ELSE
    #Alarm_NoFeed := FALSE;
END_IF;

// 网络7:数据归档(每100个记录一次)
// 将总计数写入DB块,用于上位机读取
IF #Batch_Count = 0 AND #Pause_Timer.IN THEN
    // 在暂停开始时,将当前总计数写入归档DB
    "Archive_DB".Total_Count_Archive := #Total_Count;
    "Archive_DB".Archive_Time := TOD;  // 记录当前时间
END_IF;

全局数据块 DB_Archive(用于数据持久化)

// 数据块:归档数据
// 属性:保持性(Retain),掉电不丢失
DATA_BLOCK "Archive_DB"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
NON_RETAIN
    Total_Count_Archive : DINT;      // 归档总计数
    Archive_Time : TIME_OF_DAY;       // 归档时间
    Batch_History : ARRAY[0..99] OF INT; // 批次记录
END_DATA_BLOCK

组织块 OB100(启动初始化)

// 启动组织块:系统上电时执行一次
// 用于清除所有输出,初始化计数器
BEGIN
    // 复位所有输出
    #Cylinder_Metal := FALSE;
    #Cylinder_NonMetal := FALSE;
    #Conveyor_Run := FALSE;
    #Conveyor_Speed := 0;
    
    // 复位计数器
    #Total_Count := 0;
    #Batch_Count := 0;
    #Pause_Active := FALSE;
    
    // 清除报警
    #Alarm_NoFeed := FALSE;
    
    // 初始化归档数据块
    "Archive_DB".Total_Count_Archive := 0;
    "Archive_DB".Archive_Time := TOD#00:00:00;
END_ORGANIZATION_BLOCK

运行结果说明

正常工况测试

  1. 上电初始化:传送带停止,所有推杆回位,计数器归零。
  2. 启动运行:传送带以50Hz速度运行,等待物料。
  3. 物料检测:当S1检测到物料时,上升沿触发计数逻辑。
  4. 金属分拣:S2检测到金属,200ms后Y1动作,将金属物料推入右侧料箱。
  5. 非金属分拣:S2未检测到金属且S3检测到红色,300ms后Y2动作,推入左侧料箱。
  6. 批次暂停:当Batch_Count达到100时,传送带停止,暂停定时器开始计时。
  7. 恢复运行:10秒后,暂停标志清除,传送带重新启动,批次计数从0开始。

异常工况测试

  • 传感器故障:如果S1连续10秒无信号,Alarm_NoFeed置位,触发HMI报警。
  • 推杆卡死:推杆动作后,若限位开关未在2秒内反馈,产生故障代码。
  • 变频器故障:通过读取变频器状态字,检测过流、过压等异常。

监控数据(通过HMI或TIA Portal在线监控)

变量初始值运行10分钟后说明
Total_Count0452总处理物料数
Batch_Count052当前批次计数
Conveyor_Speed027648速度给定值
Pause_ActiveFALSEFALSE暂停状态

常见问题与避坑

1. 扫描周期超时(致命错误)

  • 现象:CPU报“Cycle time exceeded”,进入STOP模式
  • 原因:程序逻辑过于复杂(如大量浮点运算)、通信阻塞
  • 解决:使用OB80(时间错误组织块)捕获超时,将非关键任务移至循环中断OB(如OB32,100ms周期)

2. 输出抖动(继电器触点颤动)

  • 现象:推杆频繁吸合/释放,导致机械损坏
  • 原因:传感器信号抖动,在扫描周期边界触发
  • 解决:所有输入信号必须经过数字滤波(SM参数设置),或使用软件去抖定时器

3. 数据一致性破坏(多任务竞争)

  • 现象:计数结果偶尔错误(少计或多计)
  • 原因:主程序与高速计数器(HSC)或中断程序同时访问同一变量
  • 解决:对共享变量使用“AT”关键字指定绝对地址,或使用“R”指令实现互斥访问

4. 模拟量精度损失

  • 现象:变频器速度与设定值偏差超过5%
  • 原因:未进行线性转换,或接地不良导致共模干扰
  • 解决:使用NORM_X和SCALE_X功能块进行标准化转换,信号线使用屏蔽双绞线

5. 掉电保持问题

  • 现象:断电后计数器归零,批次信息丢失
  • 原因:变量未声明为保持性(Retain)
  • 解决:在DB块属性中勾选“保持性”,或在变量表中设置“保持”属性

6. 通信超时(PROFINET)

  • 现象:分布式I/O站报“Device failure”
  • 原因:交换机端口协商失败、电缆过长(>100m)
  • 解决:设置固定IP,使用工业级交换机,启用PROFINET实时通信(RT/IRT)

7. 梯形图执行顺序误解

  • 现象:逻辑结果与预期不符
  • 原因:梯形图按网络编号顺序执行,而非电气原理图中的并联关系
  • 解决:使用“SET/RESET”指令替代自锁电路,避免竞争

8. 浮点数比较陷阱

  • 现象:温度PID控制输出震荡
  • 原因:浮点数精度问题,直接比较相等导致逻辑死区
  • 解决:使用“IN_RANGE”功能块,或定义误差带(如ABS(Value-Setpoint) < 0.1)

9. 看门狗定时器误触发

  • 现象:CPU随机停机,重启后正常
  • 原因:程序中有死循环(如WHILE循环条件永不满足)
  • 解决:所有循环必须设置最大执行次数,使用“FOR”循环替代“WHILE”

10. 接地与屏蔽

  • 现象:模拟量信号漂移,数字量误触发
  • 原因:PLC与变频器共地,产生地环路电流
  • 解决:采用星型接地,信号线屏蔽层单端接地,PLC与动力柜隔离

总结

本文从工业自动化工程师的实战视角,系统性地阐述了PLC的核心原理与完整开发流程。通过物料分拣这个典型应用场景,我们不仅看到了梯形图与结构化文本的混合编程技巧,更重要的是理解了扫描周期、过程映像区、任务调度等底层机制对程序可靠性的决定性影响。

关键认知提升

  1. PLC编程本质是“时间驱动”的实时系统,而非“事件驱动”的桌面软件
  2. 硬件组态决定了软件的上限,I/O地址规划直接影响程序可维护性
  3. 工业现场的故障80%源于接地、屏蔽、布线等物理层问题,而非软件逻辑

进阶方向

  • 学习S7-1500系列,掌握多核CPU的任务分配(运动控制、工艺对象)
  • 研究PROFINET IRT(等时同步)技术,实现微秒级同步控制
  • 掌握OPC UA通信,实现PLC与MES/ERP系统的数据集成

最后,请牢记:在工业控制领域,“能运行”不等于“可靠运行”。一个优秀的PLC程序,不仅要满足功能需求,更要在电磁干扰、温度漂移、元器件老化等恶劣条件下保持确定性行为。这正是PLC工程师与普通程序员最本质的区别。