市场上有许多PLC一般都支持IEC 61131-3标准的五种编程语言[1],其中梯形图(LD)是比较常见的一种[2]。梯形图编程界面下会提供一种SR或RS函数块,其功能的具体解释见[3]。简单地说,SR函数块接受两个IO信号,一个称为S(Set),另一个称为R(Reset);同时输出一个IO信号Q。在程序刚开始时,该函数块的输出Q值为0。当S置1后,函数的输出Q值会被置1,且即使输入S的值已经变为0,Q值仍然会保留在1,直到R值置1了,输出的Q值才会被归0。

下图大致展示一下SR或RS函数块的逻辑:

该功能是把设置(Set)和重置(Reset)的功能分别用两个输入实现的。这个逻辑称为互锁模式[4]。但在家用电器,以及工业机器上,经常需要用同一个输入进行自锁模式的控制,例如按下按钮,设备启动,松开后保持通电状态,但再按一下按钮后就应断电[4]。

这样的逻辑,在梯形图中,可以通过巧用SR函数来实现。

一、线圈(Coil)与触点(Contact)互用

通常在PLC中,线圈(Coil)是用于输出计算结果的,而触点(Contact)是用于输入的,即采集变量值的。但PLC的输出是保存在内存中的某个变量的地址的。因此,通过把触点对应的变量地址设为线圈的对应的变量地址,则可以实现将PLC的线圈,即计算出的结果用于程序的某个步骤的输入。这样的编程思维可称为"继电器"(relay)[5]。

如图所示,变量Internal relay 1在程序(1)中是线圈输出,同时在程序(3)中是触点输入。也就是说,程序(1)计算出来的Internal relay 1的值在程序(3)中被使用。这样的编程方式不仅可以减少程序的长度,而且可以实现一些特别逻辑,例如本文介绍的单按钮自锁功能的逻辑。

自锁功能的逻辑,本质上说,是在输出值为1时,通过输入来重置(Reset);在输出值为0时,通过输入来设置(Set)。因此,需要实现的逻辑是:

(1)当输出值为0时,按下按钮,SR函数块的S输入值应该为1,但R输入为0。

(2)当输出值为1时,按下按钮,SR函数块的R输入值应该为1,但S输入为0。

(3)不按按钮时,SR函数块的S和R输入值均应该为0。

所以,假定输出的控制灯光的值的变量为res,外部输入即按钮的值的变量为button,则可以这样设计程序:

在该程序中,res既是输入也是输出。对于通向S的分支,res作为常闭触点,当res为0时结果为1,故此时按下按钮,S值变为1,灯光通电。而对于通向R的分支,res作为常开触点,当res为1时结果为1,故此时按下按钮,R值变为1,灯光断电。

现在将该程序导入Arduino Opta PLC,观察实验结果。

如图,上方的USER按钮和变量button关联,下方的指示灯和res变量关联。实验结果如下:

从gif图中可看出,实验结果并非理想。按住按钮时,指示灯不断闪烁,而松开按钮时,指示灯可能保持高亮,也可能熄灭。出现该问题的原因如下:

由于按住按钮时,button值始终保持在1,故而当res值在0和1之间变化时,无论值为0还是1,S和R至少有一个会被触发,且是轮流被触发(为0时触发S,为1时触发R)。所以res会在0和1之间反复横跳。而按钮松开时(button=0),S和R均不被触发,输出值res取决于松开前的状态。因此,若要解决该问题,就要确保当按钮按下后,直到按钮松开并再次按下前,S和R都不应被触发,这样才能真正实现自锁功能。下一章节讲述如何实现该功能。

二、P触点

PLC编程语言LD梯形图中,除了常开和常闭触点外,还有P触点和N触点。这两种触点的作用见[6]。简单的说,P触点就是在相应变量由0变1的一瞬间输出1,其余的时间都输出0。因此,当一个按钮关联了P触点,只有在按钮按下的一瞬间,该触点才输出1,而当按钮按住不放时,在PLC程序的下一轮扫描周期,该触点将输出0。若要让该触点再次输出1,唯一的办法就是松开按钮,然后再次按下,此时0到1的变化会再次出现。

因此,设计按钮自锁模式的PLC程序,若要防止出现按钮按住时res值反复横跳的现象,应当将涉及按钮的触点设为P触点,这样只有在按钮按下的一瞬间,S或R才会被触发。

此时,在按钮按下,即button值从0变为1的一瞬间,该触点输出1,所以当res值为0时,S被触发;当res值为1时,R被触发。在按钮被释放并再次按下前,button对应的触点值始终为0,所以S和R均不会被触发,res值也不会改变。

从gif图中可看出,该逻辑正确实现了按钮自锁模式。

三、初始值

Arduino Opta PLC的程序分为两部分:第一部分是init,即PLC刚启动时运行的程序,只执行一次,用于初始化一些变量;第二部分是loop,即PLC在初始程序完成后,重复运行的程序[7]。

在本程序中,若要实现PLC启动时,指示灯一开始亮起​​​​​​​,按下按钮后才关闭的逻辑,应当在初始函数中加入变量的初始化值。通常,对于布尔(bool)型变量,默认初始值为0。故若要让res的初始值为1,可用以下程序作为初始程序:

运行一个梯形图程序,可视为值1从左向右流动,直到出现值为0的触点为止。若值1在到达线圈时仍未变为0,则线圈输出值为1。

然而,由于SR程序块的默认输出值为0,因此若要让res值,即指示灯在按下按钮前一直输出1,则需让res值在未按下按钮时,也作为使S被触发的"或"条件之一。

基本逻辑是:S应有两个触发条件,符合一条就可触发:

(1)res值为0时按下按钮的一瞬间

(2)按钮未按下时,res值为1。

程序如下:

实验结果:

PLC刚启动时,指示灯亮起。之后运行自锁开关的逻辑。

四、总结

在PLC梯形图编程中,若要通过SR函数块实现按钮自锁模式逻辑,需要把线圈(Coil)和触点(contact)互用,且触点应使用P触点。另外,可以通过初始函数让输出值默认为1,但除此之外,在SR函数块的S输入中,还应增加一个涉及线圈值以及常闭触点的逻辑。

五、参考资料

[1]https://docs.arduino.cc/software/plc-ide/

[2]​​​​​​​https://blog.claves.cn/archives/7590

[3]http://www.dzkfw.com.cn/Article/plc/3200.html

[4]https://zhidao.baidu.com/question/137013649633778045.html

[5]https://basicplc.com/plc-programming/

[6]https://www.cnblogs.com/jackchog/p/5828778.html

[7]https://docs.arduino.cc/software/plc-ide/tutorials/plc-programming-introduction/

Logo

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

更多推荐