普誠創智(成都)科技有限公司-论坛
标题:
基于PT32 BLDC驱动方案的增量PID调试思路
[打印本页]
作者:
Dooo.
时间:
2022-3-3 17:22
标题:
基于PT32 BLDC驱动方案的增量PID调试思路
一. 源码
void SpeedPID_Init(void)
{
SpeedPID.OutMax = 5*65536;
SpeedPID.OutMin = -5*65536;
SpeedPID.Kp = 50;
SpeedPID.Ki = 10;
}
void SpeedPID_Rest(void)
{
SpeedPID.Err = 0;
SpeedPID.ErrBak = 0;
SpeedPID.Uout = 0;
SpeedPID.UoutBak = 0;
}
LONG SpeedPID_Ctrl(LONG ref,LONG fdb)
{
SpeedPID.Ref = ref; // the set data
SpeedPID.Fdb = fdb; // the actual data
//-----Error-------------
SpeedPID.Err = SpeedPID.Ref - SpeedPID.Fdb;
//
SpeedPID.Uout = SpeedPID.UoutBak + SpeedPID.Kp * (SpeedPID.Err - SpeedPID.ErrBak) + SpeedPID.Ki * SpeedPID.Err;
//
if(SpeedPID.Uout > SpeedPID.OutMax)
{
SpeedPID.Uout = SpeedPID.OutMax;
}
else if(SpeedPID.Uout < SpeedPID.OutMin)
{
SpeedPID.Uout = SpeedPID.OutMin;
}
//
SpeedPID.ErrBak = SpeedPID.Err;
SpeedPID.UoutBak = SpeedPID.Uout;
//
SpeedPID.Uout /= 65536;
//
return SpeedPID.Uout;
}
SpeedPID.OutMax和SpeedPID.OutMin对我们当前的最大累积值进行限幅。
SpeedPID.Kp和SpeedPID.Ki就是目前我们主要调试的PI参数。
SpeedPID.Err当前的误差值,SpeedPID.ErrBak上一次的误差值。
在加速期间,SpeedPID.Err理论上是慢慢减小的,所以(SpeedPID.Err - SpeedPID.ErrBak)大部分情况是负数的。
例如:设置的目标转速为5000转,第一次速度为2000转,第二次速度为3000转,以第二次为当前状况,第一次为上一次状况,则Err为2000,ErrBak为3000,(SpeedPID.Err - SpeedPID.ErrBak)=-1000。
SpeedPID.Uout是当前的输出值,SpeedPID.UoutBak为上一次的输出值。当前输出值是在上一次输出值的基础上再进行计算的。
二. 参数的设定
1. PID调用时间的设定
建议可以根据设置的目标转速电周期时间设置,例如设置的目标转速为20000转 (2对极) ,对应电周期为1.5ms,那么此时我们的调用时间设置应大于1.5ms,需要保证速度更新后才会调用PID。为什么需要保证速度更新后才会调用PID呢,以加速为例,当实际速度接近目标速度时,若在速度出来前,仍调用了多次pid,那么此时对于PID来说,实际速度未发生变化,(SpeedPID.Err - SpeedPID.ErrBak)为0,Kp不起作用,Ki*Err在UoutBak上迅速累加,直到被OutMAX限幅,则PID输出值会一直很大,不会慢慢减小。
当然,调用时间也不能太大,“PID输出值会一直很大” 的情况我们在实际转速还未接近目标转速时是需要这个上限值进行加速的。所以此时我们的调用时间需要确定一个范围,假设目标转速20000转,空载时20000转,此时带载,电机速度降到了10000转,那么要将10000转迅速调回20000转,则调用时间便可设置在1.5ms~3ms之间,建议可用3ms。(2对极10000转对应电周期3ms,2对极20000转对应电周期1.5ms。)
2. SpeedPID.OutMax和SpeedPID.OutMin的设定
例如例程中OutMax为5*65536
①5这个值代表每一次加减的最大CMP值,设置一般建议为g_PWMLoadData*0.5%左右。
例如:平时PT32M6xx程序中默认使用的PWM频率为20k,此时的PWMLoadData为1200,0.5%为6,那么可以OutMax建议可以设置为6*xxx,也可以在6的基础上进行调整。
②65536代表放大倍数,一般建议可以设置在目标转速1倍左右。
例如目标转速为20000转,可以设置为xxx*20000,也可根据实际情况调整为其他倍数。当65536改了后,程序 “
SpeedPID.Uout /= 65536;
” 处的
65536
请一并更改。
3. Kp和Ki的设定
首先可以先确定一个Kp的初始值,找初始值的方法为:先将Ki=0,慢慢增加Kp的值,会发现存在一个Kp值,此时的实际转速会最接近目标转速。
例如:Kp值为 ( 1,2,3,4,5,6 ... ),目标转速为20000,当Kp=1时,实际转速最大能到7000转,Kp=2时能到12000转,Kp=3时能到15000转,Kp=4时能到17000转,但是当Kp=5时可能就只有15000转了,而Kp=6时能达到的转速就更低了,那么此时的Kp=4就应该时我们设置的初始Kp值。
初始Kp值设定完,可以开始加上Ki值,一般先给1,此时可以观察到加上Ki后,实际转速会在目标转速附近震荡,那么便可以增大Kp。此时也可打印g_PID_Data观察,在第一次接近目标转速时 ( 例如:目标转速20000,实际转速18000),如果此时的g_PID_Data已经缓慢减至1了,后续转速也稳定在目标转速附近,那么此时PID已大致ok,可微调。
在电机从静止开始启动时,此时的g_PID_Data会瞬间变小,是因为速度从0变成了2000转 ( 静止和第一次得出转速,不一定2000,但大部分相差较大 ),(SpeedPID.Err - SpeedPID.ErrBak)=-2000,再加上Kp较大,所以g_PID_Data会瞬间较小,后续Ki会将g_PID_Data迅速拉回5,后续的速度变化基本较缓,并不会出现很大的速度突变,所以电机从静止到转动的瞬间出现的g_PID_Data瞬间变小是正常的。
4. PID调用范围
这个可以根据个人需要,确定是否加上PID范围限制。如果要加上范围限制,那么在不调用PID时需要清除PID。
例如:在目标转速
3%的
范围内不调用PID。3%以外是正常调用PID的,但在这3%的范围内,则需要对PID的的值进行清除。可参考以下例程:
if((g_ActualSpeed <= ((g_SetSpeed * (100 - 3)) / 100)) || (g_ActualSpeed >= (((g_SetSpeed * (100 + 3)) / 100))))
{
g_PID_Data = SpeedPID_Ctrl(g_SetSpeed,g_ActualSpeed);
}
else
{
g_PID_Data = 0;
SpeedPID_Rest();
}
以上是对目前程序内增量PID的相关理解和调试思路,如有不足,请指正,欢迎大家阅读。
作者:
James_Jiang
时间:
2022-3-4 09:42
厉害!
欢迎光临 普誠創智(成都)科技有限公司-论坛 (https://princeton.com.cn/)
Powered by Discuz! X3.2