From 0ff4af9b529f65d294f199d0334926a2e8bd8308 Mon Sep 17 00:00:00 2001 From: MRprusa3d Date: Wed, 2 Jan 2019 18:25:41 +0100 Subject: [PATCH 1/9] minTemp safety heaters management during/after minTemp --- Firmware/Marlin_main.cpp | 20 +++----------------- Firmware/temperature.cpp | 4 ++++ 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 32e1d34e1..89b640420 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1,21 +1,6 @@ /* -*- c++ -*- */ - -/* - 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 . +/** + * @file */ /* @@ -6356,6 +6341,7 @@ void Stop() disable_heater(); if(Stopped == false) { Stopped = true; + lcd_print_stop(); Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart SERIAL_ERROR_START; SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED); diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 9e8fdd36d..7655106b6 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -572,6 +572,8 @@ void manage_heater() else { soft_pwm[e] = 0; } + if(target_temperature[e]==0) + soft_pwm[e] = 0; #ifdef WATCH_TEMP_PERIOD if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD) @@ -693,6 +695,8 @@ void manage_heater() WRITE(HEATER_BED_PIN,LOW); } #endif + if(target_temperature_bed==0) + soft_pwm_bed = 0; #endif //code for controlling the extruder rate based on the width sensor From 311960211b8e0f7c4564c413eff0cee900aa8aea Mon Sep 17 00:00:00 2001 From: MRprusa3d Date: Thu, 17 Jan 2019 02:57:08 +0100 Subject: [PATCH 2/9] PID / manage_heater PSD regulator improvement --- Firmware/Configuration.h | 2 ++ Firmware/temperature.cpp | 76 ++++++++++++++++++++++------------------ Firmware/temperature.h | 16 +++++++++ 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index b363912ae..11b82dc03 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -146,8 +146,10 @@ //#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 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 +// :-O :-O :-O #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. +// :-O :-O :-O #define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term #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 diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 7655106b6..718fe4bf8 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -91,15 +91,15 @@ static volatile bool temp_meas_ready = false; #ifdef PIDTEMP //static cannot be external: - static float temp_iState[EXTRUDERS] = { 0 }; - static float temp_dState[EXTRUDERS] = { 0 }; + static float iState_sum[EXTRUDERS] = { 0 }; + static float dState_last[EXTRUDERS] = { 0 }; static float pTerm[EXTRUDERS]; static float iTerm[EXTRUDERS]; static float dTerm[EXTRUDERS]; //int output; static float pid_error[EXTRUDERS]; - static float temp_iState_min[EXTRUDERS]; - static float temp_iState_max[EXTRUDERS]; + static float iState_sum_min[EXTRUDERS]; + static float iState_sum_max[EXTRUDERS]; // static float pid_input[EXTRUDERS]; // static float pid_output[EXTRUDERS]; static bool pid_reset[EXTRUDERS]; @@ -396,7 +396,7 @@ void updatePID() { #ifdef PIDTEMP for(int e = 0; e < EXTRUDERS; e++) { - temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki; + iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; } #endif #ifdef PIDTEMPBED @@ -482,6 +482,10 @@ void checkExtruderAutoFans() #endif // any extruder auto fan pins set +void resetPID(uint8_t extruder) // ready for eventually parameters adjusting +{ +} + void manage_heater() { float pid_input; @@ -489,6 +493,7 @@ void manage_heater() if(temp_meas_ready != true) //better readability return; +// more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms) updateTemperaturesFromRawValues(); @@ -507,38 +512,42 @@ void manage_heater() pid_input = current_temperature[e]; #ifndef PID_OPENLOOP - pid_error[e] = target_temperature[e] - pid_input; - 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) { + if(target_temperature[e] == 0) { pid_output = 0; pid_reset[e] = true; - } - else { - if(pid_reset[e] == true) { - temp_iState[e] = 0.0; + } else { + pid_error[e] = target_temperature[e] - pid_input; + if(pid_reset[e]) { + 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; } - pTerm[e] = Kp * pid_error[e]; - temp_iState[e] += pid_error[e]; - temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); - iTerm[e] = Ki * temp_iState[e]; - - //K1 defined in Configuration.h in the PID settings +#ifndef PonM + pTerm[e] = cs.Kp * pid_error[e]; + iState_sum[e] += pid_error[e]; + iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]); + iTerm[e] = cs.Ki * iState_sum[e]; + // K1 defined in Configuration.h in the PID settings #define K2 (1.0-K1) - dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]); - pid_output = pTerm[e] + iTerm[e] - dTerm[e]; + dTerm[e] = (cs.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]; // 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_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; - } else if (pid_output < 0){ - if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration + } else if (pid_output < 0) { + if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration pid_output=0; } +#else // PonM ("Proportional on Measurement" method) + iState_sum[e] += cs.Ki * pid_error[e]; + iState_sum[e] -= cs.Kp * (pid_input - dState_last[e]); + iState_sum[e] = constrain(iState_sum[e], 0, PID_INTEGRAL_DRIVE_MAX); + dTerm[e] = cs.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 pid_output = constrain(target_temperature[e], 0, PID_MAX); #endif //PID_OPENLOOP @@ -555,7 +564,7 @@ void manage_heater() SERIAL_ECHO(" iTerm "); SERIAL_ECHO(iTerm[e]); SERIAL_ECHO(" dTerm "); - SERIAL_ECHOLN(dTerm[e]); + SERIAL_ECHOLN(-dTerm[e]); #endif //PID_DEBUG #else /* PID off */ pid_output = 0; @@ -565,15 +574,14 @@ void manage_heater() #endif // 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; } - else { + else + { soft_pwm[e] = 0; } - if(target_temperature[e]==0) - soft_pwm[e] = 0; #ifdef WATCH_TEMP_PERIOD if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD) @@ -895,8 +903,8 @@ void tp_init() // populate with the first value maxttemp[e] = maxttemp[0]; #ifdef PIDTEMP - temp_iState_min[e] = 0.0; - temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki; + iState_sum_min[e] = 0.0; + iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; #endif //PIDTEMP #ifdef PIDTEMPBED temp_iState_min_bed = 0.0; diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 5e80a0b39..958a76be0 100644 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -76,6 +76,8 @@ extern float current_temperature_bed; extern volatile int babystepsTodo[3]; #endif +void resetPID(uint8_t extruder); + inline void babystepsTodoZadd(int n) { if (n != 0) { @@ -126,8 +128,22 @@ FORCE_INLINE float degTargetBed() { FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) { target_temperature[extruder] = celsius; + resetPID[extruder]; }; +static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder) +{ + if (extruder Date: Mon, 8 Apr 2019 11:47:26 +0200 Subject: [PATCH 3/9] remove comments --- Firmware/Configuration.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 11b82dc03..b363912ae 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -146,10 +146,8 @@ //#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 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 -// :-O :-O :-O #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. -// :-O :-O :-O #define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term #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 From efdd3bc998091ff31ac5d01f91ea2be0ea7644b6 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Mon, 8 Apr 2019 11:55:40 +0200 Subject: [PATCH 4/9] setTargetHotendSafe change --- Firmware/temperature.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 958a76be0..9a5e8c791 100644 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -133,10 +133,7 @@ FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) { static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder) { - if (extruder Date: Mon, 21 Jan 2019 18:20:40 +0100 Subject: [PATCH 5/9] PID / manage_heater some small corrections --- Firmware/Configuration.h | 4 +--- Firmware/temperature.cpp | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index b363912ae..cdd0f8c2e 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -141,13 +141,11 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP #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 //#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 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 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 diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 718fe4bf8..08677a583 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -484,6 +484,7 @@ void checkExtruderAutoFans() void resetPID(uint8_t extruder) // ready for eventually parameters adjusting { +extruder=extruder; // only for compiler-warning elimination (if function do nothing) } void manage_heater() From 36c70aacce28f2df5970868dab9b4441fd9dee0b Mon Sep 17 00:00:00 2001 From: MRprusa3d Date: Wed, 23 Jan 2019 20:14:40 +0100 Subject: [PATCH 6/9] PID / manage_heater better build-warnings elimination --- Firmware/temperature.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 08677a583..a5a7e7ee4 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -482,9 +482,10 @@ void checkExtruderAutoFans() #endif // any extruder auto fan pins set -void resetPID(uint8_t extruder) // ready for eventually parameters adjusting +// ready for eventually parameters adjusting +void resetPID(uint8_t) // only for compiler-warning elimination (if function do nothing) +//void resetPID(uint8_t extruder) { -extruder=extruder; // only for compiler-warning elimination (if function do nothing) } void manage_heater() From 858a44e915614c6e0695e91d7fb88cab15a5c107 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Mon, 8 Apr 2019 17:57:07 +0200 Subject: [PATCH 7/9] add resetPID function --- Firmware/temperature.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 9a5e8c791..d22269f35 100644 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -128,12 +128,15 @@ FORCE_INLINE float degTargetBed() { FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) { target_temperature[extruder] = celsius; - resetPID[extruder]; + resetPID(extruder); }; static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder) { - if (extruder Date: Mon, 8 Apr 2019 18:24:18 +0200 Subject: [PATCH 8/9] add lcd_print_stop() function --- Firmware/ultralcd.cpp | 67 +++++++++++++++++++++++-------------------- Firmware/ultralcd.h | 1 + 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 7776b79d2..8a86b2c15 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4872,6 +4872,41 @@ static void lcd_sd_updir() 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() { @@ -4899,37 +4934,7 @@ void lcd_sdcard_stop() } if ((int32_t)encoderPosition == 2) { - 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; + lcd_print_stop(); } } diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 511ba6ae1..060848ecb 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -31,6 +31,7 @@ unsigned char lcd_choose_color(); void lcd_mylang(); bool lcd_detected(void); + void lcd_print_stop(); void lcd_menu_statistics(); From 9bfeedcd8e8411732e3c68c21eeddfe432c82f6a Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Mon, 8 Apr 2019 18:31:15 +0200 Subject: [PATCH 9/9] Ki, Kp, Kd configuration store --- Firmware/temperature.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index a5a7e7ee4..7e509b64e 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -396,7 +396,7 @@ void updatePID() { #ifdef PIDTEMP for(int e = 0; e < EXTRUDERS; e++) { - iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; + iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki; } #endif #ifdef PIDTEMPBED @@ -525,13 +525,13 @@ void manage_heater() pid_reset[e] = false; } #ifndef PonM - pTerm[e] = cs.Kp * pid_error[e]; + pTerm[e] = Kp * pid_error[e]; iState_sum[e] += pid_error[e]; iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]); - iTerm[e] = cs.Ki * iState_sum[e]; + iTerm[e] = Ki * iState_sum[e]; // K1 defined in Configuration.h in the PID settings #define K2 (1.0-K1) - dTerm[e] = (cs.Kd * (pid_input - dState_last[e]))*K2 + (K1 * dTerm[e]); // e.g. digital filtration of derivative term changes + 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]; // 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_error[e] > 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration @@ -541,10 +541,10 @@ void manage_heater() pid_output=0; } #else // PonM ("Proportional on Measurement" method) - iState_sum[e] += cs.Ki * pid_error[e]; - iState_sum[e] -= cs.Kp * (pid_input - dState_last[e]); + 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] = cs.Kd * (pid_input - dState_last[e]); + 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 @@ -906,7 +906,7 @@ void tp_init() maxttemp[e] = maxttemp[0]; #ifdef PIDTEMP iState_sum_min[e] = 0.0; - iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; + iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki; #endif //PIDTEMP #ifdef PIDTEMPBED temp_iState_min_bed = 0.0;