PID 电机调速 问题
本帖最后由 hzocce 于 2025-3-19 16:21 编辑问大家一个问题,转速通常是RPM, 也就是每分钟的转速,除以60秒便是 RPS ,
电机转动感应霍尔,通过霍尔输出的脉冲来获取电机的转速,采样转速需要一定的时间,比如一秒内数霍尔输出的脉冲来 或得电机的转动速度。
那控制电机转动的时候,通过霍尔的反馈,来调整电机的驱动信号。
那我想知道的是,这个调用周期通常是多少合适?是1S数 一个脉冲,然后下一秒调整输出
还是半秒一次?
时间越密集,那是不是检测的越不准?
那时间长了,那调整的时间是不是变得非常漫长了?
有没有分享一个 调速例程呢? 谢谢~~
........ 你说的很对,用霍尔测速就是这样 qinlu123 发表于 2025-3-12 10:34
你说的很对,用霍尔测速就是这样
这样调节起来不是要好久,很费时间 测周期啊,我都是用一定的时间来测N个周期的时间来计算转速,比如计算周期是100ms,则每隔100ms检测N个脉冲对应的时间t,则周期就是t/N,速度就是N/t,比如某次测得N=10,t=99.8002ms,则转速就是100.2/S。 coody 发表于 2025-3-12 18:11
测周期啊,我都是用一定的时间来测N个周期的时间来计算转速,比如计算周期是100ms,则每隔100ms检测N个脉冲 ...
谢谢大佬指点 调试起来,好不容易
不知道有没有哪位坛友做过这样的处理
能不能分享 一个例程呢? struct PID
{
float SetSpeed;//每100ms的转速
float DriverOut;//为检测到零点之后延时打开可控硅的时间。
float Err;//当次误差
float LastErr;//上次误差
float Kp;
float Ki;
float Kd;
float Integral;
};
void Pid_init(void)
{
PID.SetSpeed=60;
PID.DriverOut=0;
PID.Err=0;
PID.LastErr=0;
PID.Kp=2.2;
PID.Ki=0;
PID.Kd=0;
}
//定时调用
void AutoReloadCallback(void)
{
int Actual_Encoder_Hall_Speed = 0;
int res_pwm = 0;
Actual_Encoder_Hall_Speed=HallPulseNumber;//
PID.LastErr = PID.Err;
PID.Err = PID.SetSpeed -Actual_Encoder_Hall_Speed;
PID.Integral += PID.Err;
// PID.DriverOut = PID.Kp * PID.Err +
// PID.Ki * PID.Integral +
// PID.Kd * (PID.Err - PID.LastErr);
PID.DriverOut = PID.Kp * PID.Err ;
//DriverOut为检测到零点之后延时打开可控硅的时间。
if(PID.DriverOut>165)PID.DriverOut=165;;
if(PID.DriverOut<30)PID.DriverOut=30;
} 单独调整PID.SetSpeed,固定float Kp;
单独调整float Kp,固定PID.SetSpeed;
固定速度在某个值,有的时候能稳定,多开几次又出现了振动,一到速度时候又上升,然后慢慢下降到设置速度,一到之后又上升,反反复复;
在实际应用中,电机的负载变化也会影响调速效果 暖心小太阳 发表于 2025-3-18 13:26
在实际应用中,电机的负载变化也会影响调速效果
PID 不就是 让负载变化的时候,能比较稳定在某个转速么?、 本帖最后由 hzocce 于 2025-3-19 16:24 编辑
struct PID
{
float SetSpeed;//每100ms的转速
float DriverOut;//为检测到零点之后延时打开可控硅的时间。
float Err;//当次误差
float LastErr;//上次误差
float Kp;
float Ki;
float Kd;
float Integral;
};
void Pid_init(void)
{
PID.SetSpeed=60;
PID.DriverOut=0;
PID.Err=0;
PID.LastErr=0;
PID.Kp=2.2;
PID.Ki=0;
PID.Kd=0;
}
//定时调用
void AutoReloadCallback(void)
{
int Actual_Encoder_Hall_Speed = 0;
int res_pwm = 0;
Actual_Encoder_Hall_Speed=HallPulseNumber;//
PID.LastErr = PID.Err;
PID.Err = Actual_Encoder_Hall_Speed-PID.SetSpeed ;//发现这样才行,为什么?
//PID.Err = PID.SetSpeed -Actual_Encoder_Hall_Speed;
PID.Integral += PID.Err;
PID.DriverOut = PID.Kp * PID.Err +
PID.Ki * PID.Integral +
PID.Kd * (PID.Err - PID.LastErr);
//DriverOut为检测到零点之后延时打开可控硅的时间。
if(PID.DriverOut>165)PID.DriverOut=165;;
if(PID.DriverOut<30)PID.DriverOut=30;
Out(PID.DriverOut);
}
看到的现象是,屏蔽上面的取值,直接给PID.DriverOut赋值,如下
赋值时得到如下数值:
PID.DriverOut=172;HallPulseNumber=12;
PID.DriverOut=170;HallPulseNumber=20;
PID.DriverOut=165;HallPulseNumber=45;
PID.DriverOut=160;HallPulseNumber=70;
PID.DriverOut=150;HallPulseNumber=100;
PID.DriverOut=140;HallPulseNumber=125;
PID.DriverOut=130;HallPulseNumber=143;
如上AutoReloadCallback有没有那里有问题?
那
PID.Kp、PID.Ki、PID.Kd大概怎么取值才合适,
随意给i为1,d为1
拔掉电机的电极,完全静止的时候上电,空载的时候,能稳定下来转速。
拔掉电机的电极,未停下来的时候上电,发现转速失控了。 别别沉了 ........ 跟着学习下,最近学电机。 关注起来~~
页:
[1]