4. 高速装配设备中的变量与数据类型

在高速装配设备中,控制程序往往要同时处理几十个工位、上百个气缸与伺服轴,还要与视觉、机器人、MES 交换数据。如果变量命名随意、类型混乱,程序很快就会变成一团难以维护的“面条”。Sysmac Studio 基于 IEC 61131-3 标准,提供了全局变量、局部变量、结构体、数组和用户自定义数据类型(UDT)等机制,本节围绕它们在高速装配设备中的实际用法展开。

一、全局变量与局部变量的分工

全局变量(Global Variable)在整个 NJ/NX 控制器项目中可见,任何 POU(程序、功能块、函数)都能读写;局部变量(Local Variable)只在定义它的 POU 内部有效。高速装配线的典型做法是:与硬件直接绑定的 I/O 变量、跨工位共享的状态与配方数据用全局变量;单个功能块内部的中间计算、循环计数、临时标志用局部变量。

在 Sysmac Studio 中,全局变量在“全局变量表”中定义,需要指定名称、数据类型、初值和 AT 地址(如 AT %I0.00 对应输入位)。局部变量在 POU 的变量声明区定义,不需要 AT 地址。一个常见错误是把所有变量都建成全局变量,导致同一名称在不同工位被重复赋值,出现“变量被谁改的”无法追踪的问题。建议约定:全局变量加前缀 g_,局部变量加前缀 l_,例如 g_Station1_Ready、l_CylinderTimer。

二、结构体:把相关变量打包

结构体(Structure)把多个不同数据类型的变量组合成一个整体。高速装配设备中,一个气缸通常需要“伸出到位、缩回到位、伸出命令、缩回命令、动作超时”等成员,若逐个定义会非常零散。用结构体可以这样组织:

TYPE ST_Cylinder :
STRUCT
    bExtendCmd   : BOOL;   // 伸出命令
    bRetractCmd  : BOOL;   // 缩回命令
    bExtended    : BOOL;   // 伸出到位
    bRetracted   : BOOL;   // 缩回到位
    tTimeout     : TIME;   // 动作超时时间
    bAlarm       : BOOL;   // 超时报警
END_STRUCT
END_TYPE

定义好类型后,声明变量 g_Cyl_Load : ST_Cylinder;,访问成员时写 g_Cyl_Load.bExtendCmd。这样命名清晰、便于批量复制到多个工位,也方便把整个结构体作为功能块输入输出参数传递。

三、数组:批量处理同类对象

当设备有 8 个相同工位时,用数组比定义 8 个独立变量更高效。Sysmac Studio 支持一维和多维数组,声明格式为 ARRAY[0..7] OF 数据类型。例如:

g_StationReady : ARRAY[0..7] OF BOOL;
g_PartCount    : ARRAY[0..7] OF UINT;
g_Cylinder     : ARRAY[0..7] OF ST_Cylinder;

数组配合 FOR 循环可以一次性完成 8 个工位的状态扫描或计数清零。需要注意数组下标从 0 开始,越界访问在 NJ/NX 中会触发异常,因此循环变量要严格控制在 0..7 范围内。对于高速装配线,数组还常用于缓存视觉检测结果,例如 g_VisionResult : ARRAY[0..7] OF ST_Vision。

四、用户自定义数据类型(UDT)

用户自定义数据类型是结构体、数组、枚举等组合的统称。除了上面的 ST_Cylinder,高速装配设备中还常用枚举(ENUM)表示工位状态,用联合(UNION)处理同一地址的不同解释。枚举示例:

TYPE E_StationState :
(
    eIdle    := 0,
    eReady   := 1,
    eRunning := 2,
    eAlarm   := 3
);
END_TYPE

使用枚举后,程序里写 IF g_StationState[0] = eRunning THEN 比写 = 2 可读性高得多,也避免了“魔法数字”。UDT 一旦修改,所有引用它的变量会同步更新,这是它相对普通结构体的最大优势。

五、变量作用域与数据流示意

下图展示高速装配设备中全局变量、局部变量、结构体与数组在程序中的位置关系:全局变量表连接硬件 I/O 与各工位 POU,局部变量只在 POU 内部使用,结构体与数组作为复合类型承载工位数据。

高速装配设备变量作用域与数据类型关系 全局变量表 g_StationReady[0..7] g_Cylinder[0..7] g_VisionResult[0..7] g_Recipe : ST_Recipe AT %I / %Q 硬件绑定 跨工位共享 硬件 I/O 传感器 / 电磁阀 / 伺服 视觉 / 机器人接口 POU(程序/功能块) 工位1 程序 l_Timer, l_Index 局部变量 工位2 程序 l_Timer, l_Index 局部变量 FB_Cylinder 功能块 l_Step, l_Timeout 局部变量 读写 用户自定义数据类型 ST_Cylinder 结构体 bExtendCmd / bExtended tTimeout / bAlarm E_StationState 枚举 eIdle / eReady eRunning / eAlarm ARRAY[0..7] OF ... 批量工位数据 类型定义 作用域规则:全局变量全项目可见,局部变量仅 POU 内有效;结构体/数组/枚举属于 UDT,用于组织复合数据。 命名建议:全局 g_ 前缀,局部 l_ 前缀;数组下标从 0 开始,循环边界必须严格匹配声明范围。 高速装配要点:用数组批量扫描工位,用结构体打包气缸/视觉数据,用枚举替代魔法数字。

六、在高速装配设备中的实际应用建议

以一个 8 工位转盘装配机为例,可以这样组织变量:

  • 全局变量:g_StationReady : ARRAY[0..7] OF BOOL 表示各工位就绪;g_Cylinder : ARRAY[0..7] OF ST_Cylinder 管理 8 个压装气缸;g_Recipe : ST_Recipe 保存配方参数。
  • 局部变量:每个工位程序内部用 l_Step : INT 记录步序,l_Timer : TON 做动作超时计时,这些变量不会互相干扰。
  • UDT:定义 ST_Vision 结构体,包含 bOK : BOOL、rOffsetX : REAL、rOffsetY : REAL,视觉结果直接写入 g_VisionResult[i]。

需要特别注意的是,高速装配线对扫描周期敏感。全局变量虽然方便,但过多使用会增加耦合;局部变量访问速度更快,且不会意外被其他 POU 修改。建议把“只在本工位使用”的数据一律放局部变量,把“需要跨工位或与 HMI 交互”的数据放全局变量。结构体和数组在传递时是按值还是按引用,取决于具体实现,功能块输入输出建议用 VAR_IN_OUT 传递结构体,避免大数组复制带来的周期抖动。

在 Sysmac Studio 中,修改 UDT 后需要重新编译整个项目,所有引用该类型的变量会自动更新。建议在项目初期就规划好结构体成员,避免后期频繁改动导致大量程序需要重新验证。
数组越界在 NJ/NX 中会触发“数组下标越界”异常,严重时会导致控制器停止运行。使用 FOR 循环遍历数组时,务必确认循环上限与数组声明范围一致,例如 FOR i := 0 TO 7 DO 对应 ARRAY[0..7]。