前阵子接手一条食品包装线的改造,客户的老设备换了新工艺要求:同一台机要能生产16种不同规格的产品,每种规格对应一组温度、压力、速度、延时参数。以前换规格全靠操作工翻纸质工艺卡,手动在温控表和变频器上调,一次换规格少说四十分钟,调错数字也是常有的事。客户提了个很朴素的需求:能不能做几个按钮,一按就自动把整组参数切过去?
这就是典型的配方程序需求。我用了三菱FX3U系列PLC来做这个16仓位配方管理程序,从需求拆解、存储区规划、程序编写到现场调试,前后折腾了小半个月。这篇记录把整个开发和踩坑过程捋一遍,给做OEM设备、搞老设备改造、或者刚接触配方程序的朋友一个参考。里面涉及的具体寄存器分配、程序逻辑、HMI交互方案,都是能直接抄作业的级别。
1. 16仓位配方到底是个什么需求,我是怎么把它拆清楚的
接到需求先别急着写程序。我跟客户现场聊了一上午,发现"配方"这个词在不同人口中含义差得远。对操作工来说,配方就是"那张卡片上的数字";对老板来说,配方是"换产品之后机器能立马正常干活";对设备工程师来说,配方是一串能自动灌进PLC的工艺参数。我最后把需求收敛成一句话:一条生产线上,用16组工艺参数管理不同产品规格,切换时要快、要准、不能错。
1.1 先搞清楚"配方仓位"在设备里是什么意思
所谓16仓位配方,就是把存储区划分成16个固定区域,每个区域存一套完整参数。比如我这次的项目,每套配方包含8个工艺参数:4路温控设定值、1路牵引速度、1路切刀延时、1路进给量、1路气压值,加上配方编号和校验字,每个配方占用10个字。
这16个仓位本质上就是PLC里的一片数据区。问题来了:这片数据区该放在哪、怎么组织、何时被复制到工作区、怎么防止被误改。后面会发现,配方的难点从来不在"存",而在"切换的时机"和"数据的可靠性"。
1.2 需求调研阶段最容易翻车的三件事
第一件事是搞错配方条目数量。客户一开始说"每套就七八个参数",结果我列清单的时候发现在他的生产流程里有联动参数:改了温度,对应的延时也要跟着变。最后配方条目从8个变成了13个,幸好我在存储区规划时留了余量,不然16×13个字也能放下,但HMI画面就要返工。
第二件事是没问清楚切换时机。客户说"一键切换",但设备运行中能不能切?这是个致命问题。后来确认:只能在待机状态切换,运行中必须互锁。这个逻辑如果不提前写清楚,现场调试时操作工会直接骂人——生产到一半不小心碰到配方切换,整批产品报废。
第三件事是掉电保持需求。客户所有设备都要求断电重启后配方不能丢。这直接决定了存储区选型,后面第2章详细讲。
1.3 整体框架:配方存储区、工作参数区、HMI交互区各司其职
程序框架我分成三个区域,各管各的事:
- 配方存储区:存16组配方原始数据,只允许通过配方保存程序写入。
- 工作参数区:当前正在使用的参数,设备运行过程中实时读取这个地方。
- HMI交互区:触摸屏上的输入框、修改框直接绑定这片区域。
流程上是这样:操作工在HMI上选择配方号1到16,PLC把对应仓位的参数复制到工作参数区,设备按新参数运行;操作工在HMI上修改某个参数后,按下保存按钮,PLC再把工作参数区整组拷回对应仓位。
为什么要分三个区而不是让HMI直接改配方存储区?因为如果HMI直接面对16组配方地址,操作工可能在配方号输入框里填个17,或者把配方1的参数写到配方5里去。有了工作参数区当缓冲区,PLC可以校验配方号范围、做操作确认,HMI那边永远只面对一组"当前参数",界面清爽,逻辑也安全。
2. 存储区规划才是配方的命根子:FX3U寄存器怎么分配才不掉数据
很多初学者做配方程序,直接拿几个D寄存器就开干,结果一断电数据全没了。三菱FX3U的数据寄存器不是所有区域都默认断电保持,这一点不搞清楚,配方程序就是个定时炸弹。
2.1 D区、锁存区、文件寄存器R区怎么选
FX3U的D寄存器分几类:普通D区、锁存D区、文件寄存器R区。R区比较特殊,它本质上也是数据寄存器,但编号是R0到R32767,容量比D区大得多,而且由PLC电池保持,断电后数据不丢失。D区的默认锁存范围只有一部分(具体看PLC参数设置),超出范围的D寄存器断电后清零。
我这次把16仓位的配方存储区全部放在R区,从R0开始,每10个字为1个仓位,一共160个字,再加几个状态字。R区做配方存储有几个好处:一是容量充裕,16仓位才占160个字,后面扩到32仓位也就320个字,R区根本不当回事;二是断电保持不需要额外设置,电池在就不丢;三是不占用宝贵的D区资源,D区留给工作参数和中间变量。
工作参数区放在D300到D312,HMI画面直接读写这个区域。这个区域断电丢不丢无所谓,因为每次上电时程序会自动从R区把上次用的配方恢复到D区。D区只是"临时工作台",R区才是"仓库"。
2.2 16仓位地址映射表:土办法解决偏移量混乱
配方的核心操作就是"按配方号算地址偏移"。每个仓位10个字,那么:
- 配方1:R0到R9
- 配方2:R10到R19
- 配方3:R20到R29
- 配方N的起始地址 =(N-1)×10
这个计算看着简单,但程序写多了就会发现,最怕的是2号仓和3号仓之间差了几个字导致整段错位。我的土办法是:在程序里不直接用乘法算地址,而是用变址寄存器做偏移。先把配方号减1放到变址寄存器Z里,然后用R0Z访问第一个参数,R1Z访问第二个参数。这样写程序,后面要改仓位宽度(比如每仓从10个字改成12个字),只需要改一批循环次数和HMI画面,核心搬运逻辑不用推倒重来。
2.3 配方扩容预留:从16仓位扩到32仓位要改几个地方
客户做设备的人都有一个通性:今天说16个够了,过两个月就说要加规格。所以我从架构上就留了后手。
R区存储:16仓位用了R0到R159,扩到32仓位用到R319,完全不用动。 配方号上下限:把上限常数从16改成32,加一个范围判断,超限自动报警。 HMI画面:如果是下拉选择配方号,多拉几个条目就行;如果是一页显示16个按钮,那要多加一页。 工作参数区不动、搬运逻辑不动、校验逻辑不动。
也就是说,配方数量改变是"数据量"的问题,不是"架构"的问题。这种预留思路在做工程项目时特别重要,你不知道客户什么时候会变卦,但你可以让变卦的成本变得很低。
3. 配方管理程序的编写逻辑:加载、保存、校验和防呆
存储区规划好了,接下来就是写程序。配方管理程序我分成三大块:加载流程、保存流程、校验逻辑,再加上与HMI的握手信号。这块是配方的核心,也是最容易出逻辑漏洞的地方。
3.1 配方加载流程:为什么必须先停再切
配方加载就是把R区某个仓位的参数复制到D区工作参数区。代码如下(GX Works2里用指令表形式写,便于说明逻辑):
LD M100 // 设备运行状态位,运行时为ON ANI M0 // HMI配方加载请求 OUT M101 // 设备运行中禁止加载标志,M101=ON时HMI弹窗报错当设备正在运行,M100为ON,这时候M0即使被HMI触发,加载也不会执行。只有当M100为OFF(待机状态),M0触发后才会执行后续的搬运指令。为什么必须这样?因为生产过程中设备各执行机构正在按当前参数动作,你突然把温度设定值从180度改成220度,加热器会疯狂追赶,产品直接报废是小,搞出安全事故是大。
配方加载执行的核心搬运逻辑(示意):
LD M0 AND M100 // 设备已停止 MOV K13 D0 // 配方参数条目数13 MOV D200 Z // D200是当前配方号,放入变址寄存器Z // 从R区配方存储区搬运到D区工作参数区 MOV R0Z D300 MOV R1Z D301 MOV R2Z D302 ...(循环或逐条搬运)这里用Z变址寄存器做偏移,Z的基址是0,所以配方号存的是1到16,只需要在写入时把配方号减1换算成偏移量。搬运完成后置位M1通知HMI"加载完成",HMI画面上的参数框刷新显示。
3.2 配方保存流程与数据校验:防止HMI误触写坏参数
保存比加载更危险,因为它是"把数据写进长期存储区",一旦写错,意味着整组配方被破坏。所以保存流程必须加确认和校验。
保存流程设计如下:操作工在HMI上调整参数后,按下"保存到当前配方"按钮,HMI会弹出一个确认框提醒"确定覆盖配方N的参数吗?"操作工确认后,HMI置位M2。PLC收到M2后,先把工作参数区D300到D312逐字累加,算出一个校验和存入D313,再把D300到D313整体复制到对应R区仓位。
每一组配方后面都存一个校验字,这个校验字的算法很简单:把所有参数值按16位累加,溢出不管,只保留累加结果。加载时再算一遍,跟存储的校验字对比,不一致就报警。这样能挡住绝大多数数据错乱问题,包括通讯干扰导致的某个字写错。
有一点要提醒:如果参数里可能出现负数(FX3U里16位有符号数范围是-32768到32767),累加时正负都会参与计算,只要算法一致就没问题。我见过有人把负数格式化成正数存,结果加载出来完全对不上,白白折腾两天。
3.3 与HMI的握手信号设计:避免读写打架
HMI和PLC之间是异步通讯,最怕的就是两边同时操作同一片数据。我设计了一组握手信号:
- M0:HMI请求加载配方
- M1:PLC回复加载完成/失败
- M2:HMI请求保存配方
- M3:PLC回复保存完成/失败
- M4:HMI正在编辑参数(置ON期间PLC禁止刷新D区)
这套握手逻辑看起来简单,但实际工程里经常有人忽略。比如HMI画面上的参数输入框绑定D300,操作工正在输入温度值,PLC这边因为某个触发条件在刷新D300,两边同时写,结果就是操作工输入到一半,数字被PLC刷新成别的值,或者反过来。加了M4之后,PLC在M4为ON时不做任何写D区操作,只在M4变OFF后刷新一次。
4. 触摸屏画面和通讯实测:那些说明书上不会写的细节
配方程序光PLC侧做好还不够,HMI画面才是操作工直接面对的东西。画面做得顺不顺,直接决定操作工愿不愿意用这套系统。我在这个项目里遇到过几个典型的HMI相关问题,值得单独拿出来说。
4.1 HMI端做配方库还是PLC做主管理:我的取舍
市面上的触摸屏基本都自带配方功能,可以在屏幕里建一个配方数据库,把每组参数存在屏内部,用一个"配方编号"来管理。听起来很方便,但我在实际项目里吃过亏,现在基本不用HMI自带配方库来做关键数据管理,原因有三个。
第一个原因是数据源不统一。HMI配方库的数据存在屏里,PLC程序里没有,一旦PLC程序被重新下载,或者HMI换个程序版本,两边数据就对不上了。第二个原因是上电覆盖问题,有些屏的配方数据块在启动时会把屏幕里的初始值自动下发到PLC地址,直接覆盖PLC里之前保存的配方,造成"新配方保存了,一重启又变回旧值"的诡异现象。第三个原因是管理权限,HMI配方库的校验、防呆逻辑很弱,操作工很容易把配方号填错。
所以我这一次的方案是:PLC做唯一数据源,HMI只做显示和输入。HMI画面上的所有参数框直接绑定PLC的工作参数区D300到D312,配方号选择框绑定D200,保存和加载按钮只控制M0、M2这两个位,所有搬运、校验、判断全部在PLC里完成。这样就算HMI程序被人误删重装,只要PLC不掉电,配方数据依然完好。
4.2 通讯掉线、干扰、数据错位:现场排查实录
现场调试时遇到一个很难查的问题:配方参数偶尔会整体偏移,比如配方3的参数跑到配方5的位置上,但提示报警都没报。一开始我怀疑PLC程序逻辑有问题,反复查代码没有发现异常。后来用电脑连上PLC在线监控,盯着R区数据看,才发现是HMI的配方编号输入框允许填0、填负数、填超过16的数,一旦操作工不小心填了0,PLC侧做偏移计算时就乱套了。
解决方法是三层:第一层在HMI输入框上设置上下限,最小值1,最大值16,超限根本输入不进去;第二层在PLC程序里加配方号合法性判断,D200小于1或者大于16时自动置位报警,并把D200钳位到上次使用的合法值;第三层在加载前做校验字验证,发现校验不匹配就拒绝加载并弹窗报错。三层加上之后,这个问题再没出现过。
4.3 误触保护和操作界面设计建议
实际操作中,操作工手上可能有油、可能戴着手套,误触屏幕的概率不低。界面设计我有几个具体建议:
配方切换按钮不要放在画面边缘,边缘区域容易被手掌误碰。 切换操作要两步以上:按"切换配方"→弹窗显示当前配方号和目标配方号→再按"确认"才执行。 每个配方在画面上显示一个简短的产品名称,比如"产品A-红色款",而不是光显示"配方3",人脑对文字的反应速度比数字快得多,误操作概率明显下降。
我在客户现场还加了一个小功能:新建配方。操作工把产品参数调好后,按"另存为新配方",程序自动找一个空仓位存进去,并把仓位号提示出来。这个小功能客户非常喜欢,因为这正好符合他们"打样→存参数→批量生产"的工作习惯。
5. 调试记录:三台设备上踩过的坑和修复过程
程序框架写完不代表完事,真正考验人的是调试阶段。这个项目先后在三台设备上部署,每一台都踩了不同的坑。我把最有代表性的三个问题记录下来,每一个都是花了半天以上才定位到根因的。
5.1 断电重启后参数全部归零:锁存区设置的教训
第一台设备装好之后,现场测试一切正常,配方切换、保存、校验都没问题。但第二天早上客户打电话来说:"你们这个设备参数全没了,全部变成了0。"我赶过去一看,R区里的配方数据还在,但是工作参数区D300到D312断电后清零了,设备上电后程序虽然有自动从R区恢复的逻辑,但恢复条件是M8002(首次扫描脉冲)加一个启动延时,而实际运行时设备主程序先执行了,把D区的0值参数灌给了温控表和变频器。
这个问题出在我把"恢复逻辑"放在子程序里,子程序只在特定条件下执行,而上电瞬间没执行到位。修复方案:把配方恢复逻辑放到初始化主程序段,用M8002做触发,并加一个100毫秒的延时,确保HMI通讯就绪后再刷新D区。从那以后我所有配方程序都遵循一个准则:上电初始化必须显式按顺序执行"读配方号→验证→恢复工作参数",不能依赖某个边沿信号。
5.2 生产过程中误切配方:三道保险怎么加上去
第二台设备投入使用两周后,客户反馈:操作工在设备运行的时候想按"查看另一个配方的参数",结果不小心按到了"加载配方",整台设备突然按新配方运行,产品全部报废。虽然我在程序里写了M100运行状态互锁,但问题在于:有些设备运行状态不是持续ON,而是脉冲式的,比如转盘每转一圈给一个完成信号,导致PLC判断"设备已停止"误判。
修这个问题的方案是给配方加载增加三道保险:
第一道是运行状态软元件改成长信号:设备主程序里只要有任何一个执行机构在动作,就把M100置ON,设备完全停下来后M100才变OFF。 第二道是HMI二次确认:加载按钮按下后,弹窗显示"确认从配方N加载参数?",必须再按一次确认。 第三道是操作权限分级:配方加载和保存按钮需要在HMI上登录"管理员"权限才能操作,普通操作工只能查看参数。
三道加上之后再没发生误切事件。很多做电气的人觉得权限分级是给客户添麻烦,但实际上一次误操作造成的废品损失,远比多输一次密码的成本高。
5.3 参数被"恢复出厂值":HMI配方数据块的坑
第三台设备调试时遇到一个更隐蔽的问题:操作工下午刚改了配方并保存,晚上关设备,第二天开机,所有参数又变回前天保存的旧值。排查了半天,发现是HMI自带的配方数据块在搞鬼。这块屏的配方数据块默认配置是"进入画面时自动把屏幕配方数据写入PLC地址",只要操作工打开过配方管理画面,屏幕就会把旧数据覆盖到PLC的D区。
这是个非常典型的坑,甚至不能说是故障,因为HMI的设置项就是这么设计的。解决方法是改用我前面说的方案:PLC作为唯一数据源,HMI画面上的所有参数框变成普通数值显示/输入元件,直接绑定PLC的D区,不绑定HMI自带的配方数据块。同时在HMI里关闭所有自动写入配方功能。从那以后,我再也不在配方关键项目上依赖触摸屏自带的配方库了。
写在最后:关于这套配方程序的一些体会
三台设备部署完,这套16仓位配方程序基本定型,后来被我从头到尾模块化,变成一个通用模板:存储区映射、加载保存逻辑、校验算法、HMI握手信号全部标准化,遇到类似配方需求,改改参数条目数和配方数量就能上。调试时有一个体会特别深:跟现场操作工聊天比看图纸还管用。有一次操作工随口说"我每次调完温度都要顺便把进给速度减两格,不然切出来会毛边",这句话直接让我在配方里加了一组联动参数,避免了很多后续麻烦。
另外给新入行的朋友一个忠告:配方程序的注释一定要写人话。我见过太多PLC程序里全是"XX0001"这种不明所以的注释,三个月后自己都看不懂。我在这套程序里每段配方逻辑都写了中文注释,包括"从R区加载到D区"、"配方号减1转偏移量"这种大白话,半年后回头维护,效率高得多。
最后再分享一个小技巧:配方参数表一定要用Excel维护一份,字段包括配方号、参数中文名、PLC地址、单位、上下限、当前值。这份表既是调试时的对照手册,也是给客户操作工的培训资料。工程项目的价值不只是机器能跑,还有你能把"怎么跑、为什么这么跑"讲得清清楚楚。这套16仓位配方程序本身不复杂,但把每一个细节都想明白、把每一个坑都填平,才是项目能顺利交付的真正原因。