首页 > 未分类 > 模拟工控机的模拟(2):工控机的编程
2017
09-16

模拟工控机的模拟(2):工控机的编程

模拟工控机的模拟(2):工控机的编程 - 第1张  | Processing编程艺术

 

 

 

 

 

 


 

最早工控机是为了替代基于继电器的控制电路而被发明的。一般继电器有一个电磁铁叫做线圈,有几组三片弹簧金属叫做接点,其中两片在初始状态下受弹簧压力接触。当线圈得电时,带动金属片动作,原来接触的两片分离,原来未接触的两片接触。继电器不同于三极管,不具备信号放大作用,我觉得在应用上是一种比三极管更纯粹的逻辑元件。

传统的继电器控制电路原理图看起来可能是这样的:

模拟工控机的模拟(2):工控机的编程 - 第2张  | Processing编程艺术

这里用拨钮SW1控制AUT继电器,如果AUT得电,则继电器RY的得电条件由FLG接点控制。FLG的接通条件由另外的逻辑控制,这里忽略。如果AUT不得电,则继电器RY的得电条件由拨钮MAN控制。继电器RY的接点控制接线柱Y0是否和R线接通,如果接通,则现场接线接到这个接线柱的动作装置就能得电。如果它是一个控制自来水龙头的电磁阀,那么水就喷出来了。如果这个阀门控制的是液压件管路,那么可能就能打开一个仓库门,或者把客厅地板抬起来。

这里想像的是一个非常简单的手自动切换控制。SW1拨钮开关的边上可能会被贴上“自动/手动”的标签,MAN则可能会被贴上“打开/关闭”的标签


制作这个简单的电路需要两个继电器,两个拨钮开关和导线及接线柱若干。但如果我们把继电器和开关,甚至导线的是否和R接通的情况,都看作计算机中一个位的0或1的概念的话,然后想像我们有一个1位单片机,它有一个1位工作寄存器,它能保存数个读取的位状态,且动作类似堆栈,则这个电路就能以类似汇编的伪码表达出来。

它可能是这样的:

;--input 
LD SW1;..推SW1状态到工作寄存器
OUT AUT;..送工作寄存器状态到AUT

;--operate
LD FLG;..推FLG状态到工作寄存器
AND AUT;..把工作寄存器状态与AUT做与操作

LD MAN;..推MAN状态到工作寄存器
ANI AUT;..把工作寄存器内容与AUT做与非操作

ORB;..送出工作寄存器内所有状态做或操作后推回工作寄存器
OUT RY;..送工作起寄存器状态到RY

;--output
LD RY;..推RY状态到工作寄存器
OUT Y0;..送工作寄存器内容到Y0

实际上这并不是伪码,在我用的PLC厂家提供的软件上它是可以编译的,编译后的画面是这样的:

模拟工控机的模拟(2):工控机的编程 - 第3张  | Processing编程艺术

然后它可以在工控机上运行,做出和继电器电路完全一样的动作。

这个跟电路原理图几乎没有差异的东西叫做梯形图语言(… …据说是因为左右的火线和零线与中间电路配起来看起来像是个梯子)。在个人电脑普及以前,即使把基于继电器的控制系统替换成工控机系统,它的制作和维护仍是只能由没有计算机知识的电工去做,所以传统工控机编程器的第一大目标就是让画出来的电路图直接变成可运行的程序。

几十年以前,工控机编程要靠手持的专用编程设备把电器符号一个一个画上屏幕才能完成。但即使是现在编程器已经全面软件化时代,不少厂家的默认语言仍是梯形图。


如果我们说,现在要做一个模拟现实电路动作的模拟器Sketch ,那可能是个大任务。但如果只是要把继电器电路的逻辑关系表达出来,就像上面的伪码一样,是非常简单的:

class SxPLC{
  //--
  boolean SW1,AUT,FLG,MAN,RY,Y0;
  SxPLC(){
    SW1=false;
    AUT=false;
    FLG=false;
    MAN=false;
    RY=false;
    Y0=false;
  }
  //--
  void ccScan(){
    MAN=SW1;//--input
    RY=(FLG && AUT)||(MAN && !AUT);//--operate
    Y0=RY;//--output
  }
  void ccFilpAutoSwitch(){SW1=!SW1;}
  void ccFlipManmualSwitch(){MAN=!MAN;}
  boolean ccGetOutput(){return Y0;}
  //--
}//+++

工控机的运行和Processing 一样,都是在启动时运行基本设定后进入一个定周期的无限循环,期间再用中断处理各种其他任务。循环一个周期的动作在工控机里一般被称做Scan。在Processing  范例里,它一般是update(),或者display(),或者 refresh(),或者whatever! 所以这里只要把ccScan() 方法放到draw() 当中运行得到效果是与实际工控机的效果是一样的。

需要说明的是,工控机的内存一般不是铁板一块的,而是分成好几个域的概念。域有断电清零,断电记忆,时间,计数,输入,输出等等不同的作用。工控机编程在声明变量的时候,一般都需要指定域,指定以后硬件会自动完成数据操作。比如上面的伪码里面虽然没有出现,SW1和MAN一般是通过地址标签声明在输入域里的,Y0是声明在输出域的(在编译好的梯形图里能看到明显不同),然后只要完成硬件接线,他们会自动同步到输入输出模块所采集的输入输出状态到处理器内存。但在我们的Processing 代码里,就需要再做几个方法来模拟人手拨动拨钮和输出电压的动作。

 



最后编辑:
作者:constrain
nullpointerexception

留下一个回复

你的email不会被公开。