4. Produced/Consumed标签实战
在一条由多台 Logix 控制器协同控制的产线上,主站往往需要把同一组运行参数同时下发给多个从站:产线速度给定、全线启停命令、当前配方号。若用 MSG 指令逐台轮询,代码量大、周期长,且新增从站时还要改程序。Produced/Consumed(生产/消费)标签正是为解决这类“一对多广播”而设计的:生产者控制器把标签打包成组播数据,消费者控制器按需订阅,一次生产、多方消费,网络负载与编程量都显著降低。
一、先理解数据是怎么流动的
Produced 标签由生产者控制器周期性发出,采用 UDP 组播,不确认、不重传,因此它适合“周期性刷新、允许偶发丢包”的过程数据,而不适合一次性事件或需要严格握手的命令。Consumed 标签在消费者侧是一个只读连接,其数据由网络刷新更新,消费者程序不能写它。连接建立的前提是:生产者与消费者位于同一子网或可路由的组播域内,且双方对同一标签的连接参数(RPI、连接类型)匹配。
关键参数有三个:RPI(请求数据包间隔)决定刷新周期,例如 20 ms 表示每 20 ms 生产一次;连接类型通常选“多播(Multicast)”,这样多个消费者共享同一份数据流;标签数据类型必须双方一致,推荐使用用户自定义结构体(UDT),把速度、启停、配方号打包成一个标签,减少连接数量。
二、生产者侧:定义 UDT 并发布标签
第一步在控制器标签数据库里新建一个用户自定义数据类型,命名为 LineCmd_UDT,成员如下:Speed_SP : REAL(单位 m/min)、Run_Stop : BOOL、Recipe_No : INT。用 UDT 的好处是三个字段共享一个连接,消费者只需订阅一个标签。
接着在 Controller Tags 中新建标签 LineCmd,类型选 LineCmd_UDT。右键该标签 → Edit Properties → 在 Produce 选项卡中勾选“Produce this tag”,设置 Maximum number of consumers(例如 8,按从站数量留余量),RPI 填 20 ms,连接类型选 Multicast。确认后标签图标会出现“P”标记,表示已发布。
// 生产者侧示例:主程序周期性刷新 LineCmd
LineCmd.Speed_SP := HMI_Speed_SP; // 来自 HMI 的速度给定
LineCmd.Run_Stop := Line_Run_PB AND NOT Line_Stop_PB;
LineCmd.Recipe_No := Current_Recipe; // 当前配方号
// 注意:LineCmd 由生产者写入,消费者侧同名标签为只读
三、消费者侧:建立连接并映射
在每个从站控制器中,同样先导入 LineCmd_UDT(可通过 L5X 导出/导入或直接在项目中复制 UDT 定义,保证结构完全一致)。然后在 Controller Tags 中新建标签,例如从站1用 LineCmd_1,类型选 LineCmd_UDT。右键 → Edit Properties → Consume 选项卡,勾选“Consume this tag”,在 Producer 栏填入主站的路径,例如 192.168.1.10 或 MainCtrl,并选择对应的生产者标签 LineCmd,RPI 与生产者保持一致(20 ms)。
连接建立后,LineCmd_1 会以只读方式刷新。从站程序直接引用它即可:
// 从站1 消费侧示例
IF LineCmd_1.Run_Stop THEN
Station1_Run := TRUE;
Station1_SpeedRef := LineCmd_1.Speed_SP;
ELSE
Station1_Run := FALSE;
END_IF;
// 配方号变化时切换本站参数组
IF LineCmd_1.Recipe_No <> Last_Recipe THEN
Last_Recipe := LineCmd_1.Recipe_No;
Call_Recipe_Change(LineCmd_1.Recipe_No);
END_IF;
四、验证数据一致性
配置完成后不能只看“连接已建立”,必须验证数据真的同步。推荐用三层验证:
- 在线监视:在从站控制器中打开
LineCmd_1的监视窗口,与主站LineCmd并排对比。修改主站Speed_SP为 45.0,观察从站是否在 1~2 个 RPI 内变为 45.0。 - 程序比对:在从站写一段校验逻辑,把消费到的三个字段与本地期望值比较,不一致时置位报警位
Data_Mismatch。 - 趋势与统计:用趋势图记录主站与从站的
Recipe_No,切换配方时观察各从站是否同步跳变;也可用 GSV 指令读取连接状态,确认ConnectionFault为 0。
// 从站一致性校验示例
Data_Mismatch := (LineCmd_1.Speed_SP <> Main_Speed_Ref)
OR (LineCmd_1.Run_Stop <> Main_Run_Ref)
OR (LineCmd_1.Recipe_No <> Main_Recipe_Ref);
// 若需读取连接健康状态
GSV(Connection, LineCmd_1, ConnectionFault, Fault_Flag);
五、实战中的几个要点
RPI 不是越小越好。 20 ms 适合速度给定这类连续量;若只是配方号这种低频变化,可单独用一个 RPI 100 ms 的标签,避免占用带宽。启停命令建议加去抖与确认。 由于组播不重传,可在从站侧对 Run_Stop 做 2~3 个扫描周期的滤波,防止瞬时丢包导致误动作。新增从站时只需在从站侧新建 Consume 标签并指向同一生产者,主站无需改动,这正是 Produced/Consumed 相对 MSG 轮询的最大优势。
最后提醒:生产者和消费者的 UDT 必须“同名同构”,任何字段增删都要同步更新所有站点,否则连接会失败或数据错位。建议把 UDT 定义纳入版本管理,每次修改后重新导出 L5X 分发,确保全线一致。