☰
三菱PLC库存管理:用CTUD替代双CTU解决计数不同步
2026/10/26 9:40:11 网站建设 项目流程

1. 项目缘起:一个让产线停机的库存差问题

去年帮一家做汽车小配件的客户处理产线数据,碰到一个挺典型的坑。他们有一条装配线,用三菱FX3U的PLC做控制,ST语言写的程序。线体上有两个工位:一个上料工位,一个下料工位。上料工位每放一个工件,传感器给一个脉冲;下料工位每取走一个工件,也传感器给一个脉冲。中间有个缓存区,理论上缓存区里的工件数量应该等于上料数减去下料数。

问题出在哪呢?他们用两个独立的CTU(加计数)指令,一个计上料,一个计下料,然后在HMI上做减法显示库存。逻辑上没毛病,但实际跑起来,库存数偶尔会跳变,甚至出现负数。产线一报警停机,操作工就得手动复位,一天折腾好几回。

我去现场看了半天,最后发现问题不在传感器,也不在PLC扫描周期,而是出在两个独立CTU的计数不同步上。上料脉冲和下料脉冲如果落在同一个扫描周期里,两个CTU的当前值更新顺序取决于程序里指令的排列位置,减法结果就会瞬间出现一个错误的差值。虽然下一个周期会修正,但HMI的刷新恰好抓到了那个错误值,操作工看到的就是跳变。

这个问题的根子,是用两个独立的加计数器去做差值运算,本身就存在时序竞争。正确的做法,是换成一个CTUD(加/减计数器)组合,让加减在同一个计数器内部完成,从根本上消除两个计数器之间的同步问题。

这篇文章就把这个改造过程完整拆一遍,包括ST语言的写法、CTUD的参数配置、以及我在现场踩过的几个坑。如果你也在用三菱PLC做类似的库存管理、位置跟踪、流量差值计算,这篇应该能帮你省下不少调试时间。

2. 为什么双CTU做差值会出问题

2.1 双CTU方案的逻辑结构

先看他们原来的写法,简化一下大概是这样:

(* 双CTU方案 - 有问题的写法 *) CTU_Up( CU := X0, (* 上料脉冲 *) R := M100, (* 复位 *) PV := 32767, (* 设定值 *) CV := D100); (* 上料计数当前值 *) CTU_Down( CU := X1, (* 下料脉冲 *) R := M100, PV := 32767, CV := D101); (* 下料计数当前值 *) (* 库存计算 *) D102 := D100 - D101;

这段代码看起来很清楚:X0来一个脉冲,D100加1;X1来一个脉冲,D101加1;库存就是D100减D101。逻辑上完全正确,但问题出在执行顺序和扫描周期上。

2.2 时序竞争的根源

PLC的扫描是周期性的:读输入、执行程序、刷新输出,循环往复。假设当前D100=10,D101=8,库存D102=2。现在某个扫描周期里,X0和X1同时来了脉冲。

程序执行到CTU_Up时,D100变成11。执行到CTU_Down时,D101变成9。然后计算D102 = 11 - 9 = 2。结果正确,没问题。

但如果X0和X1不是严格同时,而是X0的脉冲在本次扫描被读到,X1的脉冲在下次扫描才被读到呢?第一次扫描:D100=11,D101=8,D102=3。第二次扫描:D100=11,D101=9,D102=2。中间那个D102=3就是错误的瞬时值。

更麻烦的是,如果程序里CTU_Down写在CTU_Up前面,执行顺序反过来,中间错误值就变成1。HMI的刷新周期如果和PLC扫描周期不同步,就很容易抓到这些中间值。

注意:三菱FX系列的CTU指令,当前值CV是在指令执行时立即更新的,不是等整个扫描周期结束。所以两个CTU之间的减法,读到的是"半更新"状态。

2.3 为什么不能靠加延时解决

有人可能会想,那我在减法之前加个延时,等两个CTU都更新完再算不就行了?理论上可以,但实际很别扭。延时多久?一个扫描周期?FX3U的扫描周期在几毫秒到几十毫秒之间波动,取决于程序大小。延时太短没效果,太长又影响响应。而且延时期间如果又来新脉冲,问题依旧。

根本的解决办法,是让加减操作在同一个计数器里完成。这就是CTUD的用武之地。

3. CTUD组合的核心原理与选型

3.1 CTUD是什么

CTUD是三菱PLC里的加/减计数器指令,全称Count Up/Down。它有两个脉冲输入:CU(加计数输入)和CD(减计数输入)。每来一个CU脉冲,当前值加1;每来一个CD脉冲,当前值减1。当前值CV是一个变量,加减都在这个变量上直接操作。

关键区别在于:CTUD只有一个当前值寄存器。不管加还是减,都是对同一个CV做操作。所以不存在两个计数器之间的同步问题。上料脉冲让CV加1,下料脉冲让CV减1,CV本身就是库存值,不需要再做减法。

3.2 CTUD的参数配置

三菱FX3U的CTUD指令参数如下:

参数说明本例取值
CU加计数输入X0(上料脉冲)
CD减计数输入X1(下料脉冲)
R复位输入M100
LD负载输入(预置值加载)M101
PV预置值32767
CV当前值D100

这里有几个细节要注意。PV设成32767是因为FX3U的计数器是16位有符号整数,范围-32768到32767。库存不可能到这么大,设成上限就行。R是复位,把CV清零。LD是加载预置值,一般不用,但如果有初始库存需要预置,可以用LD把PV加载到CV。

3.3 为什么选CTUD而不是其他方案

有人可能会问,用加减指令(ADD/SUB)配合普通计数器行不行?也行,但CTUD更直接。用ADD/SUB的话,你还是得先有计数,再做运算,中间还是有一步。CTUD是硬件级的计数器指令,加减在指令内部完成,效率更高,代码也更简洁。

还有人选INC/DEC指令,每次脉冲来的时候对寄存器加1或减1。这个方案其实和CTUD效果类似,但INC/DEC是通用指令,CTUD是专用计数器指令,在ST语言里CTUD的语义更清晰,可读性更好。

实操心得:FX3U的CTUD当前值CV是掉电保持的,但如果你用的是D寄存器做CV,需要确认D寄存器的掉电保持范围。FX3U默认D0-D199是普通寄存器,掉电不保持;D200-D511是掉电保持的。如果库存需要掉电恢复,CV要指定到D200以后的寄存器。

4. ST语言实现CTUD库存管理

4.1 完整的ST程序结构

改造后的ST程序,核心就一段:

(* CTUD库存管理 - 推荐写法 *) CTUD_Stock( CU := X0, (* 上料脉冲 *) CD := X1, (* 下料脉冲 *) R := M100, (* 复位 *) LD := M101, (* 预置加载 *) PV := 32767, (* 预置值 *) CV := D200); (* 当前库存值,掉电保持 *) (* 库存上限报警 *) IF D200 > 100 THEN M200 := TRUE; (* 库存超上限 *) ELSE M200 := FALSE; END_IF; (* 库存下限报警 *) IF D200 < 0 THEN M201 := TRUE; (* 库存为负,异常 *) ELSE M201 := FALSE; END_IF;

这段代码比原来的双CTU方案短了一半,而且逻辑更清晰。D200直接就是库存值,HMI直接读D200就行,不需要再做减法。

4.2 脉冲信号的防抖处理

CTUD对脉冲的响应很敏感,如果传感器有抖动,会多计数。所以实际项目里,X0和X1最好做一下防抖。三菱FX3U的输入滤波器可以设置,但软件防抖更灵活:

(* 上料脉冲防抖 - 10ms滤波 *) TON_Up( IN := X0, PT := T#10ms, Q => M10); (* 下料脉冲防抖 *) TON_Down(IN := X1, PT := T#10ms, Q => M11); (* 用防抖后的信号驱动CTUD *) CTUD_Stock( CU := M10, CD := M11, R := M100, LD := M101, PV := 32767, CV := D200);

这里用了两个TON(接通延时定时器),只有X0持续接通10ms以上,M10才为TRUE。这样短于10ms的抖动就被滤掉了。10ms这个值可以根据实际传感器的响应速度调整,一般机械式传感器5-20ms都够用。

4.3 复位与预置的逻辑

复位M100和预置M101不能同时有效,否则CTUD的行为不确定。实际项目里,复位一般由HMI上的按钮触发,预置由参数设置界面触发。程序里最好加个互锁:

(* 复位和预置互锁 *) IF M100 AND M101 THEN M100 := FALSE; (* 复位优先 *) END_IF;

另外,复位操作最好在设备停止状态下进行,运行中复位会导致库存值突变,可能触发报警。如果确实需要在运行中复位,建议先暂停产线,复位后再启动。

5. 现场调试与问题排查实录

5.1 第一次上电:库存值不对

改造完第一次上电,D200显示的不是0,而是一个随机值。查了一下,D200是掉电保持寄存器,之前存过别的数据。解决方法是上电初始化时清零:

(* 上电初始化 *) IF M8002 THEN (* M8002是FX3U的初始脉冲,只在第一个扫描周期为TRUE *) D200 := 0; M100 := TRUE; (* 复位CTUD *) END_IF;

M8002是三菱FX系列的特殊继电器,只在PLC从STOP切换到RUN的第一个扫描周期接通。用它做初始化最合适。

5.2 计数偶尔多1或少1

跑了一段时间,发现库存偶尔会多1或少1。查了半天,发现是传感器安装位置的问题。上料传感器的检测距离太近,工件经过时产生了双脉冲。调整传感器位置后问题消失。

这个坑提醒我,CTUD本身没问题,但输入信号的质量直接决定计数准确性。如果传感器信号质量不好,再好的计数器也白搭。建议在调试阶段用PLC的脉冲捕捉功能或者高速计数器先确认一下脉冲数量对不对。

5.3 HMI显示刷新导致的视觉跳变

虽然CTUD解决了逻辑上的同步问题,但HMI显示还是偶尔会跳。查了一下,是HMI的刷新周期和PLC扫描周期不同步。HMI每200ms读一次D200,如果正好读到CTUD正在更新的瞬间,可能读到旧值。但这个跳变是视觉上的,不影响实际库存值。

解决办法是把HMI的刷新周期调到500ms以上,或者用HMI的数值平滑功能。如果对显示实时性要求不高,1s刷新一次也够用。

5.4 常见问题速查表

现象可能原因排查方法解决措施
库存值随机跳变双CTU时序竞争检查是否用了两个独立CTU改用CTUD
上电库存不为0D寄存器掉电保持查看D寄存器范围上电初始化清零
计数多1或少1传感器抖动或双脉冲用高速计数器验证脉冲数加防抖或调整传感器
HMI显示跳变刷新周期不同步对比PLC和HMI刷新周期调整HMI刷新周期
库存出现负数下料脉冲多于上料检查传感器逻辑加下限报警和互锁
CTUD不计数脉冲太窄用示波器看脉冲宽度加脉冲展宽或换传感器

避坑技巧:调试CTUD的时候,先把CU和CD分别接到两个按钮上,手动按按钮验证加减逻辑。确认CTUD本身没问题后,再接传感器。这样能把问题定位在CTUD还是传感器上。

6. 扩展应用与性能优化

6.1 多工位库存管理

如果产线有多个缓存区,每个缓存区都需要库存管理,可以用多个CTUD实例。但要注意,每个CTUD的CV要分配到不同的D寄存器,而且都要在掉电保持范围内。

(* 工位1库存 *) CTUD_Stock1(CU := X0, CD := X1, R := M100, LD := M101, PV := 32767, CV := D200); (* 工位2库存 *) CTUD_Stock2(CU := X2, CD := X3, R := M102, LD := M103, PV := 32767, CV := D201); (* 工位3库存 *) CTUD_Stock3(CU := X4, CD := X5, R := M104, LD := M105, PV := 32767, CV := D202);

如果工位数量多,建议把CTUD封装成函数块(FB),用数组管理CV。三菱的ST语言支持FB,但FX3U对FB的支持有限,GX Works2里可以用结构化工程实现。

6.2 库存数据的可视化

客户后来加了一个可视化看板,用三菱的GOT触摸屏或者第三方SCADA。数据源就是D200这些寄存器。如果要做趋势图,可以把D200的值定时存到数据记录区,用GOT的采样功能或者SCADA的 historian。

这里有个小技巧:库存值的变化频率不高,不需要每个扫描周期都记录。可以每1秒记录一次,用定时器触发:

(* 每秒记录一次库存 *) TON_Record(IN := NOT T1.Q, PT := T#1s, Q => T1.Q); IF T1.Q THEN D300 := D200; (* 记录当前库存 *) (* 可以在这里做数据移位,存历史数据 *) END_IF;

6.3 性能考量

CTUD指令的执行时间很短,FX3U上大概几微秒。即使有几十个CTUD实例,对扫描周期的影响也可以忽略。真正影响性能的是防抖定时器和HMI通信。如果防抖定时器太多,会占用定时器资源。FX3U的定时器数量有限,一般够用,但如果项目很大,要考虑复用。

另外,HMI通信如果太频繁,会拖慢PLC的扫描周期。建议HMI的刷新周期不要低于200ms,数据量大的话用批量读取,不要一个一个读。

7. 从CTUD延伸出去的几个思考

这次改造之后,我又碰到几个类似的需求,都是关于"差值"的。比如流量计的正向流量和反向流量,用两个CTU做差值也会有时序问题,换成CTUD就解决了。还有位置跟踪,编码器的正转和反转脉冲,用CTUD做位置计数,比用两个CTU再相减要可靠得多。

其实核心逻辑很简单:凡是需要做加减差值的场景,优先考虑用CTUD,而不是两个独立的计数器。CTUD把加减操作封装在一个指令里,消除了两个计数器之间的同步窗口,这是它最大的价值。

当然,CTUD也不是万能的。如果加减脉冲的频率非常高,超过了PLC的扫描周期能响应的范围,就需要用高速计数器和中断来处理。FX3U的高速计数器可以到100kHz,但那是另一套编程模型了,和CTUD不是一回事。

最后分享一个我在现场养成的小习惯:每次用CTUD之前,先手动模拟几个脉冲,确认加减逻辑和复位逻辑都对,再接实际信号。这个习惯帮我省了很多现场调试的时间。毕竟在产线上排查问题,比在办公室按按钮要麻烦得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询