只是简单记录一下个人认为重要的控制原理。
知识点
电机转动
通过__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, tmp);不停的设置比较值来实现,这个值决定了管脚下一次翻转电平的时间。如设置定时器频率为20M,若此值设置为500,输出脉冲频率为20*106/500 / 2 = 20K.为什么要除2,是因为一高一低两个电平变化才构成一个完整驱动脉冲。
要是步进电机转动一圈需要4K个脉冲的话,那么这个驱动频率可以让电机每秒转5圈。
控制
这个操作一般都是在定时器中断中完成的,也就是定时器中断完成比较值的更新,根据不同加速度状态,可设置不同的值和状态。以此完成梯形或s形速度的设置。
加减速原理
加减速,都是由基础频率(低于电机启动频率)与跳变频率(在基础频率上逐渐提高的频率)
加减速曲线,一般为梯形,指数或s形曲线,对不同的负载,不同转速,需要选择合适的基础频率与跳变频率,才能达到最佳的控制效果。
完成步进电机的加减速时间为300ms以上,过短的时间,对绝大多数步进电机来说,很难实现高速旋转。
梯形加速度的实现原理
一个非常重要的步骤就是计算电机转动所需要定时器输出的脉冲频率;它的大小决定着电机的转速。如下图所示:
加速的过程就是将脉冲的发送间隔时间逐渐变短。减速可直观理解成加速的逆过程。
精确计算时间间隔
脉冲时间间隔表达
δ t = c t t = c f t \delta t=ct_t=\frac{c}{f_t} δt=ctt=ftc
ft:表示定时器的频率,倒数的话,就是定时器的计数周期,也就一个时间,如定时器频率采用3分频,那么就是80M/(3+1)=20M
c:以tt为单位的完整的脉冲,所代表的定时器的计数值。如:设定定时器计到500次,才翻转一下电平,c=500.
步距角
α = 2 π s p r \alpha= \frac{2\pi}{spr} α=spr2π
spr:步进电机转一圈的脉冲数,这个其实是常数。确定好细分数之后,这个就定了。
步距角对应的控制含义为:转1o弧度所需要的脉冲数。步数的确定要看电机,如电机标定一步为1.8o,那么转一圈所需要步数为360/1.8=200步。200步X控制器细分数=转一圈所需要脉冲数。
位置
Θ
=
n
α
\Theta= n\alpha
Θ=nα,也可以由速度来表示:
θ
(
t
)
=
∫
τ
=
0
t
ω
(
t
)
d
τ
=
1
2
ω
˙
t
2
=
n
α
\theta(t)=\int_{\tau=0}^{t} \omega(t) d \tau=\frac{1}{2} \dot{\omega} t^{2}=n \alpha
θ(t)=∫τ=0tω(t)dτ=21ω˙t2=nα
一定时间内,电机所转过角度,也就是电机的位置
变形后,可以求得到当前位置,电机所需要的时间:
t
n
=
2
n
α
ω
˙
t_{n}=\sqrt{\frac{2 \mathrm{n} \alpha}{\dot{\omega}}}
tn=ω˙2nα,两边平方,得到
n
=
ω
˙
t
n
2
2
α
\mathrm{n}=\frac{\dot{\omega} t_{n}^{2}}{2 \alpha}
n=2αω˙tn2,又因为tn=速度/加速度,将tn代入公式,可得:
n
ω
˙
=
ω
n
2
2
α
\mathrm{n} \dot{\omega}=\frac{\omega_{n}^{2}}{2 \alpha}
nω˙=2αωn2
用运动到n+1个脉冲位置所花时间减去tn,就可以得到第n个脉冲的时间间隔,cn*tt。(cn是定时器比较值,tt为定时器计数间隔)
n:脉冲数: c n t t = t n + 1 − t n = 2 α ω ˙ ( n + 1 − n ) c_{n} t_{t}=t_{n+1}-t_{n}=\sqrt{\frac{2 \alpha}{\dot{\omega}}}(\sqrt{n+1}-\sqrt{n}) cntt=tn+1−tn=ω˙2α(n+1−n)
得到我们比较关心的cn值为: c n = 1 t t 2 α ω ˙ ( n + 1 − n ) c_{n}=\frac{1}{t_{t}} \sqrt{\frac{2 \alpha}{\dot{\omega}}}(\sqrt{n+1}-\sqrt{n}) cn=tt1ω˙2α(n+1−n),这样人为指定加速度后,就可以求得第n个脉冲的时间间隔。
第一个脉冲为 c 0 = 1 t t 2 α ω ˙ ( 0 + 1 − 0 ) = 1 t t 2 α ω ˙ c_{0}=\frac{1}{t_{t}} \sqrt{\frac{2 \alpha}{\dot{\omega}}}(\sqrt{0+1}-\sqrt{0})=\frac{1}{t_{t}} \sqrt{\frac{2 \alpha}{\dot{\omega}}} c0=tt1ω˙2α(0+1−0)=tt1ω˙2α,所以, c n = c 0 ( n + 1 − n ) c_{n}=c_{0}(\sqrt{n+1}-\sqrt{n}) cn=c0(n+1−n)
速度
ω = α δ t = α f t c \omega=\frac{\alpha}{\delta t}=\frac{\alpha f_t}{c} ω=δtα=cαft,
也就是每个定时器驱动脉冲,电机所转过的角度。后面等式是转化成定时器频率后对应的式子。c就是设定定时器比较值,可以说速度的改变全靠它。
若速度人为指定的话,那么c就等于步距角*定时器脉冲频率/速度,这个就是定时器的比较值。
加速度
ω
(
t
)
=
∫
τ
=
0
t
ω
˙
d
τ
=
ω
˙
t
\omega(t)=\int_{\tau=0}^{t} \dot{\omega} d \tau=\dot{\omega} t
ω(t)=∫τ=0tω˙dτ=ω˙t
速度是在一定时间内的加速度的积分。终于看到希望的时间了。前面说了一般会在300ms以上完成加速度。
控制过程
大体的思路
启动电机后,先要不停地减小定时器的定时翻转值,实现一定的加速度,这个加速度是一个渐进的过程,不能一下加到最大,否则就没有加减速这一说了。那问题来了,如何确定这个加速过程呢?如何确定加速的停止点?相对应,还有减速度?
问题解决思路
加速的停止点:其实对应的是定时器的最小的时间间隔。也就是最大速度,可以由用户指定。
加速过程确定:梯形加速由三段组成,如下图所示:
想要完整确定这三段都是在哪些步上操作,就先要指定一个整个三段周期步数。剩下就是三段时间划分的问题了,如何才能保持住一个线性的加速度呢?另外这个线的斜率如何确定?
这个斜率,也就是加速度,其实是可以用户指定的。指定好后,这个加速的时间也就确定了,因为加速到最大速度也是用户指定的。斜率其实脉冲n对应的时间间隔cn.
同理,减速斜率,也可以人为指定。
那么剩下的就是匀速阶段的持续的时间了。
实现
-
指定一个最大速度,那么由速度公式 ω = α δ t = α f t c \omega=\frac{\alpha}{\delta t}=\frac{\alpha f_t}{c} ω=δtα=cαft,可得到c,这个就是加速度的结束条件。
-
通过计算第一步c0来设定加速度。由 c n = 1 t t 2 α ω ˙ ( n + 1 − n ) c_{n}=\frac{1}{t_{t}} \sqrt{\frac{2 \alpha}{\dot{\omega}}}(\sqrt{n+1}-\sqrt{n}) cn=tt1ω˙2α(n+1−n)公式,得到 c 0 = 0.676 ∗ f t 2 α ∗ 10 accel c_{0}=0.676 * f t \sqrt{\frac{2 \alpha * 10}{\text { accel }}} c0=0.676∗ft accel 2α∗10 accel:人为指定的加速度,0.676是一个修正参数。
-
计算加速到最大速度所需要的步数
由公式: n ω ˙ = ω n 2 2 α \mathrm{n} \dot{\omega}=\frac{\omega_{n}^{2}}{2 \alpha} nω˙=2αωn2,得到: n = speed 2 2 α ⋅ accel ⋅ 10 n=\frac{\text { speed }^{2}}{2 \alpha \cdot \text { accel } \cdot 10} n=2α⋅ accel ⋅10 speed 2
- 计算理论上多少步之后开始减速,不考虑最大速度的步数限制
由于加速度到最大速度等于开始减速度
如下图所示:
速度其实是加速度在一定时间内积分,而时间也可以对应到步数上,所以 n 1 ω ˙ 1 = n 2 ω ˙ 2 n_{1} \dot{\omega}_{1}=n_{2} \dot{\omega}_{2} n1ω˙1=n2ω˙2,所以n1对应的就是开始减速度时的步数,两边同时加n1w2得到: n 1 ω ˙ 1 + n 1 ω ˙ 2 = n 2 ω ˙ 2 + n 1 ω ˙ 2 n_{1} \dot{\omega}_{1}+n_{1} \dot{\omega}_{2}=n_{2} \dot{\omega}_{2}+n_{1} \dot{\omega}_{2} n1ω˙1+n1ω˙2=n2ω˙2+n1ω˙2,化简得到$n1=\frac{\dot{\omega}{2}(n{1}+n_{2})}{\dot{\omega}{1}+\dot{\omega}{2} } , 因 为 ,因为 ,因为n_{1}+n_{2}$等于全部的步数,加速度与减速度是人为指定的,所以:n1 = (n1+n2)decel / (accel + decel)。
-
计算减速需要步数,分两种情况
如下图所示:
-
如果最大速度步数 < 开始减速时的步数,说明此时,加速到减速时的步数多了,需要受限于最大速度的步数,根据这个公式 n 1 ω ˙ 1 = n 2 ω ˙ 2 n{1} \dot{\omega}{1}=n{2} \dot{\omega}{2} n1ω˙1=n2ω˙2可得: decel_aval= - max_s_lim * (accel/decel),负号说明的速度的方向。
-
如果最大速度 >= 开始减速时的步数,也就是说加速度的步数,不足以加速到最大速度,那么此时就受限于开始减速时的步数了。此时的减速步数,直接用总步数减去加速时的步数就可以了。decel_val = -(step - accel_lim);
-
还要考虑特殊情况:当算出来decel_val=0,那么人为给它赋上-1,代表只剩最后一步时,减速。
-
-
计算加速到开始减速的步数
也就是是用全程的步数step + decel -
看一下,第一步c0来设定加速度是否是小于最大速度,若最大速度设置值还不如加速度大,那就没必要加速了。反之,就从c0加速度开始加速。
算法总结:
可见,算法主要是实现减速开始步数及加速步数的计算。至于三段如何加速减速是放到定时器中断中来处理的。
定时器中断处理
主要实现就是加速与减速的过程,需要计算电机每走一步定时器的比较值,根据前面位置里公式 c n = c 0 ( n + 1 − n ) c_{n}=c_{0}(\sqrt{n+1}-\sqrt{n}) cn=c0(n+1−n),就可以得到这个c值,但过程中开两次根号太麻烦,同时也不是关于前一个比较值的关系,所以需要 c n c n − 1 = c 0 ( n + 1 − n ) c 0 ( n − n − 1 ) \frac{c_{n}}{c_{n-1}}=\frac{c_{0}(\sqrt{n+1}-\sqrt{n})}{c_{0}(\sqrt{n}-\sqrt{n-1})} cn−1cn=c0(n−n−1)c0(n+1−n),再根据数学中泰勒公式特例:麦克劳林公式,(推导起来也比较麻烦,知道结果就可以了)得到最终 c n = c n − 1 − 2 c n − 1 4 n + 1 c_{n}=c_{n-1}-\frac{2 c_{n-1}}{4 n+1} cn=cn−1−4n+12cn−1。根据公式,写代码就可以了。
new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest) / (4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
rest = ((2 * srd.step_delay) + rest) % (4 * srd.accel_count + 1); // 计算余数,下次计算补上余数,减少误差
加速与减速都是用这个公式,计算结果会包含一个系数和一个余数,为了提高精度,余数要保留并包含到下一次计算当中。
然后,再设置状态,停止、加速,运行、减速,针对不同状态,计算定时器的比较值,这样就可以实现梯形控制了。s形控制也是一样的原理
总结
比较重要的就是数学公式推导,可见数学在算法中的位置。但数学真不是知道就能用的,需要一个很长很长的过程。还是想到屈原一句话“路漫漫其修远兮,吾将上下而求索”。别急,慢慢去体会。