Files
@ 9294a623e8e5
Branch filter:
Location: therm/pid.c - annotation
9294a623e8e5
1.8 KiB
text/plain
Added support for both heaters and coolers as well as thermostatic control
db81b1787e6e b42e15fadfde b42e15fadfde b42e15fadfde db81b1787e6e db81b1787e6e db81b1787e6e db81b1787e6e db81b1787e6e db81b1787e6e db81b1787e6e db81b1787e6e b42e15fadfde 9d6570f4456f 9d6570f4456f 9d6570f4456f 9d6570f4456f 9d6570f4456f 9d6570f4456f b42e15fadfde 9d6570f4456f b42e15fadfde b42e15fadfde db81b1787e6e b42e15fadfde b42e15fadfde db81b1787e6e b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde 9d6570f4456f b42e15fadfde b42e15fadfde db81b1787e6e db81b1787e6e db81b1787e6e db81b1787e6e b42e15fadfde db81b1787e6e b42e15fadfde b42e15fadfde 9d6570f4456f b42e15fadfde b42e15fadfde 9d6570f4456f b42e15fadfde 9d6570f4456f b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde b42e15fadfde | #include "pid.h"
// PID implementation
void pid_init(pid_state_t* state)
{
state->i_state = 0;
state->last_pid_temp = 0;
state->last_pid_temp_frac = 0;
}
int16_t pid_update(therm_settings_t* set, therm_status_t* status, pid_state_t *state)
{
// Convert temperature to fixed point number with 1/10th resolution
int8_t temp_frac = status->temp_frac > 9 ? status->temp_frac / 10 : status->temp_frac;
temp_frac = status->temp > 0 ? temp_frac : temp_frac * -1;
int32_t temp = (status->temp * 10) + temp_frac;
// Calculate instantaneous error
int16_t error = status->setpoint * 10 - temp; // TODO: Use fixed point fraction
// Proportional component
int32_t p_term = set->val.k_p * error;
// Error accumulator (integrator)
state->i_state += error;
// to prevent the iTerm getting huge from 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
int32_t windup_guard_res = (set->val.windup_guard * 10) / set->val.k_i;
// Calculate integral term with windup guard
if (state->i_state > windup_guard_res)
state->i_state = windup_guard_res;
else if (state->i_state < -windup_guard_res)
state->i_state = -windup_guard_res;
int32_t i_term = set->val.k_i * state->i_state;
// Calculate differential term (slope since last iteration)
int32_t d_term = (set->val.k_d * (temp - state->last_pid_temp));
// Save temperature for next iteration
state->last_pid_temp = temp;
int16_t result = (p_term + i_term - d_term) / 10;
// Put out tenths of percent, 0-1000.
if(result > 1000)
result = 1000;
else if(result < -1000)
result = -1000;
// Return feedback
return result;
}
|