2. 产线状态机的基本概念

在产线控制程序里,状态机不是一种“高级写法”,而是一种把设备行为讲清楚的组织方式。它把“设备现在处于什么情况”“什么条件下允许改变”“改变时具体做什么”拆成几个明确的概念。只要这几个概念定义清楚,程序逻辑就能从大量 if/else 中解放出来,变成可读、可查、可维护的结构。

本节围绕五个核心概念展开:状态(State)、事件(Event)、转移(Transition)、动作(Action)、守卫条件(Guard)。理解它们之间的关系,是后续编写自动/手动模式管理、故障恢复和节拍控制的基础。

一、状态:设备“此刻在做什么”

状态描述的是设备在一个相对稳定阶段中的行为特征。它不是某一个输出点的通断,而是一组输出、内部标志和等待条件的集合。例如一条包装产线,可以定义如下状态:

  • Idle(待机):电机停止,气缸复位,等待启动命令。
  • Homing(回零):各轴依次寻找原点,完成后进入 Ready。
  • Ready(就绪):原点已建立,允许启动自动循环。
  • Running(运行):按节拍执行送料、压装、检测、下料。
  • Paused(暂停):循环停在安全位置,输出保持,等待恢复。
  • Fault(故障):出现急停、超时或安全门打开,输出进入安全状态。

状态划分要遵循两个原则:一是互斥,同一时刻只能处于一个状态;二是可观察,每个状态应有明确的输出表现或 HMI 指示,便于操作员判断。状态名建议使用英文或拼音缩写,并在 HMI 上显示中文注释,避免现场误解。

二、事件:推动状态改变的外部或内部信号

事件是状态机“被唤醒”的触发源。它可以是按钮按下、传感器到位、定时器超时、报警复位,也可以是上位机下发的命令。事件本身不决定“能不能转”,它只是“提出申请”。例如:

  • StartBtn:启动按钮上升沿。
  • PartAtPos:工件到位光电信号。
  • CycleDone:本循环完成标志。
  • FaultReset:故障复位按钮。
  • Timeout_5s:某动作超过 5 秒未完成。

在 PLC 中,事件通常用上升沿指令提取,避免电平持续期间被反复触发。例如三菱的 LDP、西门子的 P_TRIG,或统一写成 R_TRIG 功能块。事件应尽量“短促”,只在一个扫描周期内有效,防止状态机被同一事件连续推动。

三、转移:从当前状态到下一状态的有向连接

转移是状态之间的“箭头”。它由源状态 + 事件 + 守卫条件共同决定,指向目标状态。没有事件,状态不会自己改变;没有守卫条件,事件来了也可能被拒绝。转移的典型表达是:

Running --[StopBtn AND Guard_SafePos]--> Paused
Running --[FaultActive]-----------------> Fault
Fault   --[FaultReset AND Guard_NoAlarm]--> Idle

注意转移是“瞬时”的:一旦条件满足,状态机在一个扫描周期内完成源状态退出和目标状态进入。因此转移条件必须用边沿或一次性标志,不能用电平长期保持,否则会出现“刚进目标状态又被同一条件推走”的抖动。

四、动作:进入、退出或停留时执行的具体操作

动作是状态机真正“干活”的部分。按执行时机可分为三类:

  • 进入动作(Entry Action):进入某状态时执行一次。例如进入 Running 时启动主电机、打开允许输出。
  • 退出动作(Exit Action):离开某状态时执行一次。例如退出 Running 时停止主电机、关闭使能。
  • 停留动作(Do Action):状态保持期间每个扫描周期执行。例如 Running 中根据节拍依次触发送料、压装、检测。

动作要尽量“短”和“确定”。如果某个动作需要等待,应把它拆成独立状态,而不是在动作里写延时循环。例如“压装并保压 2 秒”应拆为 Pressing 和 Holding 两个状态,用定时器事件转移,这样 HMI 能显示当前阶段,故障时也能定位到具体步骤。

五、守卫条件:转移的“门禁”

守卫条件是一个布尔表达式,只有为真时,事件才能触发转移。它回答的是“现在允许转吗”。守卫条件通常包括:

  • 安全条件:安全门关闭、急停未触发、气压正常。
  • 位置条件:气缸已缩回、轴已到安全位。
  • 模式条件:当前处于自动模式、手动模式或维护模式。
  • 互锁条件:另一工位未占用、下游未满料。

守卫条件与事件的区别可以用一句话概括:事件是“什么时候”,守卫是“可不可以”。例如 StartBtn 是事件,Mode == Auto AND Guard_Safe 是守卫。两者同时满足,转移才发生。

产线状态机核心要素关系图 Idle 待机 Running 运行 Paused 暂停 Fault 故障 StartBtn Guard: 安全就绪 StopBtn Guard: 安全位 ResumeBtn + Guard FaultActive Guard: 任意故障 FaultReset Guard: 无报警 图例说明 正常转移(事件 + 守卫) 故障转移 恢复转移 状态节点:蓝色=待机/就绪,绿色=运行,黄色=暂停,红色=故障

六、状态机在产线控制中的典型表达方式

在 PLC 程序中,状态机最常用的表达方式是整数状态变量 + CASE 语句。用一个 INT 或 DINT 变量保存当前状态编号,每个扫描周期先处理转移条件,再根据新状态执行对应动作。典型结构如下:

// 状态编号定义
// 0=Idle, 1=Homing, 2=Ready, 3=Running, 4=Paused, 5=Fault

CASE #State OF
    0:  // Idle
        IF #StartBtn AND #Guard_Safe THEN
            #State := 1;   // 转 Homing
        END_IF;

    1:  // Homing
        // 回零动作
        IF #HomingDone THEN
            #State := 2;
        END_IF;

    3:  // Running
        // 节拍动作
        IF #StopBtn AND #Guard_SafePos THEN
            #State := 4;
        END_IF;
        IF #FaultActive THEN
            #State := 5;
        END_IF;

    5:  // Fault
        // 输出安全状态
        IF #FaultReset AND #Guard_NoAlarm THEN
            #State := 0;
        END_IF;
END_CASE;

这种写法的好处是:状态一目了然,转移条件集中,动作与状态绑定。调试时只需观察 State 变量,就能知道设备卡在哪一步。HMI 上也可以直接用状态编号显示中文状态名,操作员不需要理解程序内部结构。

另一种常见表达是状态图(State Diagram),用于设计阶段和文档交付。它用圆圈表示状态、箭头表示转移、箭头旁标注事件和守卫条件。对于多工位、多模式产线,状态图能提前暴露“死锁”“漏转移”“守卫冲突”等问题,比直接写代码更高效。

七、一个容易混淆的点:状态与模式的区别

状态机管理的是“设备当前处于哪个阶段”,而模式管理的是“设备按哪套规则运行”。自动模式和手动模式可以共用同一套状态机,但守卫条件和动作内容不同。例如手动模式下,StartBtn 可能直接触发某个气缸动作,而不进入 Running 状态;自动模式下,StartBtn 才推动 Idle→Homing→Ready→Running 的完整链路。

因此,在程序里通常把“模式”作为守卫条件的一部分,而不是把模式本身当成状态。例如:

IF #Mode = 1 AND #StartBtn AND #Guard_Safe THEN
    #State := 1;   // 仅自动模式允许进入回零
END_IF;

这样状态机保持单一职责,模式切换不会打乱状态编号,后续增加“维护模式”“单步模式”时也只需扩展守卫条件,不必重写整个状态结构。

实践建议:初次编写状态机时,先用纸或画图工具画出状态图,标出每个状态的进入动作、退出动作和停留动作,再逐条写出转移条件。确认没有“无出口状态”和“无入口状态”后,再翻译成 CASE 代码。这样能减少大量现场调试时间。

总结来看,状态、事件、转移、动作、守卫条件这五个概念构成了状态机的完整语义:状态回答“现在在哪”,事件回答“什么时候动”,守卫回答“能不能动”,转移回答“往哪动”,动作回答“动了做什么”。把这五件事分别写清楚,产线控制程序就会从“能跑”走向“可读、可查、可维护”。