@ -25,7 +25,7 @@ void PID_Init()
if ( pid . Kd < 1e-7 ) { pid . Kd = 340 ; }
if ( pid . Kd < 1e-7 ) { pid . Kd = 340 ; }
if ( pid . tem_threshold < 0.0001 ) { pid . tem_threshold = 0.2 ; }
if ( pid . tem_threshold < 0.0001 ) { pid . tem_threshold = 0.2 ; }
pid . t = 5 000; // PID calc period
pid . t = 1 000; // PID calc period
// pid.Ti=5000000;// integral time
// pid.Ti=5000000;// integral time
// pid.Td=1000;// differential time
// pid.Td=1000;// differential time
pid . pwmcycle = 200 ; // pwm cycle 200
pid . pwmcycle = 200 ; // pwm cycle 200
@ -50,6 +50,7 @@ void set_compressor_power(int speed) {
GetCRC16 ( data , 6 , data + 6 , data + 7 ) ;
GetCRC16 ( data , 6 , data + 6 , data + 7 ) ;
RS485_3_Init ( 9600 ) ;
RS485_3_Init ( 9600 ) ;
delay_xms ( 30 ) ;
RS485_3_Send_Data ( data , 8 ) ;
RS485_3_Send_Data ( data , 8 ) ;
delay_xms ( 30 ) ;
delay_xms ( 30 ) ;
RS485_1_Init ( 9600 ) ;
RS485_1_Init ( 9600 ) ;
@ -72,6 +73,8 @@ void set_heater_power(int percent) {
GetCRC16 ( data , 6 , data + 6 , data + 7 ) ;
GetCRC16 ( data , 6 , data + 6 , data + 7 ) ;
RS485_1_Init ( 9600 ) ;
delay_xms ( 30 ) ;
RS485_1_Send_Data ( data , 8 ) ;
RS485_1_Send_Data ( data , 8 ) ;
delay_xms ( 30 ) ;
delay_xms ( 30 ) ;
}
}
@ -79,7 +82,7 @@ void set_heater_power(int percent) {
/**
/**
* heater power calc
* heater power calc
*/
*/
int calc_ p( float t_t , float t_c , float error , int p_b , float pid_p , float pid_i ) {
int calc_ h p( float t_t , float t_c , float error , int p_b , float pid_p , float pid_i ) {
int p = p_b + pid_p * ( t_t - t_c ) + pid_i * error ;
int p = p_b + pid_p * ( t_t - t_c ) + pid_i * error ;
if ( p > 100 ) {
if ( p > 100 ) {
return 100 ;
return 100 ;
@ -90,33 +93,58 @@ int calc_p(float t_t, float t_c, float error, int p_b, float pid_p, float pid_i)
return p ;
return p ;
}
}
/**
* compressor power percent calc
*/
int calc_cp ( float t_t , float t_c , int p_cb , float pid_cp ) {
int percent = p_cb + pid_cp * ( t_c - t_t ) ;
if ( percent > 100 ) {
return 100 ;
}
if ( percent < 0 ) {
return 0 ;
}
return percent ;
}
/**
* compressor speed calc
*/
int calc_compressor_speed ( int percent , int v_min , int v_max ) {
int v = percent * v_max / 100.0 ;
if ( v > v_max ) {
return v_max ;
}
if ( v < v_min ) {
return v_min ;
}
return v ;
}
void PID_Calc ( ) // pid calc
void PID_Calc ( ) // pid calc
{
{
pid . Kp = 19.2 ;
float Kp = 19.2 ;
pid . Ki = 0.02 ;
float Ki = 0.02 ;
int p_base = 52 ;
int p_base = 52 ;
float DelEk ; // The difference between the last two deviations
float DelEk ; // The difference between the last two deviations
// float td;
// float td;
float out ;
float out ;
if ( pid . C1ms < ( pid . t ) ) // The calculation cycle has not yet arrived
// if (pid.C1ms < (pid.t)) // The calculation cycle has not yet arrived
{
return ;
}
// if (pid.set_tem > pid.now_tem)
// {
// {
// pid.Ek = pid.set_tem - pid.now_tem;
// return;
// }
// }
// else
// {
// pid.Ek = pid.now_tem - pid.set_tem;
// }
// pid.Ek = pid.now_tem - pid.set_tem;
pid . Ek = pid . set_tem - pid . now_tem ;
pid . Ek = pid . set_tem - pid . now_tem ;
pid . Pout = pid . Kp * pid . Ek ; // Proportional output
pid . Pout = pid . Kp * pid . Ek ; // Proportional output
pid . SEk + = pid . Ek ; // Total historical deviation
pid . SEk + = pid . Ek ; // Total historical deviation
// SEk limit
if ( pid . SEk < - p_base / Ki ) {
pid . SEk = - p_base / Ki ;
}
DelEk = pid . Ek - pid . Ek_1 ; // The difference between the last two deviations
DelEk = pid . Ek - pid . Ek_1 ; // The difference between the last two deviations
// ti=pid.t/pid.Ti;
// ti=pid.t/pid.Ti;
@ -151,74 +179,16 @@ void PID_Calc() // pid calc
pid . C1ms = 0 ;
pid . C1ms = 0 ;
// heater percent
// heater percent
int heater_percent = calc_ p( pid . set_tem , pid . now_tem , pid . SEk , p_base , pid. Kp, pid . Ki ) ;
int heater_percent = calc_ h p( pid . set_tem , pid . now_tem , pid . SEk , p_base , Kp, Ki ) ;
// TODO:: temply, set Kd to heater_percent, use for data upload
pid . Kd = heater_percent ;
// speed count
// int speed_count = pid.OUT / 200.0 * (max_speed_count - min_speed_count) + min_speed_count;
// if (speed_count > 6000) {
// speed_count = 6000;
// }
int speed_count = 1500 ;
// if (pid.now_tem < pid.set_tem + pid.tem_offset - pid.tem_threshold)
// {
// // Obtain the current deviation value
// // when the target temperature is 1 degree Celsius higher than the actual temperature, heat up
// // close compressor open heater
// /*GPIO1->Alarm bell GPIO3->heater GPIO4->Fresh air fan GPIO5->humidifier GPIO6->compressor */
// // HC595_Send_Byte(gpio_state &= 0xDF);//close compressor &=1101 1111 0xDF
// HC595_Send_Byte(gpio_state |= 0x04); // open heater |=0000 0100 0x04
// speed_count = 1500;
// hot_clod_flag = 2;
// pid.Iout = 0;
// } else if (pid.now_tem > pid.set_tem + pid.tem_offset - pid.tem_threshold && pid.now_tem < pid.set_tem + pid.tem_offset + pid.tem_threshold)
// {
// HC595_Send_Byte(gpio_state &= 0xFB); // close heater &=1111 1011 0xFB
// speed_count = 1000; // close compressor
// hot_clod_flag = 0;
int p_c = calc_cp ( pid . set_tem , pid . now_tem , 32 , Kp ) ;
// // pid.Iout=0;
int speed_count = calc_compressor_speed ( p_c , 1500 , 4500 ) ;
// } else if (pid.now_tem > pid.set_tem + pid.tem_offset + pid.tem_threshold)
// {
// // Obtain the current deviation value
// // when the target temperature is lower than the actual temperature, refrigerate
// // open compressor close heater
// HC595_Send_Byte(gpio_state &= 0xFB); // close heater &=1111 1011 0xFB
// // // 0-200 correspond 0-100%, if pid.out=50, percentage means 25% //num=50*400/200=100 100/400=25%
// // num = (((pid.OUT * 400) / pid.pwmcycle) - 1); // Conversion of pid.OUT and PWM Duty Cycle Values
// // TIM_SetCompare3(TIM3, num / 4);
// // printf("%d\r\n",num);
// // HC595_Send_Byte(gpio_state|=0x20);//open compressor |=0010 0000
// hot_clod_flag = 1;
// // pid.Iout=0;
// }
// TODO:: temply, set Ki to speed count, Kd to heater_percent, use for data upload
pid . Ki = speed_count ;
pid . Kd = heater_percent ;
set_compressor_power ( speed_count ) ;
set_compressor_power ( speed_count ) ;
set_heater_power ( heater_percent ) ;
set_heater_power ( heater_percent ) ;
// if (hot_clod_flag == 1 && T <= tem - 3) // During the refrigeration process, the actual temperature drops by 0.3 degrees Celsius below the set temperature
// {
// HC595_Send_Byte(gpio_state&=0xDB);// close compressor and heater &=1101 1011 0xDB
// // num = 0;
// // TIM_SetCompare3(TIM3, 0); // close compressor
// speed_count = 1000;
// hot_clod_flag = 0;
// }
// if (hot_clod_flag == 2 && T >= tem) // while heat, T above tem
// {
// HC595_Send_Byte(gpio_state&=0xDB);//close compressor and heater &=1101 1011 0xDB
// num = 0;
// TIM_SetCompare3(TIM3, 0); // close compressor
// hot_clod_flag = 0;
// }
// HC595_Send_Byte(gpio_state&=0xDB);// close compressor and heater &=1101 1011 0xDB
}
}