PLC基础

我们先来看一个简单的程序。
输入输出控制

一个输入控制一个输出,这时候我们如果需要将输出保持,就需要一些改造。

输入输出保持控制

这个时候我们发现当X0 OFF时,Y0还是处于ON状态,即达到了保持的目的。
但我们不能一直让Y0保持ON,还是需要对Y0的状态进行控制的,这时要加入一个断开的控制。

启动、保持、停止

这就是比较经典的启动、保持、停止电路。

但是在PLC程序中,我们比较少用这样的写法,这个写法算是电气时代的遗留,给电气工程师过度之用。

下面看看PLC中的写法。

SET/RESET

这样X0为启动,X1为停止,Y0为输出,语义就相对清晰了。下面我们加上注释。语义会更明显。

在这里插入图片描述

语义不明,即逻辑不明,是写程序和调试程序最大的敌人。

现在有了基础结构,我们用这个结构写一个跑马灯程序。

跑马灯

这是一个间隔10S的跑马灯程序。为了进一步说明,我们用状态图对上面的程序进行表达。

有向图

在这里,我们对定时器进行了抽象,即定时器与动作在逻辑上是等价的。在实际应用中,这个动作,可以是定时器,也可以是气缸动作,也可以是伺服运动等等,甚至可以是多个动作组成的动作集合。

到这里我们完成了PLC的基础部分,用这个逻辑,我们可以无限延展下去,一般的程序,完全可以用这个逻辑扩展。

那我们看看可不可以在上图的基础上,进一步抽象。我们换一种表达方式。二维图表。

状态1状态2状态3
动作1条件1->状态2
动作2条件2->状态3
动作3条件3->状态1

在这里我们看到了与状态图不太一样的视角,但是两种表达是等价的。那这个图表对我们有什么用呢?
我们在这个图表上进一步抽象,给每一步动作加上一个序号看看。

序号状态1状态2状态3
100动作1条件1->状态2
110动作2条件2->状态3
120动作3条件3->状态1

那这幅表格对我们写程序有什么意义呢,我们可以根据这个表格,对我们上面的程序进行一下改造。

操作票模式梯形图版

这样我们将程序改造成,序号、状态、条件、序号转移,写在一起;而动作单独分开。
这样的好处是,我们可以直接从表格出发,直接写程序,逻辑更严谨的同时,也不会增加心智负担。
并且我们将动作与之分离,动作改写更加方便,尤其是多个动作组成的动作组等情况。

我们来看看这种情况用ST表达的样式。

操作票模式ST版

在表达上更加简洁和直观,如果有从高级编程语言兼职PLC的,可以参考一下,不见得一定用梯形图来表达。

这个模式,被称为操作票模式,序号即是操作票,我个人更愿意称之为状态机竖着写

那么状态机是什么?

状态机

“一般来说,在理论上,你需要知道如何计算”时间复杂度“和”空间复杂度“(time and space complexity);如果你要写一个解析器,可能还需要知道状态机(state machine)的概念;除此之外,并不需要知道特别多的理论。”——《黑客与画家》

在plc编程中,极少需要讨论数据结构以及算法的复杂度问题,也不是本文讨论的主题。我们主要看状态机。

状态机百科

状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。有限状态机简写为FSM(Finite State Machine),主要分为2大类:

第一类,若输出只和状态有关而与输入无关,则称为Moore状态机

第二类,输出不仅和状态有关而且和输入有关系,则称为Mealy状态机

以上是百科给的相关资料,我们在PLC只研究第二类。

状态机综述

  1. 状态机是有向图形,由一组节点和一组相应的转移函数组成。
  2. 状态机通过相应一系列事件而“运行”。
  3. 每个事件都在属于“当前”节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。
  4. 函数返回“下一个”(也许是同一个)节点。
  5. 这些节点中至少有一个必须是终态。当到达终态,状态机停止。

有限状态机是一种概念性机器,它能采取某种操作来响应一个外部事件。具体采取的操作不仅能取决于接收到的事件,还能取决于各个事件的相对发生顺序。之所以能 做到这一点,是因为机器能跟踪一个内部状态,它会在收到事件后进行更新。为一个事件而响应的行动不仅取决于事件本身,还取决于机器的内部状态。另外,采取的行动还会决定并更新机器的状态。

这样一来,任何逻辑都可建模成一系列事件/状态组合。

下面这个就是状态机的有向图形的表达形式,之前我们已经见过了。

有向图

状态机四要素

现态、条件、动作、次态

  1. 现态:是指当前所处的状态
  2. 条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态转移。
  3. 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新的状态。
  4. 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

在上文中,事件有两种,一种是启动事件;另外一种是定时器的计时事件。
上文中条件满足时,没有触发动作,都是进行的状态转移。动作都是在现态下执行的。

状态机表示方法

  1. 一组状态集(states)
  2. 一个起始状态(start state)
  3. 一组输入符号集(alphabet)
  4. 一个映射输入符号和当前状态到下一状态的转换函数(transition function)的计算模型
  5. 状态、状态转换函数、与动作映射列表

本文中的状态集合为:(状态1,状态2,状态3)

起始状态,在这里并没有明确表达,在ST表达中,我们给了一个默认的0,即开机之后,未启动之前,状态值为0,这算是本文的起始状态,也是有向图中的第一个起始点。

一组输入符号集,在本例中,集合中只有一个元素,启动。实际工作中,这个集合可能比较大,几十几百都有可能。

计算模型,这里我们是通过梯形图或者ST语言来表达的。

映射列表,这个可以看作是状态机的核心,因为如果写不出状态机的映射列表,那么就说明对业务梳理的不到位,有含糊的地方,在写程序的时候,就会不知所措。

我们可以用有向图,也可以用二维表来表示映射列表。

状态1状态2状态3
动作1条件1->状态2
动作2条件2->状态3
动作3条件3->状态1

现在再看这个表格,不知道大家有没有更清晰一些。
之前我们是从上向下的分析这个表格,写出了操作票模式的程序,那我们可不可以从左到右理解这个表格?我们横着写试试。

状态机在PLC中的应用之横着写

解释器模式1

这是按照横着阅读映射列表写出来的程序,但是这个有一点不好的地方在于,状态和动作(此处为计时器)是耦合在一起的,如果遇到的是一个多个动作的集合,程序就会显得很啰嗦。

下面是改造。

解释器2

通过增加一个解释字,我们将应用层与驱动层进行了分离。

应用层,这个层主要用来管理状态,事件,以及状态转移。
驱动层,只按照解释字进行动作,不用去管应用层的逻辑。
这样就大大的降低了心智成本。

这种写法就是解释器模式,我个人喜欢称之为状态机横着写,当然在每个人都有不同的称呼,比如有人称之为卡条件等等。

我们再看看解释器模式在ST中的表达。

在这里插入图片描述

至此,我们关于状态机在PLC中的两种应用模式就讨论完了。

当然状态机不止这两种,比如,我们在本例中,由于写得比较简单,所以实质上这个状态机也可以用独热码表示。
独热码在PLC中我们可以用一个字进行表示,然后用移位指令进行状态管理,也是可以的。

BUG

没错,写程序,怎么可能没有bug呢。

在本文中,由于只专注于讨论状态机,那么关于启动相关的状态,我们是忽略的,这就导致多次点击启动,会出现同时出现多状态的情况,这个需要在实际工作中注意。这里不做讨论,当然最后的ST表达的解释器模式实际上是解除了这个bug的,大家有兴趣可以自行尝试。

文中提及的程序在这里下载

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐