Browse Source

Merge pull request #1710 from PavelSindler/preheat_error_MK2

Preheat error improvement for mk2
MRprusa3d 5 years ago
parent
commit
9575948875
6 changed files with 102 additions and 82 deletions
  1. 1 3
      Firmware/Configuration.h
  2. 3 17
      Firmware/Marlin_main.cpp
  3. 45 31
      Firmware/temperature.cpp
  4. 16 0
      Firmware/temperature.h
  5. 36 31
      Firmware/ultralcd.cpp
  6. 1 0
      Firmware/ultralcd.h

+ 1 - 3
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

+ 3 - 17
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 <http://www.gnu.org/licenses/>.
+/**
+ * @file
  */
 
 /*
@@ -6385,6 +6370,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);

+ 45 - 31
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 / Ki;  
   }
 #endif
 #ifdef PIDTEMPBED
@@ -482,6 +482,12 @@ void checkExtruderAutoFans()
 
 #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()
 {
   float pid_input;
@@ -489,6 +495,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 +514,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;
           }
+#ifndef PonM
           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
+          iState_sum[e] += pid_error[e];
+          iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]);
+          iTerm[e] = 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] = (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] += 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 
           pid_output = constrain(target_temperature[e], 0, PID_MAX);
     #endif //PID_OPENLOOP
@@ -555,7 +566,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,11 +576,12 @@ 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;
     }
 
@@ -693,6 +705,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 
@@ -891,8 +905,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 / Ki;
 #endif //PIDTEMP
 #ifdef PIDTEMPBED
     temp_iState_min_bed = 0.0;

+ 16 - 0
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<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) {  
   target_temperature_bed = celsius;
 };

+ 36 - 31
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();
 		}
 	}
 

+ 1 - 0
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();