void PID_autotune(float temp) { float input; int cycles=0; bool heating = true; unsigned long temp_millis = millis(); unsigned long t1=temp_millis; unsigned long t2=temp_millis; long t_high; long t_low; long bias=PID_MAX/2; long d = PID_MAX/2; float Ku, Tu; float Kp, Ki, Kd; float max, min; SERIAL_ECHOLN("PID Autotune start"); disable_heater(); // switch off all heaters. soft_pwm[0] = PID_MAX/2; for(;;) { if(temp_meas_ready == true) { // temp sample ready CRITICAL_SECTION_START; temp_meas_ready = false; CRITICAL_SECTION_END; input = analog2temp(current_raw[0], 0); max=max(max,input); min=min(min,input); if(heating == true && input > temp) { if(millis() - t2 > 5000) { heating=false; soft_pwm[0] = (bias - d) >> 1; t1=millis(); t_high=t1 - t2; max=temp; } } if(heating == false && input < temp) { if(millis() - t1 > 5000) { heating=true; t2=millis(); t_low=t2 - t1; if(cycles > 0) { bias += (d*(t_high - t_low))/(t_low + t_high); bias = constrain(bias, 20 ,PID_MAX-20); if(bias > PID_MAX/2) d = PID_MAX - 1 - bias; else d = bias; SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias); SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d); SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min); SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max); if(cycles > 2) { Ku = (4.0*d)/(3.14159*(max-min)/2.0); Tu = ((float)(t_low + t_high)/1000.0); SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku); SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu); Kp = 0.6*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/8; SERIAL_PROTOCOLLNPGM(" Clasic PID ") SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); /* Kp = 0.33*Ku; Ki = Kp/Tu; Kd = Kp*Tu/3; SERIAL_PROTOCOLLNPGM(" Some overshoot ") SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); Kp = 0.2*Ku; Ki = 2*Kp/Tu; Kd = Kp*Tu/3; SERIAL_PROTOCOLLNPGM(" No overshoot ") SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); */ } } soft_pwm[0] = (bias + d) >> 1; cycles++; min=temp; } }
void PID_autotune(float temp, int extruder, int ncycles) { float input = 0.0; int cycles=0; bool heating = true; unsigned long temp_millis = millis(); unsigned long t1=temp_millis; unsigned long t2=temp_millis; long t_high = 0; long t_low = 0; long bias, d; float Ku, Tu; float Kp, Ki, Kd; float max = 0, min = 10000; if ((extruder >= EXTRUDERS) #if (TEMP_BED_PIN <= -1) ||(extruder < 0) #endif ){ SERIAL_ECHOLN("PID Autotune failed. Bad extruder number."); return; } SERIAL_ECHOLN("PID Autotune start"); disable_heater(); // switch off all heaters. if (extruder<0) { soft_pwm_bed = (MAX_BED_POWER)/2; bias = d = (MAX_BED_POWER)/2; } else { soft_pwm[extruder] = (PID_MAX)/2; bias = d = (PID_MAX)/2; } for(;;) { if(temp_meas_ready == true) { // temp sample ready updateTemperaturesFromRawValues(); input = (extruder<0)?current_temperature_bed:current_temperature[extruder]; max=max(max,input); min=min(min,input); if(heating == true && input > temp) { if(millis() - t2 > 5000) { heating=false; if (extruder<0) soft_pwm_bed = (bias - d) >> 1; else soft_pwm[extruder] = (bias - d) >> 1; t1=millis(); t_high=t1 - t2; max=temp; } }
void PID_autotune(float temp, int extruder, int ncycles) { float input = 0.0; int cycles=0; bool heating = true; unsigned long temp_millis = millis(); unsigned long t1=temp_millis; unsigned long t2=temp_millis; long t_high = 0; long t_low = 0; long bias, d; float Ku, Tu; float Kp, Ki, Kd; float max = 0, min = 10000; if ((extruder > EXTRUDERS) #if (TEMP_BED_PIN <= -1) ||(extruder < 0) #endif ){ SERIAL_ECHOLN("PID Autotune failed. Bad extruder number."); return; } SERIAL_ECHOLN("PID Autotune start"); disable_heater(); // switch off all heaters. if (extruder<0) { soft_pwm_bed = (MAX_BED_POWER)/2; bias = d = (MAX_BED_POWER)/2; } else { soft_pwm[extruder] = (PID_MAX)/2; bias = d = (PID_MAX)/2; } for(;;) { if(temp_meas_ready == true) { // temp sample ready //Reset the watchdog after we know we have a temperature measurement. watchdog_reset(); CRITICAL_SECTION_START; temp_meas_ready = false; CRITICAL_SECTION_END; input = (extruder<0)?analog2tempBed(current_raw_bed):analog2temp(current_raw[extruder], extruder); max=max(max,input); min=min(min,input); if(heating == true && input > temp) { if(millis() - t2 > 5000) { heating=false; if (extruder<0) soft_pwm_bed = (bias - d) >> 1; else soft_pwm[extruder] = (bias - d) >> 1; t1=millis(); t_high=t1 - t2; max=temp; } }