diff --git a/HARDWARE/PID.c b/HARDWARE/PID.c index 8d80cc4..517f340 100644 --- a/HARDWARE/PID.c +++ b/HARDWARE/PID.c @@ -2,7 +2,6 @@ #include "Relays.h" #include "USART.h" #include "rs485.h" -extern u16 tem; float cold_tem = 0; float red_tem = 0; float ti; @@ -18,7 +17,6 @@ int max_speed_count = 6000; void PID_Init() { - // pid.set_tem=tem;// user set temperature // if flash have not a vaild value, just set a default value if (pid.Kp < 1e-7) { pid.Kp = 9.6; } if (pid.Ki < 1e-7) { pid.Ki = 0.01; } @@ -32,13 +30,22 @@ void PID_Init() pid.OUT0 = 1; pid.C1ms = 0; - pid.hp = 2.4; - pid.hi = 0.02; - pid.hd = 0; + pid.max_compressor_tem = 30; - pid.cp = 9.6; + pid.hp_h = 5; + pid.hi_h = 0.02; + pid.hd_h = 0.5; + pid.h_base_h = 0; + + pid.hp_l = 19.2; + pid.hi_l = 0.08; + pid.hd_l = 0; + pid.h_base_l = 30; + + pid.cp = 4.8; pid.ci = 0; pid.cd = 0; + pid.c_base = 37; pid.h_percent = 0; pid.c_speed = 0; @@ -93,8 +100,8 @@ void set_heater_power(int percent) { /** * heater power calc */ -int calc_hp(float delta_t, float Error_calc, int p_hb, float pid_hp, float pid_hi) { - int p_h = p_hb + pid_hp * delta_t + pid_hi * Error_calc; +int calc_hp(float delta_t, float Error_calc, float DelEk, int p_hb, float pid_hp, float pid_hi, float pid_hd) { + int p_h = p_hb + pid_hp * delta_t + pid_hi * Error_calc + pid_hd * DelEk; if (p_h > 100) { return 100; } @@ -136,8 +143,6 @@ void PID_Calc() // pid calc { int min_speed_count = 1800; int max_speed_count = 4800; - int p_hb = 52; - int p_cb = 33; float DelEk; // The difference between the last two deviations // float td; float out; @@ -148,32 +153,55 @@ void PID_Calc() // pid calc // } float delta_t = pid.set_tem - pid.now_tem; - - int p_c = calc_cp(delta_t, p_cb, pid.cp); - pid.c_speed = calc_compressor_speed(p_c, min_speed_count, max_speed_count); - + // When the target tem is greater then max compressor tem, the compressor will stop + if (pid.set_tem > pid.max_compressor_tem) { + pid.c_speed = 0; + } else { + int p_c = calc_cp(delta_t, pid.c_base, pid.cp); + pid.c_speed = calc_compressor_speed(p_c, min_speed_count, max_speed_count); + } + + float hp = pid.hp_h; + float hi = pid.hi_h; + float hd = pid.hd_h; + int h_base = pid.h_base_h; + + // l mode + if (pid.set_tem <= pid.max_compressor_tem) { + hp = pid.hp_l; + hi = pid.hi_l; + hd = pid.hd_l; + h_base = pid.h_base_l; + } + pid.Ek = pid.set_tem - pid.now_tem; pid.Pout = pid.Kp * pid.Ek; // Proportional output pid.SEk += pid.Ek; // Total historical deviation + DelEk = pid.Ek - pid.Ek_prev; // The difference between the last two deviations + + // no integral when the deviation is too large + if (pid.now_tem < pid.set_tem - 3) { + pid.SEk = 0; + } + // SEk limit, updated func - if (pid.SEk < - p_hb / pid.hi) { - pid.SEk = - p_hb / pid.hi; + if (pid.SEk < - h_base / hi) { + pid.SEk = - h_base / hi; } if (pid.c_speed == max_speed_count) { pid.SEk = 0; } float Error_calc = pid.SEk; - if (Error_calc < - (p_hb + pid.hp * delta_t) / pid.hi) { - Error_calc = - (p_hb + pid.hp * delta_t) / pid.hi; + if (Error_calc < - (h_base + hp * delta_t) / hi) { + Error_calc = - (h_base + hp * delta_t) / hi; } if (pid.c_speed == max_speed_count) { Error_calc = 0; } - DelEk = pid.Ek - pid.Ek_1; // The difference between the last two deviations // ti=pid.t/pid.Ti; // ki=ti*pid.Kp; @@ -203,11 +231,9 @@ void PID_Calc() // pid calc { pid.OUT = out; } - pid.Ek_1 = pid.Ek; // udpate difference - pid.C1ms = 0; // heater percent - pid.h_percent = calc_hp(delta_t, Error_calc, p_hb, pid.hp, pid.hi); + pid.h_percent = calc_hp(delta_t, Error_calc, DelEk, h_base, hp, hi, hd); // close heater when compressor is running in full state if (pid.c_speed == max_speed_count) { pid.h_percent = 0; @@ -216,4 +242,8 @@ void PID_Calc() // pid calc set_compressor_power(pid.c_speed); set_heater_power(pid.h_percent); + + pid.Ek_prev = pid.Ek; // udpate difference + pid.C1ms = 0; + } diff --git a/HARDWARE/PID.h b/HARDWARE/PID.h index 169d7a2..a3900d9 100644 --- a/HARDWARE/PID.h +++ b/HARDWARE/PID.h @@ -10,14 +10,30 @@ typedef struct Pid { float set_tem;// User settings float now_tem;// current temperature + + float max_compressor_tem; // maximum temperature of the compressor. When the target tem is greater than this value, the compressor is turned off. + + float out_tem; // outer temperature + float out_humidity; // outer humidity - float hp; - float hi; - float hd; + // in h mode + float hp_h; + float hi_h; + float hd_h; + int h_base_h; // base power percent in h mode + + // in l mode + float hp_l; + float hi_l; + float hd_l; + int h_base_l; // base power percent in l mode int h_percent; + + float cp; float ci; float cd; + float c_base; int c_speed; float Kp; // 110 @@ -28,7 +44,7 @@ typedef struct Pid float Td; float Ek; // This deviation - float Ek_1;// Last deviation + float Ek_prev;// Last deviation float SEk; // The sum of historical deviations float Iout; diff --git a/HARDWARE/rs485.c b/HARDWARE/rs485.c index 3a4b3e4..16afe73 100644 --- a/HARDWARE/rs485.c +++ b/HARDWARE/rs485.c @@ -380,6 +380,10 @@ void RS485_1_Send_Data_1(u8 *buf, u8 len) void RS485_1_Send_Data_2(void) { + // when T eq 0 and H eq 0, don't send + if (T == 0 && H == 0) { + return; + } sendbuf[0] = 0xEE; sendbuf[1] = 0xB5; sendbuf[2] = 0x05; @@ -450,21 +454,35 @@ void RS485_1_Send_Data_2(void) sendbuf[25] = 0; // ALARM state sendbuf[26] = ALARM; // ALARM state - sendbuf[27] = (int)pid.hp / 256; // Kp 110 - sendbuf[28] = (int)pid.hp % 256; // Kp 110 - sendbuf[29] = ((int)(pid.hi * 100000)) / 256; // Ti 0.001 - sendbuf[30] = ((int)(pid.hi * 100000)) % 256; // Ti 0.001 - sendbuf[31] = (int)pid.hd / 256; // Td 340 - sendbuf[32] = (int)pid.hd % 256; // Td 340 + if (pid.set_tem > pid.max_compressor_tem) { + // h mode + sendbuf[27] = (int)(pid.hp_h * 1000) / 256; // Kp 110 + sendbuf[28] = (int)(pid.hp_h * 1000) % 256; // Kp 110 + sendbuf[29] = ((int)(pid.hi_h * 100000)) / 256; // Ti 0.001 + sendbuf[30] = ((int)(pid.hi_h * 100000)) % 256; // Ti 0.001 + sendbuf[31] = (int)(pid.hd_h * 1000) / 256; // Td 340 + sendbuf[32] = (int)(pid.hd_h * 1000) % 256; // Td 340 + } else { + // l mode + sendbuf[27] = (int)(pid.hp_l * 1000) / 256; // Kp 110 + sendbuf[28] = (int)(pid.hp_l * 1000) % 256; // Kp 110 + sendbuf[29] = ((int)(pid.hi_l * 100000)) / 256; // Ti 0.001 + sendbuf[30] = ((int)(pid.hi_l * 100000)) % 256; // Ti 0.001 + sendbuf[31] = (int)(pid.hd_l * 1000) / 256; // Td 340 + sendbuf[32] = (int)(pid.hd_l * 1000) % 256; // Td 340 + } sendbuf[33] = pid.h_percent / 256; // h_percent sendbuf[34] = pid.h_percent % 256; // h_percent - sendbuf[35] = (int)pid.cp / 256; // Kp 110 - sendbuf[36] = (int)pid.cp % 256; // Kp 110 + sendbuf[35] = (int)(pid.cp * 1000) / 256; // Kp 110 + sendbuf[36] = (int)(pid.cp * 1000) % 256; // Kp 110 sendbuf[37] = ((int)(pid.ci * 100000)) / 256; // Ti 0.001 sendbuf[38] = ((int)(pid.ci * 100000)) % 256; // Ti 0.001 - sendbuf[39] = (int)pid.cd / 256; // Td 340 - sendbuf[40] = (int)pid.cd % 256; // Td 340 + // sendbuf[39] = (int)pid.cd / 256; // Td 340 + // sendbuf[40] = (int)pid.cd % 256; // Td 340 + // TODO::temply print out_tem + sendbuf[39] = (int)(pid.out_tem * 10) / 256; // Td 340 + sendbuf[40] = (int)(pid.out_tem * 10) % 256; // Td 340 sendbuf[41] = pid.c_speed / 256; // h_percent sendbuf[42] = pid.c_speed % 256; // h_percent diff --git a/myfreertos/myfreertos.c b/myfreertos/myfreertos.c index 23ebafd..e9ce7a8 100644 --- a/myfreertos/myfreertos.c +++ b/myfreertos/myfreertos.c @@ -185,7 +185,8 @@ void SensorDataRequestTask(void *pvParameters) { while (1) { // 发送传感器数据请求的操作 RS485_1_Send_Data_1(rs485buf, 8); - // delay_xms(100); + delay_xms(100); + // RS485_1_Send_Data_1(RS485_RX_BUF, 48); vTaskDelay(SENSOR_DATA_REQUEST_PERIOD); @@ -206,54 +207,9 @@ int hot = 0; */ void HotTestRequestTask(void *pvParameters) { while (1) { - - PID_Calc(); - // if (T >= 350) { - // hot = 0; - // hot_clod_flag = 0; - // } else { - // hot = 52; - - // hot_clod_flag = 2; - // // hot += 10; - // // if (hot > 100) { - // // hot = 10; - // // } - // } - // u8 temp_data[8] = { 0x10, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; - - // temp_data[4] = hot / 256; - // temp_data[5] = hot % 256; - - // GetCRC16(temp_data, 6, temp_data + 6, temp_data + 7); - - // RS485_3_Init(9600); - // RS485_3_Send_Data(temp_data, 8); - // // RS485_1_Send_Data(temp_data, 8); - // delay_xms(30); - // RS485_1_Init(9600); - - - // HC595_Send_Byte(gpio_state |= 0x04); // open heater |=0000 0100 0x04 - - // vTaskDelay(60000); - - - - // temp_data[4] = 0; - // temp_data[5] = 0; - - // GetCRC16(temp_data, 6, temp_data + 6, temp_data + 7); - - // // RS485_3_Init(9600); - // RS485_1_Send_Data(temp_data, 8); - // // RS485_3_Send_Data(temp_data, 8); - // // delay_xms(30); - // // RS485_1_Init(9600); - - // // HC595_Send_Byte(gpio_state &= 0xFB); // close heater &=1111 1011 0xFB - // hot_clod_flag = 0; - + if (!(T == 0 && H == 0)) { + PID_Calc(); + } vTaskDelay(5000); } }