Files
        @ c204b66d229e
    
        
              Branch filter: 
        
    Location: therm-ng/src/pid.c - annotation
        
            
            c204b66d229e
            2.8 KiB
            text/plain
        
        
    
    Disable LTO, was preventing successful run
    | 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 a710d1e0fc2a 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"
// PID implementation
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;
}
 |