Added PID autotune. (experimental)
M303 Starts autotune. Wait till the Kp Ki and Kd constants are printed. Put these values in Configuration.h
This commit is contained in:
		| @@ -109,6 +109,7 @@ | ||||
| // M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).   | ||||
| // M502 - reverts to the default "factory settings".  You still need to store them in EEPROM afterwards if you want to. | ||||
| // M503 - print the current settings (from memory not from eeprom) | ||||
| // M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C) | ||||
|  | ||||
| //Stepper Movement Variables | ||||
|  | ||||
| @@ -1197,6 +1198,13 @@ void process_commands() | ||||
|       allow_cold_extrudes(true); | ||||
|     } | ||||
|     break; | ||||
|     case 303: // M303 PID autotune | ||||
|     { | ||||
|       float temp = 150.0; | ||||
|       if (code_seen('S')) temp=code_value(); | ||||
|       PID_autotune(temp); | ||||
|     } | ||||
|     break; | ||||
|     case 400: // finish all moves | ||||
|     { | ||||
|       st_synchronize(); | ||||
|   | ||||
| @@ -734,7 +734,7 @@ | ||||
|     #define encrot2 3 | ||||
|     #define encrot3 1 | ||||
|  | ||||
|      | ||||
|     #define SDCARDDETECT -1 | ||||
|     //bits in the shift register that carry the buttons for: | ||||
|     // left up center down right red | ||||
|     #define BL_LE 7 | ||||
|   | ||||
| @@ -62,7 +62,7 @@ int current_raw_bed = 0; | ||||
| //=========================================================================== | ||||
| //=============================private variables============================ | ||||
| //=========================================================================== | ||||
| static bool temp_meas_ready = false; | ||||
| static volatile bool temp_meas_ready = false; | ||||
|  | ||||
| static unsigned long  previous_millis_bed_heater; | ||||
| //static unsigned long previous_millis_heater; | ||||
| @@ -133,6 +133,93 @@ static unsigned long  previous_millis_bed_heater; | ||||
| //=============================   functions      ============================ | ||||
| //=========================================================================== | ||||
|  | ||||
| void PID_autotune(float temp) | ||||
| { | ||||
|   float input; | ||||
|   int cycles=0; | ||||
|   bool heating = true; | ||||
|   soft_pwm[0] = 255>>1; | ||||
|  | ||||
|   unsigned long temp_millis = millis(); | ||||
|   unsigned long t1=temp_millis; | ||||
|   unsigned long t2=temp_millis; | ||||
|   long t_high; | ||||
|   long t_low; | ||||
|  | ||||
|   long bias=127; | ||||
|   long d = 127; | ||||
|   float Ku, Tu; | ||||
|   float Kp, Ki, Kd; | ||||
|   float max, min; | ||||
|    | ||||
|   SERIAL_ECHOLN("PID Autotune start"); | ||||
|  | ||||
|   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 ,235); | ||||
|             if(bias > 127) d = 254 - 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); | ||||
|               Kp = 0.6*Ku; | ||||
|               Ki = 2*Kp/Tu; | ||||
|               Kd = Kp*Tu/8; | ||||
|               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; | ||||
|         } | ||||
|       }  | ||||
|     } | ||||
|     if(input > (temp + 20)) { | ||||
|       SERIAL_PROTOCOLLNPGM("PID Autotune failed !!!, Temperature to high"); | ||||
|       return; | ||||
|     } | ||||
|     if(millis() - temp_millis > 2000) { | ||||
|       temp_millis = millis(); | ||||
|       SERIAL_PROTOCOLPGM("ok T:"); | ||||
|       SERIAL_PROTOCOL(degHotend(0));    | ||||
|       SERIAL_PROTOCOLPGM(" @:"); | ||||
|       SERIAL_PROTOCOLLN(getHeaterPower(0));        | ||||
|     } | ||||
|     LCD_STATUS; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void updatePID() | ||||
| { | ||||
| #ifdef PIDTEMP | ||||
|   | ||||
| @@ -158,5 +158,8 @@ FORCE_INLINE void autotempShutdown(){ | ||||
|  } | ||||
|  #endif | ||||
| } | ||||
|  | ||||
| void PID_autotune(float temp); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -315,19 +315,18 @@ void MainMenu::showStatus() | ||||
|   static int olddegHotEnd0=-1; | ||||
|   static int oldtargetHotEnd0=-1; | ||||
|   //force_lcd_update=true; | ||||
|   if(force_lcd_update||feedmultiplychanged)  //initial display of content | ||||
|   if(force_lcd_update)  //initial display of content | ||||
|   { | ||||
|     feedmultiplychanged=false; | ||||
|     encoderpos=feedmultiply; | ||||
|     clear(); | ||||
|     lcd.setCursor(0,0);lcdprintPGM("\002123/567\001 "); | ||||
|     lcd.setCursor(0,0);lcdprintPGM("\002---/---\001 "); | ||||
|     #if defined BED_USES_THERMISTOR || defined BED_USES_AD595  | ||||
|       lcd.setCursor(10,0);lcdprintPGM("B123/567\001 "); | ||||
|       lcd.setCursor(10,0);lcdprintPGM("B---/---\001 "); | ||||
|     #endif | ||||
|   } | ||||
|      | ||||
|   int tHotEnd0=intround(degHotend0()); | ||||
|   if((abs(tHotEnd0-olddegHotEnd0)>1)||force_lcd_update) //>1 because otherwise the lcd is refreshed to often. | ||||
|   if((tHotEnd0!=olddegHotEnd0)||force_lcd_update) | ||||
|   { | ||||
|     lcd.setCursor(1,0); | ||||
|     lcd.print(ftostr3(tHotEnd0)); | ||||
| @@ -379,8 +378,15 @@ void MainMenu::showStatus() | ||||
|     lcdprintPGM("Z:");lcd.print(ftostr52(current_position[2])); | ||||
|     oldzpos=currentz; | ||||
|   } | ||||
|    | ||||
|   static int oldfeedmultiply=0; | ||||
|   int curfeedmultiply=feedmultiply; | ||||
|    | ||||
|   if(feedmultiplychanged == true) { | ||||
|     feedmultiplychanged == false; | ||||
|     encoderpos = curfeedmultiply; | ||||
|   } | ||||
|    | ||||
|   if(encoderpos!=curfeedmultiply||force_lcd_update) | ||||
|   { | ||||
|    curfeedmultiply=encoderpos; | ||||
| @@ -391,12 +397,14 @@ void MainMenu::showStatus() | ||||
|    feedmultiply=curfeedmultiply; | ||||
|    encoderpos=curfeedmultiply; | ||||
|   } | ||||
|    | ||||
|   if((curfeedmultiply!=oldfeedmultiply)||force_lcd_update) | ||||
|   { | ||||
|    oldfeedmultiply=curfeedmultiply; | ||||
|    lcd.setCursor(0,2); | ||||
|    lcd.print(itostr3(curfeedmultiply));lcdprintPGM("% "); | ||||
|   } | ||||
|    | ||||
|   if(messagetext[0]!='\0') | ||||
|   { | ||||
|     lcd.setCursor(0,LCD_HEIGHT-1); | ||||
| @@ -404,7 +412,6 @@ void MainMenu::showStatus() | ||||
|     uint8_t n=strlen(messagetext); | ||||
|     for(int8_t i=0;i<LCD_WIDTH-n;i++) | ||||
|       lcd.print(" "); | ||||
|      | ||||
|     messagetext[0]='\0'; | ||||
|   } | ||||
|    | ||||
|   | ||||
		Reference in New Issue
	
	Block a user