// 1. 定义状态枚举public enum MachineState{ Standby, // 待机 Running, // 运行 Paused, // 暂停 Alarm // 报警}// 2. 定义触发事件枚举public enum TriggerEvent{ Start, // 启动 Pause, // 暂停 Resume, // 恢复 Stop, // 停止 Error, // 报错 ClearAlarm // 清除报警}// 3. 状态机核心类public class MachineFSM{ // 当前状态 public MachineState CurrentState { get; private set; } = MachineState.Standby; // 状态转移规则(核心:当前状态+触发事件 → 新状态+执行动作) private readonly Dictionary<(MachineState, TriggerEvent), (MachineState NewState, Action Action)> _transitions = new() { // 待机状态下触发Start → 切换到运行,执行启动动作 { (MachineState.Standby, TriggerEvent.Start), (MachineState.Running, () => Console.WriteLine("执行:启动设备,发送运行指令到PLC")) }, // 运行状态下触发Pause → 切换到暂停,执行暂停动作 { (MachineState.Running, TriggerEvent.Pause), (MachineState.Paused, () => Console.WriteLine("执行:发送暂停指令到PLC,保存当前参数")) }, // 暂停状态下触发Resume → 切换到运行,执行恢复动作 { (MachineState.Paused, TriggerEvent.Resume), (MachineState.Running, () => Console.WriteLine("执行:发送恢复指令到PLC,恢复运行参数")) }, // 任意运行/暂停状态下触发Error → 切换到报警,执行报警动作 { (MachineState.Running, TriggerEvent.Error), (MachineState.Alarm, () => Console.WriteLine("执行:发送停机指令,记录报警码,上位机弹窗提示")) }, { (MachineState.Paused, TriggerEvent.Error), (MachineState.Alarm, () => Console.WriteLine("执行:发送停机指令,记录报警码,上位机弹窗提示")) }, // 报警状态下触发ClearAlarm → 切换到待机,执行清除报警动作 { (MachineState.Alarm, TriggerEvent.ClearAlarm), (MachineState.Standby, () => Console.WriteLine("执行:清除报警记录,复位PLC状态")) }, // 任意状态下触发Stop → 强制切换到待机 { (MachineState.Running, TriggerEvent.Stop), (MachineState.Standby, () => Console.WriteLine("执行:发送急停指令,复位所有参数")) }, { (MachineState.Paused, TriggerEvent.Stop), (MachineState.Standby, () => Console.WriteLine("执行:发送急停指令,复位所有参数")) }, { (MachineState.Alarm, TriggerEvent.Stop), (MachineState.Standby, () => Console.WriteLine("执行:发送急停指令,复位所有参数")) } }; // 触发事件,执行状态转移 public void Trigger(TriggerEvent trigger) { var key = (CurrentState, trigger); if (_transitions.TryGetValue(key, out var transition)) { // 执行状态对应的动作 transition.Action.Invoke(); // 更新当前状态 CurrentState = transition.NewState; Console.WriteLine($"状态更新:{CurrentState}"); } else { Console.WriteLine($"无效操作:{CurrentState}状态下无法触发{trigger}事件"); } }}// 测试调用public class Program{ public static void Main() { var fsm = new MachineFSM(); // 模拟操作流程:待机→启动→暂停→恢复→报错→清除报警→停止 fsm.Trigger(TriggerEvent.Start); // 待机→运行,执行启动动作 fsm.Trigger(TriggerEvent.Pause); // 运行→暂停,执行暂停动作 fsm.Trigger(TriggerEvent.Resume); // 暂停→运行,执行恢复动作 fsm.Trigger(TriggerEvent.Error); // 运行→报警,执行报警动作 fsm.Trigger(TriggerEvent.ClearAlarm); // 报警→待机,执行清除报警 fsm.Trigger(TriggerEvent.Stop); // 待机→待机(无变化) }}
(3)C# 上位机状态机的特点
常用实现方式:自定义字典 / 枚举(简单场景)、开源库(如 Stateless、CSharpStateMachine);
核心:将 “操作逻辑” 和 “状态转移” 解耦,上位机界面按钮点击只需触发对应事件,无需关心底层逻辑;
扩展:可结合异步编程(async/await)处理 PLC / 机械手的通信延迟,避免界面卡死。
---
2. PLC 编程中的应用
PLC 是工业控制的核心,状态机是 PLC 编程的主流范式(替代传统的顺序继电器逻辑),尤其适用于多步骤、多条件的控制流程(如产线工位流转、物料搬运)。
(1)典型应用场景
产线工位流程:上料→夹紧→加工→松夹→下料;
安全逻辑控制:门关闭→允许启动→运行→门打开→紧急停机;
设备联动控制:PLC1 触发→PLC2 执行→PLC2 反馈→PLC1 继续。
(2)梯形图 / 结构化文本(ST)示例(以西门子 S7-1200/1500 为例)
PLC 中状态机常用SFC(顺序功能图) 或结构化文本(ST) 实现,以下是 ST 语言的核心逻辑:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!