续-数字积分法DDA(实时步进电机梯形+S形加减速)实现方法

上一篇的数字积分加减速度,其实就与网络上的SPTA加减速原理是哪么一回事,也就是固定时间分段,不过网络上找到的SPTA方法介绍也不是太详细,对于哪些增量参数也没提及如何计算

先看看速度,加速度与时间三者的关系

v=t*a

此式好明显速度就是时间与加速度的乘积,如果定时器频率为100KHZ,哪每周期的时间就是10微秒,先说一下如果速度为19200步每秒,这里所有说的步单位都以秒作为时间单位,在100KHZ定时器频率下,按19200这个速度移动,100000/19200=5.2083333.....个周期输出一个脉冲,这样电机就以19200HZ的速度移动了,现在看一下如何积分输出脉冲

accumulator=0;

v=19200;

F=100000;

out=0;

//以上初始化变量

for(;;)

{

        accumulator = accumulator + v; //位置累加

        if(accumulator>F) //溢出

        {

                ++out;//输出脉冲

                accumulator = accumulator-F;//清除溢出位

        }

}

代码里死循环模仿定时器中断函数,每循环一次,累加器累加一次速度值,直到大于定时器的频率值,就输出一步,也就是溢出,累加器减去频率值,就是去除溢出位,保留余数,作为下一次累加使用,这样0.xxx个周期就补回去了,它实际输出的脉冲频率,也就是并不会稳定在19200的频率,100000/19200=5.2083333.....,这0.20833333个周期会被保留起来累积到一个整数才会输出一个脉冲,所以实际输出的脉冲是一直在16666.6666...到20000范围内波动,但在整体的移动总时间是一样的,只有速度与定时器频率整数除时才是稳定不波动的脉冲频率,频率越高,这个跳动频率范围越大,如果按取一定时间长度的频率平均值,确实还是19200的频率,实际这样的波动频率脉冲输出到电机上,会不会造成电机直接卡死,也只有试验了才知道,题目为实时加减速度实现,哪就先看看以这种方法如何实现实时加减速.

这里只指定一个频率进行累加移动,加速度斜坡又应该怎么样才行呢,19200为目标速度,从启动速度到19200的速度,可以看作为一个斜率,启动为0,即电机静止状态,即0-19200,按定时器一个周期时间的长度分成许多多份,得到一个速度增量值,定时器每一个周期,把当前速度增加一个速度增量值,同时每定时周期累加器进行累加,看是否溢出,是否输出脉冲

速度增量值根据加速度和定时器频率求得  inc_v=a/f

假定加速度为a=64000步每秒,inc_v=a/f=64000/100000=0.64

inc_v=a/f  是根据 t=v/a=19200/64000=0.3 

v=t*f*at_v = 0.3*100000*0.64=19200 所以:

inc_v=a/f

accumulator=0;
v=0;
F=100000;
inc_v=0.64;
out=0;
ta_v=19200;

c0=0; //周期次数
c1=0; //上一周期次数
hz=0;//计算频率用
//以上初始化变量

for(;;)

{
        ++c0;
        if((v+inc_v) < ta_v) 
        v=v+inc_v; //速度累加
        else v = ta_v;
        accumulator = accumulator + v; //累加器位置累加

        if(accumulator>F)

        {
            
                ++out;输出脉冲

                accumulator = accumulator-F; //清除溢出位
                hz=1/((c0-c1)/F); //当前脉冲的频率
                c1=c0;    
        }
        if(c0=30000) break; //3毫秒加速度时间到达t=v/a
}

代码里增加了每个脉冲对应的频率计算,以验证结果,c0记录定时器的周期次数,hz显示当前的脉冲的频率值,按上面的参数第一个脉冲产生时,hz的值应该是178.89xxxHZ,c0=559个定时周期,如何验证这是正确的呢?看公式

s = t*t*a/2 = v*v/(a*2)  加速斜坡面积公式

v=sqrt(s*2*a) 面积反求速度

t=sqrt(s*2/a) 面积反求时间

所以一个脉冲的时间为:

t1=sqrt(2/a)

T= sqrt(2/a) =sqrt(2/64000)=0.0059016........ 计算出第一个脉冲的时间

s1_HZ=1/T =1/0.00559016........=178.89xxxHZ   第一个脉冲的频率

c0 = F*T = 100000*0.00559016.......= 取整数就是559个定时器周期

T(n) = sqrt(2*n/a) 第n个脉冲的时间

v(n)=1/T(n)   第n个脉冲的频率

根据v=sqrt(s*2*a) 面积反求速度

在输出第一个脉冲时对应的的速度值为v=sqrt(2*a)=sqrt(2*64000)=357.7708.....,即代码里v的值在位置累加到产生第一个脉冲时等于当前速度v=357.76

有这些公式就可以验证上面的累加所产生的脉冲是否按计算所得的时间或者频率,减速过程就是反过来,在当前的速度值减去速度增量值,直到速度为0,减速完成

利用位置累加和速度累加,达到省去了求平方根的复杂计算,大大省去了单片机的时间,当然,现在还是使用浮点进行加法运算,没有FPU的单片机来说,还是会消耗更多的MCU指令,我们得转换为整数来进行累加,使用整数后,速度增量值由于细分后,由于取整数会去掉了小数部分的值,哪么此时的整数累加,就会产生偏差,因为累加的总次数后达到的速度值远小于最大速度值,这样会导致相应的脉冲点的频率不正确,这样会超出加速度所要的时间达到完成加速斜坡,特别是在减速度时,由于取整数会去掉了小数部分,它的下降速度会明显变慢,导致输出的脉冲数变多了,在还远没达到0速度时,已经移动完成减速,如果加速度比较大的时候,电机可能在较高的速度进入静止状态,产生较大的冲击惯性,调试中发现,即使放大2的32次方倍,在加速度值较小的情况下,误差就会变得更大,所以还得想办法补偿误差才能成,尽量让偏差减到最小。

通过计算,要适合所有不同的加速度值,放大倍数在2的32+22次方倍即2的54次方倍可以比较理想,这样一来就得使用64位整数才能满足全范围的加速度值,如此一来,对于STM32来说,处理64位整数,就得增加相应的指令时间了,另一种方法是使用偏差补偿,预先按加速所要的步数,计算出偏差值,每产生一个脉冲,把当前速度值增加一个偏差补偿值,这样在每产生一个脉冲时才增加一个加法指令,增加判断,在均速度时,就不用加这个补偿,实际上即使补上去了,还是存在一定的偏差,只是做到接受范围内,即使是使用每脉冲计算出时间来控制 定时器的频率,像16位定时器也就65536个变化,还是会存在一定的频率偏差的,只要保证在相应的加速度或者减速时间内完成加减速度斜坡,在加速度的过程,不会产生大跨度频率变化,比如从1KHZ突然跳到3KHZ,这样加速,电机可能直接补卡死不转动了,或者在减速过程,能从当前频率按减速度一直减速到0速度让电机正确停止就能成了,如果减速过程,由于偏差太大,它在减速到1KHZ或者更高的频率下,已经走完了减速步数,直接停止,哪么在较高的频率下脉冲已经没了,电机一下子就停止了,这个冲击惯性会较大,机器会像有撞击一样的声音出现,而且可能会让电机在停止时被惯性冲击,导致不按正确的步距角停止,可能被惯性冲击移动超过了好几个步距角,这样机器的位置就会被改变掉,你就得重新让机器回零点才能继续加工了,这样问题就严重性的了

接着来就是如何把这些浮点值取整为整数型以减少指令开销,提高执行速度

思来想去,直接把速度增量值放大到一定倍数,比如增量inc_v*0xFFFFFFFF,放大倍数看样子是足够的大了,但实际上只要把取整后的增量值按照实际的次数累加后,还是会少于目标速度ta_v*0xFFFFFFFF,这样就会影响到不同时刻的当前速度比浮点值时变慢了,从均速度减速时,也会造成减速变慢了,所以步移动就不会按实际的加速度或者减速度时间完成了,可能提前了达到最大速度,或者在减速时,提前了把所有步都移动了,而且这脉冲不能在实际的最低频率下减速到静止状态,而是以较高的频率时已经进入静止状态了

然后脑子在找不着东南西北时突发奇想,想到一个神奇的数字“1”,脑海中一直环绕着一堆数字1,久久不能散开,为什么会是1,为什么不能是1为什么。。。。。天啊我小学的体育老师教给的数学 终于派上用场了,突然好想我小学的体育数学老师啊,泪水洒了一地.....假定加速度还是以64000步每秒,定时器频率为100KHZ,哪么每个定时周期也就是10微秒,即每一个周期的速度增量为64000/100000=0.64,这个值比1小啊,或者假定定时器频率为200KHZ,哪么一个周期是0.32的速度增量,所以增量值它永远是比1小,哪么把增量值放大到1,这就等于以整数1作为速度增量值了,哈哈它终于是整数了,终于是整数了.........终于这一刻脑海中几十年前小学体育数学老师哪张早已经模糊的面孔慢慢的又变得清楚起来了...........这就解决了放大倍率的问题了,1/0.64=1.562倍,把最大速度19200*1.562=30000,频率100000*1.562=156250,为什么不能是1呢!哪么这个神奇的增量整数“1”代入到代码后就是这个样子:

inc_v=64000.0/100000.0;//计算出每周期增量inc_v=a/f,双精度浮点
F=(uint32)(100000.0/inc_v);//按倍率放大频率,32位无符号整数
ta_v=(uint32)(19200.0/inc_v); //按倍率放大目标速度,32位无符号整数

v=0;//当前速度存放变量,32位无符号整数
out=0; //用作表示脉冲输出,或者位置移动变量,32位整数
accumulator=0;//位置累加器,32位无符号整数

c0=0; //周期次数
c1=0; //上一周期次数
hz=0;//计算频率用
//以上初始化变量

for(;;) //以循环模拟定时器中断入口,假定每循环一次为中断一次
{
        ++c0;

        if(v < ta_v) //已经达到目标速度?
        ++v; //速度累加值以“1”为增量,如果减速状态--v;
        //else v=ta_v; //当前速度为目标速度作为均速段,如果有均速度段
        accumulator = accumulator + v; //累加器位置累加
        if(accumulator>F) //溢出啦....
        {
            
                ++out;//输出脉冲

                accumulator = accumulator-F; //清除溢出位,保留余值

                hz=1/((c0-c1)/100000); //当前脉冲的频率,只是验证用,实际使用时没有这些
                c1=c0;    
        }
        if(c0=30000) break; //3毫秒加速度时间到达t=v/a
}

一切从1开始就解决了这个取整数和放大倍率的问题了,再好不过了,但不同的设备使用条件可能设定的加速度,并不一定是64000,可以是各种任何的加速度值,比如说使用的丝杆导程5mm,电机1.8度步距角,转动一周的步数为360/1.8=200步,不细分下,即每毫米步数为200/5=40步,如果把加速度设定为1mm每秒平方,即1*40=40步作为加速度值,假定定时器频率为100KHZ,也就是40/100000=0.0004为一周期的速度增量值,求出放大到1的放大倍率,1/=0.0004=2500倍,即100000/0.0004=250000000,这个数字它没有超过32位整形数的范围,所以符合使用条件,100KHZ定时器频率条件下,这样从40-100000的加速度设置,都是可以的,放大倍率得到的数字它都不会超过32位整数范围,所以都能正常使用,然后有的可能使用性能更高的MCU,要做到200KHZ的,哪么还是按倍率与频率的乘积后,只要不超过32位整数范围都是可以的,如果更高的频率,可能会超过32位数的存放范围,哪么计算出来的值就是溢出的值,这样是无法正确使用了,此时必须制定加速度设置范围的限制条件了,好比说加速度不能小于8mm,这样即使40*8=320,哪么这个基础值也不会太小,然后再验证出倍率来与频率值乘积一下,只要不超出32位整数值范围的条件就OK了

再说一下这种整数型数字积分法的加速度所产生的脉冲,实际上脉冲频率波动是比较大的,前面已经提及过此问题,比如按19200这个速度来累加,100000/19200=5.208333333..次,如果离散化,按照采样定理,即采样频率等于100000HZ,19200HZ的采样点只有5.20833333....次,它不存在浮点次,只有整数次,要么累加5次输出一个脉冲,要么累加6次输出一个脉冲,100000/5=20000HZ,100000/6=16666.666666......HZ,它可能是连续3次按5次累加输出脉冲,然后1次按6次累加输出脉冲,还是其它次数组合,就看溢出后的余数了,连续一定时间的周期次数内,按取平均值来看它还是19200HZ的脉冲频率,但实际上电机的脉冲频率能否以平均频率值也能稳定运行?实质脉冲频率它是波动的,而且频率越高,波动幅度越大,因为被固定的定时器频率限制死了(采样频率),简单点说,当脉冲频率越高的时候,频率分辨率就会越小,无法被 定时器频率整数除的脉冲频率都会产生较大的频率跳动,所以这种按每时间片取脉冲步数的方式,还是存在这样的一个大BUG,也是无法解决,除非使用更高的采样率(定时器频率)跑更低的速度,比如4MHZ,你实际跑200KHZ,哪么最高频率200KHZ时可以得到20个采点,这样一来就可以把波动范围减小,但这么高的频率也只能适合FPGA。想要频率波动更小范围的,只能是按每步时,每步时也不可能完全没有波动,只是更小一些,影响更小一点,求出每一步对应的时间去控制定时器的当前步频率才会比较理想,按每步时也是存在一定的问题的,前面也提及过了,定时器也就16位,可以设定65336个频率,再高级的定时器支持32位,哪么这些范围值来控制每步的频率变化就按支持多少位的范围来设置定时器的频率变化了,像要设定19200HZ,可能在这范围可刚好得到这个精确的19200频率值,也可能在这频率的小范围内,因为16位定时器值也是一个整数,你无可耐何,也是只能接受她,不可能每一个频率值都按计算出来刚刚好精确的,但这种方法并不会存在大频率范围的波动,一般可能在几十HZ到几百HZ内波动,为什么呢?因为你跑均速时,某些速度下计算所得的频率它存在浮点值,你得把频率值取整数,小数部分你还得留作下一步累积起来补偿回去,这样是不是就有点像积分法哪样的,累加5或者6的效果了,但这个频率波动变化范围要小得多,因为都已经接近精确的定时器频率了,这样一来肯定比每时步理想得多了,所以这样一对比,两款种方式它基本上也是一样的了,就频率波动范围大小的差别,但要每步时的方式,要计算平方根啊,要高频率实时生成还是得想到合适的算法才可以实现,或者使用支持双精度浮点的硬件算法器的MCU,更高性能的MCU,可以能按你想要的频率内计算出来,所以还是难难难。。。。

对于S形加速,暂时还是不想了,留着后面再研究了,研究这几个式子转来转去的脑子真不够使,把这种积分法的线性加速斜坡看在脉冲频率较高的时候跳动,会不会让电机卡死不转。

代码只是简单的演示了假定的设定速度,加速度和定时器频率,作为演示在这个加速度时间内所产生的脉冲,以理解工作原理为目的,验证每一步所对应的频率值,也不是完整能直接使用的代码

另外对于加速,均速,减速,空闲等状态比较与切换就不说了,这一篇我已经用能想到最简单的表达方式写出来了,如果能理解所说的应该都能明白是什么原理了。

有错误的也请指出,有更好的方案方法也可以提出来讨论一下

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FPGA梯形减速是一种通过FPGA实现步进电机控制方法。在这种方法中,通过调整脉冲频率来实现步进电机的加减速控制。根据引用\[1\]中的描述,FPGA的运动控制卡可以使用DDA(Digital Differential Analyzer)算法来实现脉冲输出。这种方法的优点是计算过程简单,没有浮点运算,对于MCU的开销非常小。 然而,引用\[2\]中提到的S形加速是错误的,实际上是线性加速。这可能是因为将速度增量误认为是加速度增量,并且在时间分段采样后产生了类似S形变化的曲线。另外,线性斜坡方法也存在问题,增量值的微分分数过多会导致小数部分误差,从而在实际时间对应的速度上产生偏差。 对于步进电机的控制,引用\[3\]中提到了空载启动频率和有负载情况下的启动频率。空载启动频率是指步进电机在空载情况下能够正常启动的脉冲频率。如果脉冲频率高于该值,电机可能会发生丢步或堵转。在有负载的情况下,启动频率应更低。如果要使电机达到高速转动,脉冲频率应该有加速过程,即启动频率较低,然后按一定加速度升到所希望的高频。 综上所述,FPGA梯形减速是一种通过调整脉冲频率来实现步进电机减速控制的方法。然而,需要注意的是在实际应用中可能存在一些问题,如S形加速误差和线性斜坡方法的误差累积。同时,根据步进电机的负载情况和所需转速,需要选择适当的启动频率和加速过程。 #### 引用[.reference_title] - *1* *2* [数字积分法DDA实时步进电机梯形+S形加减速实现方法](https://blog.csdn.net/dbxzjq/article/details/130022758)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [FPGA学习笔记(5)——步进电机梯形减速算法](https://blog.csdn.net/step__forward/article/details/124715218)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值