Version 1.3.17T
- M303 - PID relay autotune possible - G4 Wait until last move is done
This commit is contained in:
parent
5a60fcd6f5
commit
d2ccafcb77
4 changed files with 222 additions and 2 deletions
|
|
@ -287,6 +287,10 @@ const int dropsegments=5; //everything with less than this number of steps will
|
||||||
//Command M601 / Command M602 Reset the MIN/MAX Value
|
//Command M601 / Command M602 Reset the MIN/MAX Value
|
||||||
//#define DEBUG_HEATER_TEMP
|
//#define DEBUG_HEATER_TEMP
|
||||||
|
|
||||||
|
// M303 - PID relay autotune S<temperature> sets the target temperature.
|
||||||
|
// (default target temperature = 150C)
|
||||||
|
#define PID_AUTOTUNE
|
||||||
|
|
||||||
//PID Controler Settings
|
//PID Controler Settings
|
||||||
#define PID_INTEGRAL_DRIVE_MAX 80 // too big, and heater will lag after changing temperature, too small and it might not compensate enough for long-term errors
|
#define PID_INTEGRAL_DRIVE_MAX 80 // too big, and heater will lag after changing temperature, too small and it might not compensate enough for long-term errors
|
||||||
#define PID_PGAIN 2560 //256 is 1.0 // value of X means that error of 1 degree is changing PWM duty by X, probably no need to go over 25
|
#define PID_PGAIN 2560 //256 is 1.0 // value of X means that error of 1 degree is changing PWM duty by X, probably no need to go over 25
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,10 @@
|
||||||
Version 1.3.16T
|
Version 1.3.16T
|
||||||
- Extra Max Feedrate for Retract (MAX_RETRACT_FEEDRATE)
|
- Extra Max Feedrate for Retract (MAX_RETRACT_FEEDRATE)
|
||||||
|
|
||||||
|
Version 1.3.17T
|
||||||
|
- M303 - PID relay autotune possible
|
||||||
|
- G4 Wait until last move is done
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -207,6 +211,8 @@ void __cxa_pure_virtual(){};
|
||||||
// M220 - set speed factor override percentage S:factor in percent
|
// M220 - set speed factor override percentage S:factor in percent
|
||||||
// M221 - set extruder multiply factor S100 --> original Extrude Speed
|
// M221 - set extruder multiply factor S100 --> original Extrude Speed
|
||||||
|
|
||||||
|
// M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
|
||||||
|
|
||||||
// M500 - stores paramters in EEPROM
|
// M500 - stores paramters in EEPROM
|
||||||
// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
|
// 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.
|
// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
|
||||||
|
|
@ -218,7 +224,7 @@ void __cxa_pure_virtual(){};
|
||||||
// M603 - Show Free Ram
|
// M603 - Show Free Ram
|
||||||
|
|
||||||
|
|
||||||
#define _VERSION_TEXT "1.3.16T / 24.04.2012"
|
#define _VERSION_TEXT "1.3.17T / 04.05.2012"
|
||||||
|
|
||||||
//Stepper Movement Variables
|
//Stepper Movement Variables
|
||||||
char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
|
char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
|
||||||
|
|
@ -1121,6 +1127,7 @@ FORCE_INLINE void process_commands()
|
||||||
if(code_seen('P')) codenum = code_value(); // milliseconds to wait
|
if(code_seen('P')) codenum = code_value(); // milliseconds to wait
|
||||||
if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait
|
if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait
|
||||||
codenum += millis(); // keep track of when we started waiting
|
codenum += millis(); // keep track of when we started waiting
|
||||||
|
st_synchronize(); // wait for all movements to finish
|
||||||
while(millis() < codenum ){
|
while(millis() < codenum ){
|
||||||
manage_heater();
|
manage_heater();
|
||||||
}
|
}
|
||||||
|
|
@ -1795,7 +1802,15 @@ FORCE_INLINE void process_commands()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef PID_AUTOTUNE
|
||||||
|
case 303: // M303 PID autotune
|
||||||
|
{
|
||||||
|
float help_temp = 150.0;
|
||||||
|
if (code_seen('S')) help_temp=code_value();
|
||||||
|
PID_autotune(help_temp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef USE_EEPROM_SETTINGS
|
#ifdef USE_EEPROM_SETTINGS
|
||||||
case 500: // Store settings in EEPROM
|
case 500: // Store settings in EEPROM
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,203 @@ ISR(TIMER2_OVF_vect)
|
||||||
#endif
|
#endif
|
||||||
//--------------------END SOFT PWM---------------------------
|
//--------------------END SOFT PWM---------------------------
|
||||||
|
|
||||||
|
//-------------------- START PID AUTOTUNE ---------------------------
|
||||||
|
// Based on PID relay test
|
||||||
|
// Thanks to Erik van der Zalm for this idea to use it for Marlin
|
||||||
|
// Some information see:
|
||||||
|
// http://brettbeauregard.com/blog/2012/01/arduino-pid-autotune-library/
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
#ifdef PID_AUTOTUNE
|
||||||
|
void PID_autotune(int PIDAT_test_temp)
|
||||||
|
{
|
||||||
|
float PIDAT_input = 0;
|
||||||
|
int PIDAT_input_help = 0;
|
||||||
|
unsigned char PIDAT_count_input = 0;
|
||||||
|
|
||||||
|
float PIDAT_max, PIDAT_min;
|
||||||
|
|
||||||
|
unsigned char PIDAT_PWM_val = 255;
|
||||||
|
|
||||||
|
unsigned char PIDAT_cycles=0;
|
||||||
|
bool PIDAT_heating = true;
|
||||||
|
|
||||||
|
unsigned long PIDAT_temp_millis = millis();
|
||||||
|
unsigned long PIDAT_t1=PIDAT_temp_millis;
|
||||||
|
unsigned long PIDAT_t2=PIDAT_temp_millis;
|
||||||
|
unsigned long PIDAT_T_check_AI_val = PIDAT_temp_millis;
|
||||||
|
|
||||||
|
unsigned char PIDAT_cycle_cnt = 0;
|
||||||
|
|
||||||
|
long PIDAT_t_high;
|
||||||
|
long PIDAT_t_low;
|
||||||
|
|
||||||
|
long PIDAT_bias= 127;
|
||||||
|
long PIDAT_d = 127;
|
||||||
|
|
||||||
|
float PIDAT_Ku, PIDAT_Tu;
|
||||||
|
float PIDAT_Kp, PIDAT_Ki, PIDAT_Kd;
|
||||||
|
|
||||||
|
#define PIDAT_TIME_FACTOR ((HEATER_CHECK_INTERVAL*256.0) / 1000.0)
|
||||||
|
|
||||||
|
showString(PSTR("PID Autotune start\r\n"));
|
||||||
|
|
||||||
|
target_temp = PIDAT_test_temp;
|
||||||
|
|
||||||
|
#ifdef BED_USES_THERMISTOR
|
||||||
|
WRITE(HEATER_1_PIN,LOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
|
||||||
|
if((millis() - PIDAT_T_check_AI_val) > 100 )
|
||||||
|
{
|
||||||
|
PIDAT_T_check_AI_val = millis();
|
||||||
|
PIDAT_cycle_cnt++;
|
||||||
|
|
||||||
|
#ifdef HEATER_USES_THERMISTOR
|
||||||
|
current_raw = analogRead(TEMP_0_PIN);
|
||||||
|
current_raw = 1023 - current_raw;
|
||||||
|
PIDAT_input_help += analog2temp(current_raw);
|
||||||
|
PIDAT_count_input++;
|
||||||
|
#elif defined HEATER_USES_AD595
|
||||||
|
current_raw = analogRead(TEMP_0_PIN);
|
||||||
|
PIDAT_input_help += analog2temp(current_raw);
|
||||||
|
PIDAT_count_input++;
|
||||||
|
#elif defined HEATER_USES_MAX6675
|
||||||
|
current_raw = read_max6675();
|
||||||
|
PIDAT_input_help += analog2temp(current_raw);
|
||||||
|
PIDAT_count_input++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if(PIDAT_cycle_cnt >= 10 )
|
||||||
|
{
|
||||||
|
|
||||||
|
PIDAT_cycle_cnt = 0;
|
||||||
|
|
||||||
|
PIDAT_input = (float)PIDAT_input_help / (float)PIDAT_count_input;
|
||||||
|
PIDAT_input_help = 0;
|
||||||
|
PIDAT_count_input = 0;
|
||||||
|
|
||||||
|
PIDAT_max=max(PIDAT_max,PIDAT_input);
|
||||||
|
PIDAT_min=min(PIDAT_min,PIDAT_input);
|
||||||
|
|
||||||
|
if(PIDAT_heating == true && PIDAT_input > PIDAT_test_temp)
|
||||||
|
{
|
||||||
|
if(millis() - PIDAT_t2 > 5000)
|
||||||
|
{
|
||||||
|
PIDAT_heating = false;
|
||||||
|
PIDAT_PWM_val = (PIDAT_bias - PIDAT_d);
|
||||||
|
PIDAT_t1 = millis();
|
||||||
|
PIDAT_t_high = PIDAT_t1 - PIDAT_t2;
|
||||||
|
PIDAT_max = PIDAT_test_temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(PIDAT_heating == false && PIDAT_input < PIDAT_test_temp)
|
||||||
|
{
|
||||||
|
if(millis() - PIDAT_t1 > 5000)
|
||||||
|
{
|
||||||
|
PIDAT_heating = true;
|
||||||
|
PIDAT_t2 = millis();
|
||||||
|
PIDAT_t_low = PIDAT_t2 - PIDAT_t1;
|
||||||
|
|
||||||
|
if(PIDAT_cycles > 0)
|
||||||
|
{
|
||||||
|
PIDAT_bias += (PIDAT_d*(PIDAT_t_high - PIDAT_t_low))/(PIDAT_t_low + PIDAT_t_high);
|
||||||
|
PIDAT_bias = constrain(PIDAT_bias, 20 ,235);
|
||||||
|
if(PIDAT_bias > 127) PIDAT_d = 254 - PIDAT_bias;
|
||||||
|
else PIDAT_d = PIDAT_bias;
|
||||||
|
|
||||||
|
showString(PSTR(" bias: ")); Serial.print(PIDAT_bias);
|
||||||
|
showString(PSTR(" d: ")); Serial.print(PIDAT_d);
|
||||||
|
showString(PSTR(" min: ")); Serial.print(PIDAT_min);
|
||||||
|
showString(PSTR(" max: ")); Serial.println(PIDAT_max);
|
||||||
|
|
||||||
|
if(PIDAT_cycles > 2)
|
||||||
|
{
|
||||||
|
PIDAT_Ku = (4.0*PIDAT_d)/(3.14159*(PIDAT_max-PIDAT_min));
|
||||||
|
PIDAT_Tu = ((float)(PIDAT_t_low + PIDAT_t_high)/1000.0);
|
||||||
|
|
||||||
|
showString(PSTR(" Ku: ")); Serial.print(PIDAT_Ku);
|
||||||
|
showString(PSTR(" Tu: ")); Serial.println(PIDAT_Tu);
|
||||||
|
|
||||||
|
PIDAT_Kp = 0.60*PIDAT_Ku;
|
||||||
|
PIDAT_Ki = 2*PIDAT_Kp/PIDAT_Tu;
|
||||||
|
PIDAT_Kd = PIDAT_Kp*PIDAT_Tu/8;
|
||||||
|
showString(PSTR(" Clasic PID \r\n"));
|
||||||
|
//showString(PSTR(" Kp: ")); Serial.println(PIDAT_Kp);
|
||||||
|
//showString(PSTR(" Ki: ")); Serial.println(PIDAT_Ki);
|
||||||
|
//showString(PSTR(" Kd: ")); Serial.println(PIDAT_Kd);
|
||||||
|
showString(PSTR(" CFG Kp: ")); Serial.println((unsigned int)(PIDAT_Kp*256));
|
||||||
|
showString(PSTR(" CFG Ki: ")); Serial.println((unsigned int)(PIDAT_Ki*PIDAT_TIME_FACTOR));
|
||||||
|
showString(PSTR(" CFG Kd: ")); Serial.println((unsigned int)(PIDAT_Kd*PIDAT_TIME_FACTOR));
|
||||||
|
|
||||||
|
PIDAT_Kp = 0.30*PIDAT_Ku;
|
||||||
|
PIDAT_Ki = PIDAT_Kp/PIDAT_Tu;
|
||||||
|
PIDAT_Kd = PIDAT_Kp*PIDAT_Tu/3;
|
||||||
|
showString(PSTR(" Some overshoot \r\n"));
|
||||||
|
showString(PSTR(" CFG Kp: ")); Serial.println((unsigned int)(PIDAT_Kp*256));
|
||||||
|
showString(PSTR(" CFG Ki: ")); Serial.println((unsigned int)(PIDAT_Ki*PIDAT_TIME_FACTOR));
|
||||||
|
showString(PSTR(" CFG Kd: ")); Serial.println((unsigned int)(PIDAT_Kd*PIDAT_TIME_FACTOR));
|
||||||
|
/*
|
||||||
|
PIDAT_Kp = 0.20*PIDAT_Ku;
|
||||||
|
PIDAT_Ki = 2*PIDAT_Kp/PIDAT_Tu;
|
||||||
|
PIDAT_Kd = PIDAT_Kp*PIDAT_Tu/3;
|
||||||
|
showString(PSTR(" No overshoot \r\n"));
|
||||||
|
showString(PSTR(" CFG Kp: ")); Serial.println((unsigned int)(PIDAT_Kp*256));
|
||||||
|
showString(PSTR(" CFG Ki: ")); Serial.println((unsigned int)(PIDAT_Ki*PIDAT_TIME_FACTOR));
|
||||||
|
showString(PSTR(" CFG Kd: ")); Serial.println((unsigned int)(PIDAT_Kd*PIDAT_TIME_FACTOR));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PIDAT_PWM_val = (PIDAT_bias + PIDAT_d);
|
||||||
|
PIDAT_cycles++;
|
||||||
|
PIDAT_min = PIDAT_test_temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PID_SOFT_PWM
|
||||||
|
g_heater_pwm_val = PIDAT_PWM_val;
|
||||||
|
#else
|
||||||
|
analogWrite_check(HEATER_0_PIN, PIDAT_PWM_val);
|
||||||
|
#if LED_PIN>-1
|
||||||
|
analogWrite_check(LED_PIN, PIDAT_PWM_val);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if(PIDAT_input > (PIDAT_test_temp + 20))
|
||||||
|
{
|
||||||
|
showString(PSTR("PID Autotune failed! Temperature to high\r\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(millis() - PIDAT_temp_millis > 2000)
|
||||||
|
{
|
||||||
|
PIDAT_temp_millis = millis();
|
||||||
|
showString(PSTR("ok T:"));
|
||||||
|
Serial.print(PIDAT_input);
|
||||||
|
showString(PSTR(" @:"));
|
||||||
|
Serial.println((unsigned char)PIDAT_PWM_val*1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(((millis() - PIDAT_t1) + (millis() - PIDAT_t2)) > (10L*60L*1000L*2L))
|
||||||
|
{
|
||||||
|
showString(PSTR("PID Autotune failed! timeout\r\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(PIDAT_cycles > 5)
|
||||||
|
{
|
||||||
|
showString(PSTR("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h\r\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//---------------- END AUTOTUNE PID ------------------------------
|
||||||
|
|
||||||
void manage_heater()
|
void manage_heater()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -119,4 +119,8 @@ extern unsigned char manage_monitor;
|
||||||
void init_Timer2_softpwm(void);
|
void init_Timer2_softpwm(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PID_AUTOTUNE
|
||||||
|
void PID_autotune(int PIDAT_test_temp);
|
||||||
|
#endif
|
||||||
|
|
||||||
void manage_heater();
|
void manage_heater();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue