Files
@ 752fd27f607a
Branch filter:
Location: therm-ng/src/pid.c - annotation
752fd27f607a
2.8 KiB
text/plain
Basic code cleanup
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 72630eaa8151 72630eaa8151 72630eaa8151 72630eaa8151 a710d1e0fc2a 2b4eb31dd8da a710d1e0fc2a 752fd27f607a 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da 02c66b160d15 2b4eb31dd8da a710d1e0fc2a 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da a710d1e0fc2a a710d1e0fc2a 02c66b160d15 02c66b160d15 2b4eb31dd8da a710d1e0fc2a 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da f602474ad6c6 2b4eb31dd8da 2b4eb31dd8da f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 2b4eb31dd8da 7fc667dd7f38 f602474ad6c6 2b4eb31dd8da f602474ad6c6 f602474ad6c6 2b4eb31dd8da f602474ad6c6 f602474ad6c6 7fc667dd7f38 7fc667dd7f38 7fc667dd7f38 f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 2b4eb31dd8da f153d4ca027c 2b4eb31dd8da 2b4eb31dd8da 02c66b160d15 02c66b160d15 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da 2b4eb31dd8da f602474ad6c6 f602474ad6c6 a710d1e0fc2a f602474ad6c6 7fc667dd7f38 7fc667dd7f38 a710d1e0fc2a f602474ad6c6 f602474ad6c6 a710d1e0fc2a f602474ad6c6 f602474ad6c6 a710d1e0fc2a f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 7fc667dd7f38 a710d1e0fc2a f602474ad6c6 f602474ad6c6 2b4eb31dd8da f602474ad6c6 2b4eb31dd8da a710d1e0fc2a 7fc667dd7f38 7fc667dd7f38 7fc667dd7f38 7fc667dd7f38 f602474ad6c6 a710d1e0fc2a f602474ad6c6 f602474ad6c6 a710d1e0fc2a f602474ad6c6 f602474ad6c6 a710d1e0fc2a f602474ad6c6 a710d1e0fc2a f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 f602474ad6c6 a710d1e0fc2a f602474ad6c6 f602474ad6c6 a710d1e0fc2a a710d1e0fc2a a710d1e0fc2a | //
// PID: proportional/integral/derivative controller
//
#include "pid.h"
#include "flash.h"
// Private variables
static pid_state_t state;
// Initialize PID loop
void pid_init()
{
state.i_state = 0;
state.last_pid_temp = 0;
state.last_pid_temp_frac = 0;
}
// Apply PID output values
float pid_process(void)
{
// #ifdef MAX31865_RTD_SENSOR
// max31865_readtemp(spi_get(), &set, &status);
// #else
// max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
// #endif
float ssr_output = 0;
if(runtime_status()->pid_enabled)
{
// Get ssr output for next time
int16_t power_percent = pid_update();
if(flash_getsettings()->val.plant_type == PLANT_COOLER)
power_percent *= -1;
//power-percent is 0-1000?
ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000;
// put ssr output on display
ssd1306_drawstring(" ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise
char tempstr[8];
snprintf(tempstr, 8, "%4.1f%%", ssr_output/10.0);
ssd1306_drawstring(tempstr, 0, 85);
}
else
{
ssr_output = 0.0;
}
return ssr_output; //ssr_output;
}
// Calculate new PID values
int16_t pid_update(void)
{
therm_status_t* status = runtime_status();
therm_settings_t* set = flash_getsettings();
// Convert temperature to fixed point number with 1/10th resolution
float temp = status->temp;
// Calculate instantaneous error
// EMZ FIXME: was regulating to 1 degree below the setpoint! +1 accomadates for this
int16_t error = (status->setpoint+1) - temp;
// 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;
// Discard I if we've achieved the setpoint (TODO: add setting disable/enable)
if(error <= 0)
state.i_state = 0;
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;
}
|