4、配方加载与切换:配方加载逻辑、配方切换策略、配方参数下发到PLC

好,咱们接着聊配方管理里最核心的环节——加载与切换。

说实话,很多新手工程师把配方管理想简单了。他们觉得,不就是把参数从文件读到内存,再写到PLC吗?

嗯,表面上看确实是这样。但实际项目里,坑全藏在细节里。我见过一个食品厂的项目,就因为切换配方时没处理好PLC的运行状态,整条产线停了20分钟。那场面,厂长脸都绿了。

今天我就把配方加载和切换的实战经验,掰开了揉碎了讲给你听。

4.1 配方加载逻辑

配方加载,说白了就是把存储介质里的配方数据,搬到Intouch的内存里,再准备下发到PLC。

我个人习惯把加载逻辑分成三步:

  1. 读取源数据:从SQL Server、CSV文件或者配方标签字典里读出来
  2. 数据校验:检查格式对不对、数值范围是否合法
  3. 暂存到中间变量:放在Intouch的内存标签里,等待下发指令

你想想看,如果直接把数据往PLC里怼,万一读到一半网络断了怎么办?所以中间变量这步,其实是个缓冲层,能挡住很多意外。

核心原则:加载和下发,必须分开。加载是加载,下发是下发,别混在一起做。

我在一个化工项目里遇到过这种情况:操作员点了加载配方,结果程序直接把参数写进了PLC。当时PLC正在执行一个关键的温度控制程序,参数一改,温度瞬间失控。还好有紧急停止按钮,不然真出大事了。

所以从那以后,我设计的配方加载逻辑里,永远有一个“确认下发”的按钮。加载只是把数据准备好,等操作员确认了,再真正下发。

4.2 配方切换策略

配方切换,不是简单的“把A配方换成B配方”。这里面有几个策略要考虑。

4.2.1 立即切换 vs 等待切换

我一般把切换策略分成两种:

策略类型 适用场景 风险点
立即切换 设备处于停止状态,或者参数修改不影响当前运行 如果设备正在运行,可能造成冲击
等待切换 设备正在运行,需要等到当前批次结束再切换 操作员可能忘记切换,导致下一批次用错配方

我个人更推荐“等待切换”策略。为什么呢?因为安全。

我曾经在一个制药项目里,操作员在反应釜搅拌阶段直接切换了配方。结果搅拌速度从200转瞬间跳到500转,物料飞溅出来。还好防护做得好,没人受伤。但那次事故之后,厂里规定所有配方切换必须等设备停止。

小技巧:在Intouch里做一个“切换状态指示灯”。绿色表示可以安全切换,红色表示设备正在运行,禁止切换。这个灯用PLC的一个状态位来控制,简单又可靠。

4.2.2 部分参数切换

有时候,你不需要切换整个配方。比如只改温度参数,其他保持不变。

嗯,这里要注意:部分切换容易出问题。因为操作员可能忘了哪些参数改了,哪些没改。我建议在界面上做一个“差异对比”功能,把新旧配方的不同参数高亮显示出来。

说白了,就是让操作员看得清清楚楚:你这次切换,到底动了哪些参数。

4.3 配方参数下发到PLC

这是最后一步,也是最关键的一步。参数下发到PLC,本质上就是Intouch往PLC的寄存器里写数据。

但这里有个坑:写数据的时序

PLC的寄存器不是一次性写完的。比如一个配方有20个参数,你一个一个写,PLC读到一半的时候,数据是不完整的。如果PLC在这个半中间状态触发了控制逻辑,那就乱套了。

怎么解决?我常用的方法有两种:

  1. 先写到一个临时区域:PLC里开辟一块临时寄存器,Intouch先把所有参数写进去。写完之后,给PLC一个“数据就绪”的脉冲信号。PLC收到信号后,一次性把临时区域的数据复制到工作区域。
  2. 使用数据块传输:如果PLC支持,直接用Modbus或Profibus的数据块功能,一次传输所有参数。这样能保证数据的完整性。

警告:千万不要在PLC运行时,直接往工作寄存器里写配方参数。一定要用“双缓冲”机制——先写缓冲区,再切换。

我记得有个项目,用的是西门子S7-1200。我设计了下发逻辑:Intouch写数据到DB块的“配方缓冲区”,然后置位一个“加载完成”位。PLC检测到这个位为True,就把缓冲区数据复制到“运行参数区”,然后复位“加载完成”位。整个过程不到100毫秒,但安全性提升了好几个档次。

4.4 实战代码示例

下面是一个Intouch脚本的示例,展示配方加载和下发的基本逻辑。这段代码我用了很多年,改过几版,现在算是比较成熟了。

// 配方加载脚本(点击“加载配方”按钮时触发)
// 假设配方数据已经存储在内存标签 Recipe_Temp_Array[0..19] 中

// 第一步:从SQL读取配方数据
SQLConnect(ConnectionId, "DSN=RecipeDB;UID=sa;PWD=123");
SQLSelect(ConnectionId, "SELECT * FROM Recipes WHERE RecipeName = 'Recipe_A'");
SQLFirst(ConnectionId);

// 第二步:将数据读入中间变量
FOR i = 0 TO 19
    Recipe_Temp_Array[i] = SQLGetField(ConnectionId, "Param" + Text(i));
END FOR;

SQLDisconnect(ConnectionId);

// 第三步:设置数据就绪标志
Recipe_Ready = 1;

// 注意:这里没有直接写PLC,而是等待操作员点击“确认下发”
// 配方下发脚本(点击“确认下发”按钮时触发)
// 前提:Recipe_Ready == 1,且PLC处于停止状态

IF PLC_Running == 0 THEN
    // 将中间变量写入PLC的缓冲区
    FOR i = 0 TO 19
        PLC_Buffer[i] = Recipe_Temp_Array[i];
    END FOR;
    
    // 置位“数据就绪”信号,通知PLC取数据
    PLC_DataReady = 1;
    
    // 等待PLC确认(超时保护)
    WHILE PLC_Acknowledge == 0 AND TimeOut < 5000
        // 等待PLC处理
    END WHILE;
    
    IF PLC_Acknowledge == 1 THEN
        // 下发成功,复位标志
        PLC_DataReady = 0;
        Recipe_Ready = 0;
        Message("配方下发成功");
    ELSE
        Message("错误:PLC未确认,请检查通信");
    END IF;
ELSE
    Message("错误:PLC正在运行,无法下发配方");
END IF;

提示:上面的代码里,我加了一个超时保护。这是血的教训换来的。有一次PLC死机了,Intouch一直等PLC确认,结果界面卡死了5分钟。从那以后,所有通信交互我都加了超时。

4.5 知识体系流程图

下面这张图,把配方加载与切换的整个逻辑串起来了。你可以把它当作一个参考框架。

配方加载与切换核心逻辑 数据源 SQL / CSV / 标签字典 加载与校验 格式检查 / 范围校验 中间变量暂存 Recipe_Temp_Array[0..19] 设备运行中? 等待当前批次结束 立即切换 下发到PLC缓冲区 置位“数据就绪”信号

这张图里,我特意把“设备运行中”的判断放在中间。说白了,这就是整个切换策略的分水岭。你把这个逻辑理清楚了,配方切换就不会出大问题。

总结一下:配方加载与切换,核心就三件事——加载要校验、切换要等待、下发要缓冲。这三条做到了,你的配方系统就稳了八成。

好了,这一节的内容就到这儿。配方加载和切换的实战经验,我都掏心窝子讲给你了。下次你在项目里遇到类似问题,可以试试我这些方法。


公众号:蓝海资料掘金营,微信deep3321