如题 ,现在在做一个给气囊打气,并将气囊压力保持在设定值的项目。气压传感器是IIC通信的,间隔1秒发送一次数据。微型气泵用来打气,使用PWM控制,因为气囊不大,微型气泵在PID工作时达不到工作电压范围就超调了,然后开始震荡。
又因为微型气泵不在工作电压范围,就导致在同一PWM值下,有时启动,有时不启动,现象就是一直在振幅40%左右震荡。
调整多次PID参数都是这样,没什么改善。第一次做PID,不是很懂,请各位大神指点指点。
PID参数初始化:
[C] 纯文本查看 复制代码 void PID_Init(float Kp, float Ki, float Kd, float setpoint, float dt)
{
pid.Kp = Kp; // 比例系数
pid.Ki = Ki; // 积分系数
pid.Kd = Kd; // 微分系数
pid.setpoint = setpoint; // 目标压力值
pid.integral = 0; // 积分项累计值,误差和
pid.prev_error = 0; // 上一次误差(用于微分计算)
pid.dt = dt; // 控制周期(需与传感器采样周期匹配)
pid.out_min = 0; // PWM最小占空比(如0%)
pid.out_max = 360; // PWM最大占空比(如100%)
}
[C] 纯文本查看 复制代码 PID_Init(0.5, 0.03, 0.1, 50.0, 1);
PID计算函数:
[C] 纯文本查看 复制代码 float PID_Compute(float measured)
{
float error,derivative,output;
//计算误差
error = pid.setpoint - measured;
// 积分项
pid.integral += error * pid.dt;
// 微分项
derivative = (error - pid.prev_error) / pid.dt;
// 计算输出
output = pid.Kp * error + pid.Ki * pid.integral + pid.Kd * derivative;
// 输出限幅
output = (output > pid.out_max) ? pid.out_max :
(output < pid.out_min) ? pid.out_min : output;
return output;
}
main函数调用:
[C] 纯文本查看 复制代码 if(g_RunTime-TIME2>=1000)//1s间隔,因为传感器反应时间
{
Lwp6130_Send_Command_BLAST();
current_pressure = Lwp6130_FullData_Read_BLAST();
// PID计算并更新PWM
output1 = PID_Compute(current_pressure);
pwmvalue=(uint16_t)(output1*10+1000);
printf("current_pressure=%f,output1=%f,pwmvalue=%d\r\n",current_pressure,output1,pwmvalue);
TIM_SetCompare2(TIM4, pwmvalue);
TIME2=g_RunTime;
}
PWM初始化:
[C] 纯文本查看 复制代码 TIM4_PWM_init(3599,0);
|