Changeset - 68a022485d9b
[Not reviewed]
default
0 1 0
Ethan Zonca - 10 years ago 2014-09-03 21:04:19
ez@ethanzonca.com
Implement windup guard
1 file changed with 7 insertions and 6 deletions:
main.c
7
6
0 comments (0 inline, 0 general)
main.c
Show inline comments
 
@@ -137,50 +137,52 @@ void update_temp() {
 
    }
 
 
    // Deassert CS
 
    delay(1);
 
    GPIO_SetBits(MAX_CS);
 
}
 
 
 
// PID implementation
 
int16_t last_pid_temp = 0;
 
uint8_t last_pid_temp_frac = 0;
 
int16_t i_state = 0;
 
 
#define WINDUP_GUARD_GAIN 100
 
uint16_t windup_guard = WINDUP_GUARD_GAIN;
 
 
int16_t update_pid(uint16_t k_p, uint16_t k_i, uint16_t k_d, int16_t temp, uint8_t temp_frac, int16_t setpoint) 
 
{
 
  // Calculate instantaneous error
 
  int16_t error = (int16_t)setpoint - (int16_t)temp; // TODO: Use fixed point fraction
 
 
  // Proportional component
 
  int16_t p_term = k_p * error;
 
 
  // Error accumulator (integrator)
 
  i_state += error;
 
 
  // to prevent the iTerm getting huge despite lots of 
 
  //  error, we use a "windup guard" 
 
  // (this happens when the machine is first turned on and
 
  // it cant help be cold despite its best efforts)
 
  // not necessary, but this makes windup guard values 
 
  // relative to the current iGain
 
  int16_t windup_guard = WINDUP_GUARD_GAIN / k_i;  
 
  int16_t windup_guard_res = WINDUP_GUARD_GAIN / k_i;  
 
 
  // Calculate integral term with windup guard 
 
  if (i_state > windup_guard) 
 
    i_state = windup_guard;
 
  else if (i_state < -windup_guard) 
 
    i_state = -windup_guard;
 
  if (i_state > windup_guard_res) 
 
    i_state = windup_guard_res;
 
  else if (i_state < -windup_guard_res) 
 
    i_state = -windup_guard_res;
 
  int16_t i_term = k_i * i_state;
 
 
  // Calculate differential term (slope since last iteration)
 
  int16_t d_term = (k_d * (temp - last_pid_temp));
 
 
  // Save temperature for next iteration
 
  last_pid_temp = temp;
 
  last_pid_temp_frac = temp_frac;
 
 
  int16_t result = p_term + i_term - d_term;
 
 
  // Put out tenths of percent, 0-1000. 
 
@@ -194,25 +196,24 @@ int16_t update_pid(uint16_t k_p, uint16_
 
}
 
 
 
 
 
uint32_t ticks = 0;
 
uint32_t last_ssr_on = 0;
 
uint32_t last_led = 0;
 
int32_t setpoint = 0;
 
uint16_t k_p = 1;
 
uint16_t k_i = 1;
 
uint16_t k_d = 1;
 
uint16_t windup_guard = 1;
 
int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD 
 
uint8_t pid_enabled = 0;
 
 
// Process things
 
void process()
 
{
 
    update_temp(); // Read MAX31855
 
 
    // TODO: Add calibration offset (linear)
 
 
    if(ticks - last_led > 400) 
 
    {
0 comments (0 inline, 0 general)