热门搜索:
西门子6SE64402AB222BA1
上海朕锌电气电气设备有限公司
SIEMENS西门子
做一个存放数据较大值与较小值的程序时的思考
今天上午,公司同事遇到一个编程方面的思路瓶颈问题,到我这里来问。他遇到了一个问题,就是如何将一个温度数据,通过编程方式把温度数据出现波动时的较高(较大值)和较低(较小)值,通过PLC控制程序来捕捉记录下来?我耐心听完他的描述,思考了一下,大致浮现出一个控制轮廓出来,正好手头上有的200smart PLC,可以用来描述这个过程。所谓小问题大文章,就这么简单的一个程序,我也是调整了几次才最后“定稿”的。
编程思路:
1) 初始化数据;这个是编程必须具备的“套路”,使程序能够顺利从0开始运行。
2) 做一个类似的“曲线”,我这里做了一个三角波程序;就是把一个数据从0开始逐个往上加1,加到数据的较大值,到达数据较大值后,再逐个往下减,直减到数据的较小值。我暂时测试的数据地址定义为VW0,那么,也就是定义了数据范围是+32767 ~ -32768之间的范围数据。
3) 做这么一个程序,当前值与原值(准确说就是上一次的值)比较,如果是当前值大于原值,则把当前值传送到VW4中(VW4存放着是一个较大值的数据),同样,当数据到达较大值后,开始往下减的过程。仍然是当前值与原值比较,小于的值通过传送指令把它存放到VW6中。也可以理解较大值存放在VW4中,较小值存放在VW6中。
程序:
网络1,初始化数据,目的是把参与运算的数据归一化处理;
网络2,当数据自0开始加1时,VW0 = 0,则M0.0无法置位,所以,INC_W指令激活,运行加1,实际上就是累加程序的扫描周期。当VW0逐渐增大到32767时,置位M0.0的条件满足,置位M0.0后INC_W指令使能丢失,DEC_W激活,VW0 的数据由32767开始一个周期一个周期的往下减,一直减到VW0 = -32768,M0.0的复位条件满足,DEC_W使能丢失,同时再次激活INC_W指令,如此循环进行,这样就模拟了一个相当于温度波动时的状态,虽然这个数据变化的状态不同与现实中的波动幅度,且还带有一点理论层面的数据变化规律性,但,也算说明是一个数据的波动情况了。
模拟数据波动做好了,接下来需要做一个比较指令的程序,图示:
程序很简单,当VW0的数据是呈往上加的趋势,那么传送VW4的条件一直在满足,并一直刷新新值,直到VW0的数据为较大值的32767。同理,当VW0的数据不再往上升,而变为往下递减时,传送VW6的条件被满足开始递减,直到VW0的数据减到较小值-32768为止。
将程序修改、编译、下载到plc,创建一个状态图表,监控VW4及VW6的数据是否是按我这个思路在运行?图示:
监控结果是可以满足,较初的思想的测试过程。
思考:
上述是我通过修改后,最后定稿的程序段。在编程过程中我遇到了一个小问题,图示:
当我把INC_W指令写在判断数据是否到达,置位M0.0程序的上方时,VW0的数据无法到达VW0数据的较大值的32767,而是停留在32766中,那么,这个1是如何被“丢失”的呢?从程序看,M0.0 = 0 的状态时,M0.0的NC触点闭合INC_W会一直加1,直到VW0 = 32767时,置位M0.0的条件才会满足,需要下一个周期才断开INC_W指令。这不,程序就是自左而右,自上而下的采集扫描的吗。我截个图:
这不,VW0 =32766,而非32767。嘿嘿嘿,PLC就像是“没有”脑子的忠实“奴仆”,任劳任怨工作它不会造假和偷懒的,数据就明明白白的放着呢。仔细想了想,其实PLC确确实实的严格按我刚才的思路,不折不扣的运行,它没有错,错是在我当时的理解和判断上。
重新整理一下思路,我打算这样来描述这个情况。当VW0小于32767时,数据是往上增的趋势在时刻运行。当数据增加到32767时,如果我不及时关闭INC_W整理,那么,再加1,就是负数了,16位数据高位是符号位是西门子数据的基本定义。不要转移数据往上加这个思路点,继续思考,当VW0 = 32767,那么M0.0 置位条件满足,置位M0.0 = 1。让程序继续运行到下一个周期吧,这时,由于M0.0 = 1,它触点的所有逻辑变反,这时,INC_W的加1指令已经无法满足加1指令的条件了,那么,减1指令是满足了是,所以,VW0 = 32767实际显示32766少1,是被DEC_W指令“偷偷”减掉的。这么理解这个DEC_W指令减的?
再看这个传送VW4和VW6的程序段,关闭往上加的程序,是VW0开始往下减的那个扫描周期,因为,我把这些程序写在网络2的下面,所以,关闭INC_W指令,需要开始往下减的开始同一个周期中,我是将置位指令写到INC_W指令的上面,来规避这个问题。这就是我理解的,所谓小问题,大文章,没有仔细推敲这个过程,或者直接就是先写置位程序,再写INC_W指令程序不一定能够遇到这样的问题,每个人编程的习惯各有差异,较终我们需要的程序必须,也一定能够满足当初的思路,这就是我们平时在说的工艺要求是一致的。
在我把这个验证过程写下来时,我又想到一个问题,我在编程时并没有给VW0等*过数据类型,+32767 ~ -32768是INT的数据类型,而不是word的数据类型。当我打开INC_W和DEC_W指令帮助时,发现了问题的初衷,在F1帮助中,INC_W/DEC_W指令的IN数据类型就定义了INT数据类型,我定义与不定义,调用指令时,系统已经“自动”给定的数据类型了,这个就是大家常说的“隐式”数据类型