amobbs.com 阿莫电子技术论坛
标题:
求温度控制PID自整定解决方案,欢迎大家一起讨论
[打印本页]
作者:
51ZHOUJUNHUA
时间:
2023-5-29 22:25
标题:
求温度控制PID自整定解决方案,欢迎大家一起讨论
最近在研究继电反馈PID自整定算法,发现算出来的PID值还没有硬件调出来的值准确,还有温度控制能用增量式PID算法么?求求大家为小白答疑解惑
作者:
51ZHOUJUNHUA
时间:
2023-5-29 22:26
/***********************************************************************/
//*******函数名:void PID_Auto(void)
//*******用途:PID自整定
//*******说明:构建闭环回路 确定稳定极限 确定两个参数 极限值KP和震荡周期·
//*******参数:无
//*******返回值:无
/***********************************************************************/
void PID_Auto(void)
{
u8 save_buff[6] = {0}; //保存数据缓存
u8 i = 0;
float KC = 0;
float TC = 0;
float sum_temp = 0,min_temp = 0,max_temp = 0,aver_temp = 0;
//第一步进入比较初始温度 确定此时温度处于哪种情况
if(PID_read == 0)
{
if(PID.SetSpeed >= PID.ActualSpeed) // 如果初始温度小于设定值
{
pid_self_first_status_flag = 1;
Step_Auto = 0;
}
else// 如果初始温度大于设定值
{
pid_self_first_status_flag = 0;
Step_Auto = 1;
}
PID_read = 1;
}
if(PID_Auto_Deal == 1) //自整定过程 修改成500ms 计算一次 如果需要精度很高 计算周期必须短
{
PID_Auto_Deal = 0; //清除标识
PID_Auto_Time++; //整定时间计数
if(PID_Auto_Time >= 6000)//整定时间超过50分钟 整定失败数据回滚
{
PID_Auto_Time = 0; //计数清零
}
//程序第一次进入 查看对比当前温度和设定温度
//0 设定温度 低于 当前温度 //1设定温度 高于 或者 等于 当前温度 启动加热
if(( pid_self_first_status_flag == 1) || ( pid_self_first_status_flag == 0))//0 设定温度 低于 当前温度 //1设定温度 高于 或者 等于 当前温度 启动加热
{
if(PID.SetSpeed >= PID.ActualSpeed)//启动加热
{
PID_cool_cnt = 0;
PID_heat_cnt++;
if(PID_heat_cnt >= 3)//连续3次结果都大于大于实际温度
{
PID.voltage = 100;//全速加热
percent_lv = Ar_Set;
if(Step_Auto == 0)
{
Step_Auto = 1;
zero_across_counter++;
if(zero_across_counter == 3)
{
time_low = PID_Auto_Time - 3;//此时的时间不是最低温度对应的时间
}
}
}
}
else//当前温度 大于 设定温度 停止加热
{
PID_cool_cnt++;
PID_heat_cnt = 0;
if(PID_cool_cnt > 3)
{
PID.voltage = 950;//不加热
percent_lv = 0;
if(Step_Auto == 1)
{
Step_Auto = 0;
zero_across_counter++;
if(zero_across_counter == 3)
{
time_low = PID_Auto_Time - 3;//此时的时间不是最低温度对应的时间
}
}
}
}
//最低温度 出现在 zero_across_counter = 3 的阶段
//最高温度 出现在 zero_across_counter = 4 的阶段
if((zero_across_counter == 3 ) || (zero_across_counter == 4 ))
{
pid_self_calc_buffer[k_pid_self_counter] = PID.ActualSpeed;
k_pid_self_counter++;
if(k_pid_self_counter > 3)//0--3 共4个元素
{
k_pid_self_counter = 0;
enable_calc_min_max_flag = 1;
}
if(enable_calc_min_max_flag == 1)//只要有4个值,就可以计算了 后面来的值覆盖了前面的值
{
//去掉最小值 最大值 取剩下2个值的平均值
sum_temp = 0; //先清0
min_temp = 300.0;
max_temp = -80.0;
for(i = 0;i < 4;i++)
{
if(pid_self_calc_buffer[i] <= min_temp)
{
min_temp = pid_self_calc_buffer[i];
}
if(pid_self_calc_buffer[i] >= max_temp)
{
max_temp = pid_self_calc_buffer[i];
}
sum_temp += pid_self_calc_buffer[i];
}
sum_temp = sum_temp - min_temp - max_temp ;
//pid_self_first_status_flag = 1 时 最低温度出现在3阶段
//pid_self_first_status_flag = 0 时 最低温度出现在4阶段
if(pid_self_first_status_flag == 1)
{
if(zero_across_counter == 3 )//最低温度
{
aver_temp = (sum_temp/2.0);
if( aver_temp <= temp_low )
{
temp_low = aver_temp;
}
}
else if(zero_across_counter == 4 )//最高温度
{
aver_temp = (sum_temp/2.0);
if( aver_temp >= temp_high )
{
temp_high = aver_temp;
}
}
}
else if(pid_self_first_status_flag == 0)
{
if(zero_across_counter == 4 )//最低温度
{
aver_temp = (sum_temp/2.0);
if( aver_temp <= temp_low )
{
temp_low = aver_temp;
}
}
else if(zero_across_counter == 3 )//最高温度
{
aver_temp = (sum_temp/2.0);
if( aver_temp >= temp_high )
{
temp_high = aver_temp;
}
}
}
}
}
else if(zero_across_counter == 5 )//4次过0 则说明出现了振荡 整定成功
{
zero_across_counter = 0;
PID_Auto_Deal = 0;//退出pid阶段
time_high = PID_Auto_Time - 3;//此时的时间不是最高温度对应的时间
KC = 127/(temp_high - temp_low);
TC = 1 * (time_high - time_low);//如果记录了 最低温度 与 最高温度对应的时间 那么沿用这个公式:TC = 2 * (TIME_Hight - TIME_LOW);
PID.Kp = 0.6*KC;
PID.Ki = (0.6*KC)/(0.5*TC)/10;
PID.Kd = (0.6*KC)*(0.125*TC)/60;
if(dp_Set == 0)
{
if(PID.Ki < 0.1)
{
PID.Ki = 0.1;
}
}
else
{
if(PID.Ki < 0.01)
{
PID.Ki = 0.01;
}
}
if(dp_Set == 1)
{
P_Set[cool_open_flag] = PID.Kp*100;
I_Set[cool_open_flag] = PID.Ki*100;
}
else
{
P_Set[cool_open_flag] = PID.Kp*10;
I_Set[cool_open_flag] = PID.Ki*10;
}
D_Set[cool_open_flag] = PID.Kd;
save_buff[0] = P_Set[cool_open_flag]>>8;
save_buff[1] = P_Set[cool_open_flag];
save_buff[2] = I_Set[cool_open_flag]>>8;
save_buff[3] = I_Set[cool_open_flag];
save_buff[4] = D_Set[cool_open_flag]>>8;
save_buff[5] = D_Set[cool_open_flag];
W25QXX_Write(save_buff,4 + 12*cool_open_flag,6);
PID_Auto_flag = 0;
temp_high = -80.0; //得到最高温度
temp_low = 300; //得到最低温度
time_high = 0; //得到最高温度
time_low = 0; //得到最低温度
PID_Auto_Time = 0;
Status_show(3,0);//符号不显示
}
}
}
}
作者:
lyping1987
时间:
2023-5-30 01:17
这头像。。
作者:
罗小蘑菇
时间:
2023-5-30 04:42
这头像……
作者:
tang_qianfeng
时间:
2023-5-30 05:58
这头像……
作者:
wang137long
时间:
2023-5-30 07:02
最近也在弄PID,大部分都是控制继电器的,现在主要想找到温度值附近就输出一个恒定的PWM,不要一下高一下低的PWM.
作者:
zhangling520
时间:
2023-5-30 08:14
继电器的寿命 得考虑呀
作者:
mypear
时间:
2023-5-30 08:37
还以为阿莫搞嵌入式,原来。。。。。
作者:
jbpan852
时间:
2023-5-30 08:45
以为阿莫搞嵌入式,原来。。。。。
作者:
yanyanyan168
时间:
2023-5-30 09:07
以为阿莫搞嵌入式,原来。。。。。
作者:
51ZHOUJUNHUA
时间:
2023-5-30 09:48
有大哥帮忙指点一下迷津么?这个整定过程是不是有问题,整定出来的P:4.751 I:0.007 D:1.227
作者:
51ZHOUJUNHUA
时间:
2023-5-30 09:49
lyping1987 发表于 2023-5-30 01:17
这头像。。
(引用自3楼)
这头像怎么了
作者:
GZLJZ
时间:
2023-5-30 22:00
哈哈,竟然不知是老大的头像,还是...
作者:
jiezi
时间:
2023-5-30 23:06
封号警告,,,,
作者:
spring152
时间:
2023-5-31 06:12
这是坛主小号??
作者:
armok.
时间:
2023-5-31 06:43
spring152 发表于 2023-5-31 06:12
这是坛主小号??
(引用自15楼)
当然不是。
已经后台警告楼主。封锁ID到今晚23:59
欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/)
Powered by Discuz! X3.4