第四章 梯形图编程实战:梯形图基础、运动控制逻辑编写、状态机设计模式

4.1 梯形图,其实没那么玄乎

说实话,很多刚入行的工程师一听到「梯形图」三个字,就觉得这是老古董。我当年也有这想法——直到我在一条高速包装线上被现实狠狠教育了一回。

梯形图是什么?说白了,就是一种用图形表示逻辑的编程语言。左边是母线,右边是线圈,中间是触点。你想想看,这不就是继电器电路的翻版吗?对,它本来就是给电气工程师准备的,让他们不用学C语言也能写程序。

我个人习惯把梯形图分成三块来看:

  • 输入条件:常开触点、常闭触点、上升沿、下降沿
  • 逻辑处理:串联(AND)、并联(OR)、自锁、互锁
  • 输出执行:线圈、置位/复位、定时器、计数器

嗯,这里要注意:梯形图的执行顺序是从左到右、从上到下。这一点和高级语言完全不一样。我在项目中遇到过有人把两个互锁的线圈写在同一行,结果PLC一运行就打架,设备直接报警停机。

核心原则:梯形图里,同一线圈不要在两个不同分支里同时输出。除非你用了置位/复位指令,否则后果自负。

4.2 运动控制逻辑怎么写?从点动到连续

运动控制,说白了就是让电机按照你的想法转起来、停下来、转到指定位置。在包装线上,最常见的动作就是:

  1. 点动(Jog)—— 调试时用,按着转,松手停
  2. 回原点(Home)—— 每次开机必须做
  3. 定长运动(Index)—— 切膜、送料、封口
  4. 连续运行(Run)—— 生产线正常跑

我给你们看一段我实际用过的梯形图逻辑,这是点动和连续运行的切换:

// 点动模式
||---[ 点动按钮 ]-------------------( 电机正转 )---|
||---[ 急停按钮/常闭 ]---[ 点动按钮 ]---( 电机反转 )---|

// 连续运行模式(带自锁)
||---[ 启动按钮 ]---[ 停止按钮/常闭 ]---( 运行中 )---|
||---[ 运行中 ]-----------------------------------( 运行中 )---|

// 输出合并
||---[ 点动模式 ]---[ 点动正转 ]---( 电机正转输出 )---|
||---[ 连续模式 ]---[ 运行中 ]---[ 正转方向 ]---( 电机正转输出 )---|

你看,逻辑其实不复杂。但坑在哪里?坑在「模式切换」的时候。我曾经遇到过操作工在点动模式下没松手,直接切到连续模式,电机突然全速跑起来,差点把模具撞坏。

避坑指南:模式切换时,一定要先强制停止所有输出,再切换。我后来在程序里加了一个「模式切换中」的中间变量,切换时先复位所有输出,延时100ms再激活新模式。

4.3 状态机设计模式——让逻辑不再乱成一锅粥

说实话,我刚入行那会儿写梯形图,就是一个字:堆。按钮多了就加行,动作多了就加分支。结果程序写到后面,自己都看不懂了。直到我学会了状态机设计模式,才真正把逻辑理清楚。

状态机是什么?就是给设备定义几个「状态」,每个状态下只处理该做的事。比如一个包装机的送膜机构,可以分成:

状态编号 状态名称 说明
S0 空闲 等待启动指令,所有输出复位
S1 回原点 执行回零动作,完成后自动跳转
S2 送膜 定长送膜,到位后停止
S3 封口 封口气缸动作,完成后返回S0
SE 报警 任何异常进入,手动复位后回S0

用梯形图实现状态机,核心就三句话:

  • 当前状态判断:用比较指令判断当前是哪个状态
  • 状态转移条件:满足条件时,把状态寄存器的值改成下一个状态编号
  • 状态动作执行:每个状态下只执行对应的输出

我给你们画个流程图,你们一看就明白:

S0: 空闲 S1: 回原点 S2: 送膜 S3: 封口 SE: 报警 启动指令 回零完成 送膜到位 封口完成 异常 手动复位

你看,状态机的好处就是:每个状态只管自己的事,不会乱。我在实际项目中,把状态编号存在一个叫 D100 的数据寄存器里,然后用比较指令判断当前状态,用 MOV 指令做状态跳转。

我的小技巧:状态编号用十进制,从0开始。0代表空闲,1、2、3...代表工作状态,99代表报警。这样调试时看数据寄存器,一眼就知道设备在干嘛。

4.4 实战案例:一个简单的送料机构

好了,理论说完了,咱们来点实际的。假设你要控制一个送料机构,动作流程是:

  1. 按下启动按钮,电机正转送料
  2. 传感器检测到物料到位,电机停止
  3. 气缸伸出推料
  4. 气缸缩回,等待下一次启动

用状态机写梯形图,大概长这样:

// 状态寄存器: D0
// 状态定义: 0=空闲, 1=送料, 2=推料, 3=缩回

// ---- 状态转移逻辑 ----
// S0 -> S1: 启动按钮按下
||---[ D0 == 0 ]---[ 启动按钮 ]---( MOV 1 TO D0 )---|

// S1 -> S2: 物料到位传感器
||---[ D0 == 1 ]---[ 物料到位 ]---( MOV 2 TO D0 )---|

// S2 -> S3: 气缸伸出到位
||---[ D0 == 2 ]---[ 伸出到位 ]---( MOV 3 TO D0 )---|

// S3 -> S0: 气缸缩回到位
||---[ D0 == 3 ]---[ 缩回到位 ]---( MOV 0 TO D0 )---|

// ---- 状态动作执行 ----
// S1: 电机正转
||---[ D0 == 1 ]---( 电机正转 )---|

// S2: 气缸伸出
||---[ D0 == 2 ]---( 气缸伸出 )---|

// S3: 气缸缩回
||---[ D0 == 3 ]---( 气缸缩回 )---|

你看,逻辑是不是特别清晰?每个状态做什么、什么时候跳转,一目了然。我后来把所有项目的程序都改成了状态机结构,调试时间至少缩短了一半。

注意:状态机一定要加「超时保护」。每个状态进入后开始计时,如果超过设定时间还没跳转,强制进入报警状态。我曾经因为一个传感器松动,设备卡在送料状态一直转,差点烧了电机。

好了,这一章的内容就到这儿。梯形图不难,难的是把逻辑理清楚。状态机设计模式,说白了就是给程序画个地图,让代码按图索骥,不会迷路。你们回去可以拿自己的项目试试,把原来的面条式逻辑改成状态机,保证你会回来感谢我。

专注资料整理