#ifndef __BSP_PID_H
#define __BSP_PID_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct
{
float target_val;
float err;
float err_last;
float Kp, Ki, Kd;
float integral;
float output_val;
} PID;
extern PID pid_Temper;
extern PID pid_speed;
void PID_param_init(void);
void set_pid_target(PID *pid, float temp_val);
float get_pid_target(PID *pid);
void set_p_i_d(PID *pid, float p, float i, float d);
float Temper_pid_update(PID *pid, float actual_val);
float speed_pid_update(PID *pid, float actual_val);
#endif
#include "bsp_pid.h"
PID pid_Temper;
PID pid_speed;
void PID_param_init()
{
pid_Temper.target_val = 0;
pid_Temper.output_val = 0.0;
pid_Temper.err = 0.0;
pid_Temper.err_last = 0.0;
pid_Temper.integral = 0.0;
pid_Temper.Kp = 3;
pid_Temper.Ki = 0.2;
pid_Temper.Kd = 5;
pid_speed.target_val = 10.0;
pid_speed.output_val = 0.0;
pid_speed.err = 0.0;
pid_speed.err_last = 0.0;
pid_speed.integral = 0.0;
pid_speed.Kp = 3.65;
pid_speed.Ki = 0.007;
pid_speed.Kd = 300.0;
}
extern float det_plus;
void set_pid_target(PID *pid, float temp_val)
{
pid->target_val = temp_val;
}
float get_pid_target(PID *pid)
{
return pid->target_val;
}
void set_p_i_d(PID *pid, float p, float i, float d)
{
pid->Kp = p;
pid->Ki = i;
pid->Kd = d;
}
#define TEMPER_DEAD_ZONE 60
#define TEMPER_INTEGRAL_START_ERR 50
#define TEMPER_INTEGRAL_MAX_VAL 150
float Temper_pid_update(PID *pid, float actual_val)
{
pid->err = pid->target_val - actual_val;
#if 0
if ((pid->err >= -TEMPER_DEAD_ZONE) && (pid->err <= TEMPER_DEAD_ZONE))
{
pid->err = 0;
pid->integral = 0;
pid->err_last = 0;
}
#endif
#if 0
pid->integral += pid->err;
#else
if (pid->err > -TEMPER_INTEGRAL_START_ERR && pid->err < TEMPER_INTEGRAL_START_ERR)
{
pid->integral += pid->err;
if (pid->integral > TEMPER_INTEGRAL_MAX_VAL)
{
pid->integral = TEMPER_INTEGRAL_MAX_VAL;
}
else if (pid->integral < -TEMPER_INTEGRAL_MAX_VAL)
{
pid->integral = -TEMPER_INTEGRAL_MAX_VAL;
}
}
#endif
pid->output_val = pid->Kp * pid->err +
pid->Ki * pid->integral +
pid->Kd * (pid->err - pid->err_last);
pid->err_last = pid->err;
return pid->output_val;
}
#define SPE_DEAD_ZONE 5.0f
#define SPE_INTEGRAL_START_ERR 300
#define SPE_INTEGRAL_MAX_VAL 150
float speed_pid_update(PID *pid, float actual_val)
{
pid->err = pid->target_val - actual_val;
#if 0
if ((pid->err > -SPE_DEAD_ZONE) && (pid->err < SPE_DEAD_ZONE))
{
pid->err = 0;
pid->integral = 0;
pid->err_last = 0;
}
#endif
#if 0
pid->integral += pid->err;
#else
{
pid->integral += pid->err;
if (pid->integral > SPE_INTEGRAL_MAX_VAL)
{
pid->integral = SPE_INTEGRAL_MAX_VAL;
}
else if (pid->integral < -SPE_INTEGRAL_MAX_VAL)
{
pid->integral = -SPE_INTEGRAL_MAX_VAL;
}
}
#endif
pid->output_val = pid->Kp * pid->err +
pid->Ki * pid->integral +
pid->Kd * (pid->err - pid->err_last);
pid->err_last = pid->err;
return pid->output_val;
}
#include "het_config.h"
extern PID pid_Temper;
extern PID pid_speed;
extern sturheat stheat;
void update_PID2PID(void)
{
static char step = 0;
static short ticks = 0;
static short temperLast = 0;
static short temperDelta = 0;
if (step == 0)
{
step = 1;
PID_param_init();
}
if ((ticks++ % 4) == 0)
{
set_pid_target(&pid_Temper, stheat.setTemp);
Temper_pid_update(&pid_Temper, stheat.temperature);
temperDelta = stheat.temperature - temperLast;
temperLast = stheat.temperature;
}
set_pid_target(&pid_speed, pid_Temper.output_val);
gHeat.Scr_Duty = speed_pid_update(&pid_speed, temperDelta);
if (pid_Temper.target_val == 0)
{
gHeat.Scr_Duty = 0;
}
if (gHeat.Scr_Duty < 0)
{
gHeat.Scr_Duty = 0;
}
else if (gHeat.Scr_Duty > 1000)
{
gHeat.Scr_Duty = 1000;
}
}