博途S7-1500SCL实现斜坡线性平滑算法程序
01
线性平滑功能关主要有两大作用:
1、对设置值目标值进行平滑,在收放卷以及一些同步控制中,闭环有可能会在PLC里面做闭环控制,所以速度指令通常是由PLC给出,变频器、驱动器这些执行机构加减速时间设置的会非常短,因为要满足一些同步性跟随控制的需要,这时候如果去点动一个外部设备,直接设定一个目标值,如果没有一个线性平滑的功能,设备都会有一个明显的一个冲击,所以这时候一般会引入一个线性平滑功能,对于设定值,它实现一个斜坡加减速的功能,
2、另外一个功能就是在PID的优化算法里面实现对于给定值PID的目标值的一个平滑给定。比如设定给定的一个温度,我们从30°升到100°C,通常我们如果直接设置的话,会有一个很明显的阶跃。对于这样的一个阶跃信号后面的闭环控制系统PID,它的响应是比较困难,所以这时候我们通常会对给定值进行一个平滑,比如说那些线速度设定,张力设定,对于这些需要控制的这个目标量,通常都会有一个平滑过渡的过程,一个阶跃信号给过去后面的闭环控制系统很难及时响应,会给系统造成一定的冲击,所以这时候会引入这样的一个线性平滑功能块,介绍完线性平滑功能块的作用之后,我们看一下这样一个功能块它的算法原理是如何实现的。
算法原理,这里我们结合着PLC代码部分进行讲解。我们这里已经编写好了一个线性平滑功能块,这里我们在定时中断OB30里面进行调用,这里的定时中断的中断时间是10ms,每10ms里面去调用一个这样的一个平滑函数功能块,直接监控观察一下这样的一个功能块。现在它的目标值是30,如果要去修改它的这样的一个速度,比如让他转到60r/min,大家可以看得到我的这个目标值虽然阶跃发生变化了,但是我的输出平滑值它是慢慢爬升到这个阶段的,它有一个爬升的这样的一个过程。
我们在将速度降低,可以看到我们在触摸屏或者上位机上去给进这样的一个速度指令,但是实际上速度指令并不是马上降到的设定值,而是一个斜坡有一个加速减速的过程,所以这里的线性平滑功能快主要是为了完成对于我们的目标值的一个线性平滑。
平滑时间是自己可设的,这里的工程量的最小值是0,最大值是200,然后总的平滑时间是50,实现这样的一个平滑时间一个设定,对于变频器里面,通常大家知道0~50Hz对应的你的加速时间,有的时候会设置成15秒,20秒,其实是一个道理,就是这里的算法是在PLC里面去实现这样的一个过程,因为有的时候我们的这样的一个闭环控制,同步控制是在PLC这边去做的,所以这样的平滑必须由我们这个PLC上位控制器去给出这样的一个平滑指令。
接下来看一下编程里面是如何进行实现的。这里将纵坐标的最小值、最大值设定成0-200,横坐标平滑总时间设置成50秒,这里面还有一个求解步长,就是所谓的这个定时中断的时间,如果我们设置是10ms,那10ms,50秒里面被划分了多少份呢?我们首先利用这样的一个平滑总时间除以一个计算步长,当然这里的单位是毫秒,总时间单位是秒,秒我们要转成毫秒,毫秒之后再除以这样的一个步长,就总共我们被分割了这么多份,从这个最小值到最大值被分割这么多份,需要计算出我们的单步增量,这里的增量它是一个既是代表递增也是代表递减的,所以它是一个变化量。首先要计算出这样的一个变化量,这个变化量计算出来之后,这样的一个平滑输出,就利用这样的一个公式就可以算出来我们的平滑数值,值等于我们的这个初始值,就是这里的平滑值,再加上单步递增量,再乘以一个系数。为什么要有个系数呢?就是因为我们有可能是递增的也有可能是递减,这要根据这个目标值和我们的平滑输出值这个大小关系,可以看一下,这边这时候平滑输出值已经是10了,那如果这时候我要让它变为变为2,那是不是必须得递减,所以这里是根据这样的一个输出平滑值和我们的这个目标值的大小来判断到底是递减还是递增的,可以看到我们现在就是一个递减的过程,那我们如果将我们的这个设定值设置的大于我们的这个平滑输出值,比如说我们设置成40,可以看到我们现在的输出它就是一个平滑递增的这样的一个过程。
符号表:
代码:
REGION 单步变化量
#deltaValue := (#maxValue - #minValue) / DINT_TO_REAL(#smoothTime * 1000 / #h);
END_REGION
REGION 计算偏差juedui值
#SetSmSUB := #SetValue - #sm_out_1;
IF #SetSmSUB < 0.0 THEN
#SetSmSUB := #SetSmSUB * -1;
END_IF;
END_REGION
REGION 计算平滑输出值sm_out
IF #SetSmSUB > #deltaValue THEN
IF #SetValue > #sm_out_1 THEN
#factor := 1.0;
ELSIF #SetValue = #sm_out_1 THEN
#factor := 0.0;
ELSIF #SetValue < #sm_out_1 THEN
#factor := -1.0;
END_IF;
#sm_out_1 := #sm_out_1 + #factor * #deltaValue;
ELSE
#sm_out_1 := #SetValue;
END_IF;
#sm_out := #sm_out_1;
END_REGION