Hi,
I was reading your blog post here: http://brettbeauregard.com/blog/2012/01/arduino-pid-autotune-library/ and trying to implement autotune library to maintain temperature in industrial ovens.
1. We bought a Delta Electronics PID and oven and see how it Delta Electronics PID controller do autotune. Below is the graph we obtained
2. Since it looks like Astrom-Hagglund(Relay) Method, sowe tried to get Kc & Tu values from it.
3. For our reading we took readings from second cycle only.
4. a) Tu is calculated in seconds
b) Kc = (4*D)/(pi*A)
D=100 taken since relay is 100% on or off only
A=Difference between +peak and -peak value.
5. One important thing we note that its not symmetrical oscillation, (zero to +peak) is higher than (zero to -peak) value.
6. But when we put it in formula as in link above menetioned code, outout is always saturated high. I think we have to normailize outut formula before using, but dont know how to do it or anything we are doing in our code.
I was reading your blog post here: http://brettbeauregard.com/blog/2012/01/arduino-pid-autotune-library/ and trying to implement autotune library to maintain temperature in industrial ovens.
1. We bought a Delta Electronics PID and oven and see how it Delta Electronics PID controller do autotune. Below is the graph we obtained
2. Since it looks like Astrom-Hagglund(Relay) Method, sowe tried to get Kc & Tu values from it.
3. For our reading we took readings from second cycle only.
4. a) Tu is calculated in seconds
b) Kc = (4*D)/(pi*A)
D=100 taken since relay is 100% on or off only
A=Difference between +peak and -peak value.
5. One important thing we note that its not symmetrical oscillation, (zero to +peak) is higher than (zero to -peak) value.
6. But when we put it in formula as in link above menetioned code, outout is always saturated high. I think we have to normailize outut formula before using, but dont know how to do it or anything we are doing in our code.
Code:
const float32_t c_output_max = 100.0f;
const float32_t c_output_min = 0.0f;
float32_t input_temperature;
float32_t setpoint_temperature;
float32_t output_duty_cycle;
float32_t i_term;
float32_t last_input;
//ku = 12.60633212609071966486208026713f; units: per degree celsius
//tu = 820 seconds
float32_t kp = 7.563799f; //kp = 0.6*Ku
float32_t ki = 0.018448f; // ki = 1.2*Ku/Tu
float32_t kd = 775.289425f; // ki = 0.075*Ku*Tu
float32_t sample_time = 1.0f; // 1 second
//sample_time + derivative_kick + On-The-Fly Tuning Changes + integral windup +
void compute_pid_duty_cycle(void)
{
float32_t error;
float32_t d_input;
/* get error */
error = setpoint_temperature - input_temperature;
/* integral error */
i_term = i_term + (error * ki);
if(i_term > c_output_max)
{
i_term = c_output_max;
}
else if(i_term < c_output_min)
{
i_term = c_output_min;
}
else
{
}
/* differential error */
d_input = input_temperature - last_input;
/*Compute PID Output*/
output_duty_cycle = (kp * error) + (i_term) - (kd * d_input);
if(output_duty_cycle > c_output_max)
{
output_duty_cycle = c_output_max;
}
else if(output_duty_cycle < c_output_min)
{
output_duty_cycle = c_output_min;
}
else
{
}
/*Remember some variables for next time*/
last_input = input_temperature;
} /* function ends here */