Merge pull request #1710 from PavelSindler/preheat_error_MK2
Preheat error improvement for mk2
This commit is contained in:
commit
9575948875
|
|
@ -141,13 +141,11 @@
|
||||||
// Comment the following line to disable PID and enable bang-bang.
|
// Comment the following line to disable PID and enable bang-bang.
|
||||||
#define PIDTEMP
|
#define PIDTEMP
|
||||||
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
|
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
|
||||||
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
|
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active; 255=full current
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
//#define PID_DEBUG // Sends debug data to the serial port.
|
//#define PID_DEBUG // Sends debug data to the serial port.
|
||||||
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
||||||
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
||||||
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
|
|
||||||
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
|
|
||||||
#define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term
|
#define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term
|
||||||
#define K1 0.95 //smoothing factor within the PID
|
#define K1 0.95 //smoothing factor within the PID
|
||||||
#define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
|
#define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,6 @@
|
||||||
/* -*- c++ -*- */
|
/* -*- c++ -*- */
|
||||||
|
/**
|
||||||
/*
|
* @file
|
||||||
Reprap firmware based on Sprinter and grbl.
|
|
||||||
Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -6385,6 +6370,7 @@ void Stop()
|
||||||
disable_heater();
|
disable_heater();
|
||||||
if(Stopped == false) {
|
if(Stopped == false) {
|
||||||
Stopped = true;
|
Stopped = true;
|
||||||
|
lcd_print_stop();
|
||||||
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
||||||
SERIAL_ERROR_START;
|
SERIAL_ERROR_START;
|
||||||
SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
|
SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
|
||||||
|
|
|
||||||
|
|
@ -91,15 +91,15 @@ static volatile bool temp_meas_ready = false;
|
||||||
|
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
//static cannot be external:
|
//static cannot be external:
|
||||||
static float temp_iState[EXTRUDERS] = { 0 };
|
static float iState_sum[EXTRUDERS] = { 0 };
|
||||||
static float temp_dState[EXTRUDERS] = { 0 };
|
static float dState_last[EXTRUDERS] = { 0 };
|
||||||
static float pTerm[EXTRUDERS];
|
static float pTerm[EXTRUDERS];
|
||||||
static float iTerm[EXTRUDERS];
|
static float iTerm[EXTRUDERS];
|
||||||
static float dTerm[EXTRUDERS];
|
static float dTerm[EXTRUDERS];
|
||||||
//int output;
|
//int output;
|
||||||
static float pid_error[EXTRUDERS];
|
static float pid_error[EXTRUDERS];
|
||||||
static float temp_iState_min[EXTRUDERS];
|
static float iState_sum_min[EXTRUDERS];
|
||||||
static float temp_iState_max[EXTRUDERS];
|
static float iState_sum_max[EXTRUDERS];
|
||||||
// static float pid_input[EXTRUDERS];
|
// static float pid_input[EXTRUDERS];
|
||||||
// static float pid_output[EXTRUDERS];
|
// static float pid_output[EXTRUDERS];
|
||||||
static bool pid_reset[EXTRUDERS];
|
static bool pid_reset[EXTRUDERS];
|
||||||
|
|
@ -396,7 +396,7 @@ void updatePID()
|
||||||
{
|
{
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
for(int e = 0; e < EXTRUDERS; e++) {
|
for(int e = 0; e < EXTRUDERS; e++) {
|
||||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
|
iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIDTEMPBED
|
#ifdef PIDTEMPBED
|
||||||
|
|
@ -482,6 +482,12 @@ void checkExtruderAutoFans()
|
||||||
|
|
||||||
#endif // any extruder auto fan pins set
|
#endif // any extruder auto fan pins set
|
||||||
|
|
||||||
|
// ready for eventually parameters adjusting
|
||||||
|
void resetPID(uint8_t) // only for compiler-warning elimination (if function do nothing)
|
||||||
|
//void resetPID(uint8_t extruder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void manage_heater()
|
void manage_heater()
|
||||||
{
|
{
|
||||||
float pid_input;
|
float pid_input;
|
||||||
|
|
@ -489,6 +495,7 @@ void manage_heater()
|
||||||
|
|
||||||
if(temp_meas_ready != true) //better readability
|
if(temp_meas_ready != true) //better readability
|
||||||
return;
|
return;
|
||||||
|
// more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms)
|
||||||
|
|
||||||
updateTemperaturesFromRawValues();
|
updateTemperaturesFromRawValues();
|
||||||
|
|
||||||
|
|
@ -507,38 +514,42 @@ void manage_heater()
|
||||||
pid_input = current_temperature[e];
|
pid_input = current_temperature[e];
|
||||||
|
|
||||||
#ifndef PID_OPENLOOP
|
#ifndef PID_OPENLOOP
|
||||||
pid_error[e] = target_temperature[e] - pid_input;
|
if(target_temperature[e] == 0) {
|
||||||
if(pid_error[e] > PID_FUNCTIONAL_RANGE) {
|
|
||||||
pid_output = BANG_MAX;
|
|
||||||
pid_reset[e] = true;
|
|
||||||
}
|
|
||||||
else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
|
|
||||||
pid_output = 0;
|
pid_output = 0;
|
||||||
pid_reset[e] = true;
|
pid_reset[e] = true;
|
||||||
}
|
} else {
|
||||||
else {
|
pid_error[e] = target_temperature[e] - pid_input;
|
||||||
if(pid_reset[e] == true) {
|
if(pid_reset[e]) {
|
||||||
temp_iState[e] = 0.0;
|
iState_sum[e] = 0.0;
|
||||||
|
dTerm[e] = 0.0; // 'dState_last[e]' initial setting is not necessary (see end of if-statement)
|
||||||
pid_reset[e] = false;
|
pid_reset[e] = false;
|
||||||
}
|
}
|
||||||
|
#ifndef PonM
|
||||||
pTerm[e] = Kp * pid_error[e];
|
pTerm[e] = Kp * pid_error[e];
|
||||||
temp_iState[e] += pid_error[e];
|
iState_sum[e] += pid_error[e];
|
||||||
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
|
iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]);
|
||||||
iTerm[e] = Ki * temp_iState[e];
|
iTerm[e] = Ki * iState_sum[e];
|
||||||
|
// K1 defined in Configuration.h in the PID settings
|
||||||
//K1 defined in Configuration.h in the PID settings
|
|
||||||
#define K2 (1.0-K1)
|
#define K2 (1.0-K1)
|
||||||
dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
|
dTerm[e] = (Kd * (pid_input - dState_last[e]))*K2 + (K1 * dTerm[e]); // e.g. digital filtration of derivative term changes
|
||||||
pid_output = pTerm[e] + iTerm[e] - dTerm[e];
|
pid_output = pTerm[e] + iTerm[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||||
if (pid_output > PID_MAX) {
|
if (pid_output > PID_MAX) {
|
||||||
if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
if (pid_error[e] > 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||||
pid_output=PID_MAX;
|
pid_output=PID_MAX;
|
||||||
} else if (pid_output < 0){
|
} else if (pid_output < 0) {
|
||||||
if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||||
pid_output=0;
|
pid_output=0;
|
||||||
}
|
}
|
||||||
|
#else // PonM ("Proportional on Measurement" method)
|
||||||
|
iState_sum[e] += Ki * pid_error[e];
|
||||||
|
iState_sum[e] -= Kp * (pid_input - dState_last[e]);
|
||||||
|
iState_sum[e] = constrain(iState_sum[e], 0, PID_INTEGRAL_DRIVE_MAX);
|
||||||
|
dTerm[e] = Kd * (pid_input - dState_last[e]);
|
||||||
|
pid_output = iState_sum[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||||
|
pid_output = constrain(pid_output, 0, PID_MAX);
|
||||||
|
#endif // PonM
|
||||||
}
|
}
|
||||||
temp_dState[e] = pid_input;
|
dState_last[e] = pid_input;
|
||||||
#else
|
#else
|
||||||
pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
||||||
#endif //PID_OPENLOOP
|
#endif //PID_OPENLOOP
|
||||||
|
|
@ -555,7 +566,7 @@ void manage_heater()
|
||||||
SERIAL_ECHO(" iTerm ");
|
SERIAL_ECHO(" iTerm ");
|
||||||
SERIAL_ECHO(iTerm[e]);
|
SERIAL_ECHO(iTerm[e]);
|
||||||
SERIAL_ECHO(" dTerm ");
|
SERIAL_ECHO(" dTerm ");
|
||||||
SERIAL_ECHOLN(dTerm[e]);
|
SERIAL_ECHOLN(-dTerm[e]);
|
||||||
#endif //PID_DEBUG
|
#endif //PID_DEBUG
|
||||||
#else /* PID off */
|
#else /* PID off */
|
||||||
pid_output = 0;
|
pid_output = 0;
|
||||||
|
|
@ -565,11 +576,12 @@ void manage_heater()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check if temperature is within the correct range
|
// Check if temperature is within the correct range
|
||||||
if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
|
if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0))
|
||||||
{
|
{
|
||||||
soft_pwm[e] = (int)pid_output >> 1;
|
soft_pwm[e] = (int)pid_output >> 1;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
soft_pwm[e] = 0;
|
soft_pwm[e] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -693,6 +705,8 @@ void manage_heater()
|
||||||
WRITE(HEATER_BED_PIN,LOW);
|
WRITE(HEATER_BED_PIN,LOW);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if(target_temperature_bed==0)
|
||||||
|
soft_pwm_bed = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//code for controlling the extruder rate based on the width sensor
|
//code for controlling the extruder rate based on the width sensor
|
||||||
|
|
@ -891,8 +905,8 @@ void tp_init()
|
||||||
// populate with the first value
|
// populate with the first value
|
||||||
maxttemp[e] = maxttemp[0];
|
maxttemp[e] = maxttemp[0];
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
temp_iState_min[e] = 0.0;
|
iState_sum_min[e] = 0.0;
|
||||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
|
iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
|
||||||
#endif //PIDTEMP
|
#endif //PIDTEMP
|
||||||
#ifdef PIDTEMPBED
|
#ifdef PIDTEMPBED
|
||||||
temp_iState_min_bed = 0.0;
|
temp_iState_min_bed = 0.0;
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,8 @@ extern float current_temperature_bed;
|
||||||
extern volatile int babystepsTodo[3];
|
extern volatile int babystepsTodo[3];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void resetPID(uint8_t extruder);
|
||||||
|
|
||||||
inline void babystepsTodoZadd(int n)
|
inline void babystepsTodoZadd(int n)
|
||||||
{
|
{
|
||||||
if (n != 0) {
|
if (n != 0) {
|
||||||
|
|
@ -126,8 +128,22 @@ FORCE_INLINE float degTargetBed() {
|
||||||
|
|
||||||
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
|
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
|
||||||
target_temperature[extruder] = celsius;
|
target_temperature[extruder] = celsius;
|
||||||
|
resetPID(extruder);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder)
|
||||||
|
{
|
||||||
|
if (extruder<EXTRUDERS) {
|
||||||
|
target_temperature[extruder] = celsius;
|
||||||
|
resetPID(extruder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void setAllTargetHotends(const float &celsius)
|
||||||
|
{
|
||||||
|
for(int i=0;i<EXTRUDERS;i++) setTargetHotend(celsius,i);
|
||||||
|
}
|
||||||
|
|
||||||
FORCE_INLINE void setTargetBed(const float &celsius) {
|
FORCE_INLINE void setTargetBed(const float &celsius) {
|
||||||
target_temperature_bed = celsius;
|
target_temperature_bed = celsius;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4872,6 +4872,41 @@ static void lcd_sd_updir()
|
||||||
currentMenuViewOffset = 0;
|
currentMenuViewOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcd_print_stop() {
|
||||||
|
cancel_heatup = true;
|
||||||
|
#ifdef MESH_BED_LEVELING
|
||||||
|
mbl.active = false;
|
||||||
|
#endif
|
||||||
|
// Stop the stoppers, update the position from the stoppers.
|
||||||
|
if (mesh_bed_leveling_flag == false && homing_flag == false) {
|
||||||
|
planner_abort_hard();
|
||||||
|
// Because the planner_abort_hard() initialized current_position[Z] from the stepper,
|
||||||
|
// Z baystep is no more applied. Reset it.
|
||||||
|
babystep_reset();
|
||||||
|
}
|
||||||
|
// Clean the input command queue.
|
||||||
|
cmdqueue_reset();
|
||||||
|
lcd_setstatuspgm(MSG_PRINT_ABORTED);
|
||||||
|
lcd_update(2);
|
||||||
|
card.sdprinting = false;
|
||||||
|
card.closefile();
|
||||||
|
|
||||||
|
stoptime = millis();
|
||||||
|
unsigned long t = (stoptime - starttime - pause_time) / 1000; //time in s
|
||||||
|
pause_time = 0;
|
||||||
|
save_statistics(total_filament_used, t);
|
||||||
|
lcd_return_to_status();
|
||||||
|
lcd_ignore_click(true);
|
||||||
|
lcd_commands_type = LCD_COMMAND_STOP_PRINT;
|
||||||
|
if (farm_mode) prusa_statistics(7);
|
||||||
|
// Turn off the print fan
|
||||||
|
SET_OUTPUT(FAN_PIN);
|
||||||
|
WRITE(FAN_PIN, 0);
|
||||||
|
fanSpeed=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void lcd_sdcard_stop()
|
void lcd_sdcard_stop()
|
||||||
{
|
{
|
||||||
|
|
@ -4899,37 +4934,7 @@ void lcd_sdcard_stop()
|
||||||
}
|
}
|
||||||
if ((int32_t)encoderPosition == 2)
|
if ((int32_t)encoderPosition == 2)
|
||||||
{
|
{
|
||||||
cancel_heatup = true;
|
lcd_print_stop();
|
||||||
#ifdef MESH_BED_LEVELING
|
|
||||||
mbl.active = false;
|
|
||||||
#endif
|
|
||||||
// Stop the stoppers, update the position from the stoppers.
|
|
||||||
if (mesh_bed_leveling_flag == false && homing_flag == false) {
|
|
||||||
planner_abort_hard();
|
|
||||||
// Because the planner_abort_hard() initialized current_position[Z] from the stepper,
|
|
||||||
// Z baystep is no more applied. Reset it.
|
|
||||||
babystep_reset();
|
|
||||||
}
|
|
||||||
// Clean the input command queue.
|
|
||||||
cmdqueue_reset();
|
|
||||||
lcd_setstatuspgm(MSG_PRINT_ABORTED);
|
|
||||||
lcd_update(2);
|
|
||||||
card.sdprinting = false;
|
|
||||||
card.closefile();
|
|
||||||
|
|
||||||
stoptime = millis();
|
|
||||||
unsigned long t = (stoptime - starttime - pause_time) / 1000; //time in s
|
|
||||||
pause_time = 0;
|
|
||||||
save_statistics(total_filament_used, t);
|
|
||||||
|
|
||||||
lcd_return_to_status();
|
|
||||||
lcd_ignore_click(true);
|
|
||||||
lcd_commands_type = LCD_COMMAND_STOP_PRINT;
|
|
||||||
if (farm_mode) prusa_statistics(7);
|
|
||||||
// Turn off the print fan
|
|
||||||
SET_OUTPUT(FAN_PIN);
|
|
||||||
WRITE(FAN_PIN, 0);
|
|
||||||
fanSpeed=0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
unsigned char lcd_choose_color();
|
unsigned char lcd_choose_color();
|
||||||
void lcd_mylang();
|
void lcd_mylang();
|
||||||
bool lcd_detected(void);
|
bool lcd_detected(void);
|
||||||
|
void lcd_print_stop();
|
||||||
|
|
||||||
|
|
||||||
void lcd_menu_statistics();
|
void lcd_menu_statistics();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue