版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
把编写简单计算器作为入门的第一个范例程序,主要是因为比较简单,而且综合了HMI,数据类型,数据转换,PRG和FBD等功能块的混合等知识,个人认为还是比较适合用来快速上手的。由于是第一个范例,所以视频教程和文档说明都会比较详细(学习能力较强的可以跳着看,后面范例的说明会逐渐减少)
添加一个PLC,随便取个名字
首先是把人机界面做好,最简单的计算器需要实现加减乘除的功能,右击VISUs添加一个人机界面,名字也随便
在人机界面上拖放需要的控件(这个跟高级语言一样,但是注意是控件都是TwinCAT提供的控件,所以会有Rectangle,Line这种控件,一般TwinCAT2用的比较多,因为一个Rectangle既可以是Button,又可以是Textbox,但是TwinCAT3既然提供了更加接近高级语言的控件,就使用常规的按钮和文本框即可)
然后就是创建一个功能块了(你也可以在MAIN里面直接写,或者不创建功能块,创建FUN,PRG都可以),具体区别后面会讲到
FB本身是有输入输出的(VAR_INPUT,VAR_OUTPUT,而定义在VAR 和END_VAR之间的是临时变量,我们暂时用不上)在这个FB上右击添加Method,比如最简单的相加方法(注意返回类型LREAL就是double类型)
用同样的方法做好加减乘除,这样再主程序调用的时候就会非常方便,直接类.方法就出来了,注意FB需要实例化一个对象,我个人习惯于把变量都定义在全局变量中(至少这些变量是很多地方都要用到的)。
在具体编写某个Method的时候,注意最后只要让Method的名称赋值等于结果即可(加不加RETURN都行),这不仅仅是对于INT,LREAL这些基本类型,如果要函数输入两个数组,输出一个数组之类的也可以,这个后面会讲到,暂时还没用到
在做除法的时候,自己要判断分母是否为零(TwinCAT如果碰到非法的运算,可能会返回NaN,也可能会直接报警,例如SQRT(-1)在TwinCAT3中就会得到一个NaN的结果,而除以0就直接会报警)
我们看到了功能块的解决方法(Function Block,需要声明类的实例,稍微有点麻烦,但是一个整体的功能块能否划分给一个类,比如MathCalc包括了加减乘除,也可以继续扩展开多次方,开根号,算圆面积,算三角函数等等),在接着往下做之前,先来看一下别的做法。直接创建一个FUN(函数),这样也可以做,而且写法基本一样(到最后的Method名称=结果即可)
使用的时候不需要声明FB的实例,直接函数名即可(可以认为FUN是全局的,不是哪个类的),所以看个人的使用习惯,如果项目很小,也无所谓以后的代码复用,可以直接FUN来做,但是如果考虑一个类不断完善和代码复用,肯定还是需要用FB来的更合理(直接的FUN都是散开的,如果你有10个很基本的FUN散落在这个项目的各个位置,下次要用的时候是不是还得挨个找到,复制粘贴到新的项目?使用FB直接复制一个FB,他的所有方法就都有了)
除了FUN和FB的区别,我们还可以在FB上新建Action(Method,Property,Transition一个四种,但是最主要用的是Action和Method),新建了Action之后可以发现代码是空的啥也没有,因为Action只是一个代码片段,没有输入输出,相当于还是在执行MathCalc的一部分代码而已
如果一定要这样做也可以,但是非常繁琐,你需要对Math(FB的实例)的指定属性赋值,然后执行Math的指定Action,然后从Math的指定输出中采集结果(可想而知如果某个函数需要10个输入,你就要挨个做,肯定是不方便的)
那么Action具体干什么用?Action的好处就是可以更加有条理的归纳代码。比如MAIN程序的每一个状态里面已经有很多事情了(获取HMI的输入,变量转换,执行功能,显示输出,回到0状态等等),可以在MAIN里面新建一个Action把这些主程序逻辑结构不关系的东西都放进去,这样如果执行到Math_Add,就只需要一行就可以了。
分析完了程序结构,我们再来看人机界面的注意事项,一个文本框如果要绑定到String类型,则Text应该是%s,如果是INT类型,则%d,如果是LREAL类型,则%f,我们为了可以直接输入文本方式的数字,所以绑定到字符串类型(执行运算的时候再把字符串转成LREAL类型)
相比于Numpad就会方便很多,你可以直接键盘输入数字,结果也可以鼠标按进去之后复制结果
建议对一类功能成组,这样可以很方便的整体拖动,复制粘贴。在工具箱中搜索group即可找到,同时打开顶部的元素列表也可以批量选中一个组中的控件
为了演示数组类型的传入传入,我们以向量的点乘和叉乘为例。(本质上函数不能传出数组,但是可以传出结构体,结构体定义成只有一个数组的元素即可),这样只要输入的同样类型结构体赋值准确,就可以执行函数,同时得到的输出也放到指定类型结构体,并不比数组难用,在本例中,直接结构体.DATA[数组下标]即可读写数组元素
更多教学视频和资料下载,欢迎关注以下信息:
我的优酷空间:
http://i.youku.com/acetaohai123
我的在线论坛:
问题交流:
QQ:910358960