Browse Source

Merge remote-tracking branch 'upstream/MK3' into MK3-bed_fast_pwm

# Conflicts:
#	Firmware/temperature.cpp
resolved
Robert Pelnar 5 years ago
parent
commit
c4d5b58c37

+ 1 - 3
Firmware/Configuration.h

@@ -126,13 +126,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

+ 1 - 0
Firmware/Marlin_main.cpp

@@ -7640,6 +7640,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);

+ 95 - 65
Firmware/temperature.cpp

@@ -41,6 +41,9 @@
 #include "adc.h"
 #include "ConfigurationStore.h"
 
+#include "Timer.h"
+#include "Configuration_prusa.h"
+
 
 extern "C" {
 extern void timer02_init(void);
@@ -109,15 +112,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];
@@ -158,6 +161,8 @@ static volatile bool temp_meas_ready = false;
   # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
 #endif
 
+static ShortTimer oTimer4minTempHeater,oTimer4minTempBed;
+
 // Init min and max temp with extreme values to prevent false errors during startup
 static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
 static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
@@ -426,7 +431,7 @@ void updatePID()
 {
 #ifdef PIDTEMP
   for(int e = 0; e < EXTRUDERS; e++) { 
-     temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;  
+     iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki;  
   }
 #endif
 #ifdef PIDTEMPBED
@@ -595,6 +600,11 @@ void checkExtruderAutoFans()
 
 #endif // any extruder auto fan pins set
 
+void resetPID(uint8_t extruder)                   // ready for eventually parameters adjusting
+{
+extruder=extruder;                                // only for compiler-warning elimination (if function do nothing)
+}
+
 void manage_heater()
 {
 #ifdef WATCHDOG
@@ -606,9 +616,13 @@ 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();
 
+  check_max_temp();
+  check_min_temp();
+
 #ifdef TEMP_RUNAWAY_BED_HYSTERESIS
   temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
 #endif
@@ -624,38 +638,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] = cs.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] = cs.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] = cs.Ki * iState_sum[e];
+          // K1 defined in Configuration.h in the PID settings
           #define K2 (1.0-K1)
-          dTerm[e] = (cs.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
@@ -672,7 +690,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;
@@ -682,16 +700,12 @@ void manage_heater()
   #endif
 
     // Check if temperature is within the correct range
-#ifdef AMBIENT_THERMISTOR
-    if(((current_temperature_ambient < MINTEMP_MINAMBIENT) || (current_temperature[e] > minttemp[e])) && (current_temperature[e] < maxttemp[e])) 
-#else //AMBIENT_THERMISTOR
-    if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e])) 
-#endif //AMBIENT_THERMISTOR
+    if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0))
     {
       soft_pwm[e] = (int)pid_output >> 1;
     }
     else
-	{
+    {
       soft_pwm[e] = 0;
     }
 
@@ -776,11 +790,7 @@ void manage_heater()
       pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
     #endif //PID_OPENLOOP
 
-#ifdef AMBIENT_THERMISTOR
-	  if(((current_temperature_bed > BED_MINTEMP) || (current_temperature_ambient < MINTEMP_MINAMBIENT)) && (current_temperature_bed < BED_MAXTEMP)) 
-#else //AMBIENT_THERMISTOR
-	  if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP)) 
-#endif //AMBIENT_THERMISTOR
+	  if(current_temperature_bed < BED_MAXTEMP)
 	  {
 	    soft_pwm_bed = (int)pid_output >> 1;
 		timer02_set_pwm0(soft_pwm_bed << 1);
@@ -792,7 +802,7 @@ void manage_heater()
 
     #elif !defined(BED_LIMIT_SWITCHING)
       // Check if temperature is within the correct range
-      if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
+      if(current_temperature_bed < BED_MAXTEMP)
       {
         if(current_temperature_bed >= target_temperature_bed)
         {
@@ -813,7 +823,7 @@ void manage_heater()
       }
     #else //#ifdef BED_LIMIT_SWITCHING
       // Check if temperature is within the correct band
-      if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
+      if(current_temperature_bed < BED_MAXTEMP)
       {
         if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
         {
@@ -833,6 +843,8 @@ void manage_heater()
         WRITE(HEATER_BED_PIN,LOW);
       }
     #endif
+      if(target_temperature_bed==0)
+        soft_pwm_bed = 0;
   #endif
   
 #ifdef HOST_KEEPALIVE_FEATURE
@@ -1017,8 +1029,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 / cs.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;
@@ -1557,11 +1569,6 @@ ISR(TIMER2_COMPB_vect)
 	asm("sei");
 
 	if (!temp_meas_ready) adc_cycle();
-	else
-	{
-		check_max_temp();
-		check_min_temp();
-	}
 	lcd_buttons_update();
 
   static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
@@ -1954,26 +1961,49 @@ void check_min_temp_bed()
 
 void check_min_temp()
 {
+static bool bCheckingOnHeater=false;              // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over heaterMintemp)
+static bool bCheckingOnBed=false;                 // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over bedMintemp)
 #ifdef AMBIENT_THERMISTOR
-	static uint8_t heat_cycles = 0;
-	if (current_temperature_raw_ambient > OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)
-	{
-		if (READ(HEATER_0_PIN) == HIGH)
-		{
-//			if ((heat_cycles % 10) == 0)
-//				printf_P(PSTR("X%d\n"), heat_cycles);
-			if (heat_cycles > 50) //reaction time 5-10s
-				check_min_temp_heater0();
-			else
-				heat_cycles++;
-		}
-		else
-			heat_cycles = 0;
-		return;
-	}
+if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type, so operator is ">" ;-)
+     {                                            // ambient temperature is low
+#endif //AMBIENT_THERMISTOR
+// *** 'common' part of code for MK2.5 & MK3
+// * nozzle checking
+if(target_temperature[active_extruder]>minttemp[active_extruder])
+     {                                            // ~ nozzle heating is on
+     bCheckingOnHeater=bCheckingOnHeater||(current_temperature[active_extruder]>=minttemp[active_extruder]); // for eventually delay cutting
+     if(oTimer4minTempHeater.expired(HEATER_MINTEMP_DELAY)||(!oTimer4minTempHeater.running())||bCheckingOnHeater)
+          {
+          bCheckingOnHeater=true;                 // not necessary
+		check_min_temp_heater0();               // delay is elapsed or temperature is/was over minTemp => periodical checking is active
+          }
+     }
+else {                                            // ~ nozzle heating is off
+     oTimer4minTempHeater.start();
+     bCheckingOnHeater=false;
+     }
+// * bed checking
+if(target_temperature_bed>BED_MINTEMP)
+     {                                            // ~ bed heating is on
+     bCheckingOnBed=bCheckingOnBed||(current_temperature_bed>=BED_MINTEMP); // for eventually delay cutting
+     if(oTimer4minTempBed.expired(BED_MINTEMP_DELAY)||(!oTimer4minTempBed.running())||bCheckingOnBed)
+          {
+          bCheckingOnBed=true;                    // not necessary
+		check_min_temp_bed();                   // delay is elapsed or temperature is/was over minTemp => periodical checking is active
+          }
+     }
+else {                                            // ~ bed heating is off
+     oTimer4minTempBed.start();
+     bCheckingOnBed=false;
+     }
+// *** end of 'common' part
+#ifdef AMBIENT_THERMISTOR
+     }
+else {                                            // ambient temperature is standard
+     check_min_temp_heater0();
+     check_min_temp_bed();
+     }
 #endif //AMBIENT_THERMISTOR
-	check_min_temp_heater0();
-	check_min_temp_bed();
 }
  
 #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1))

+ 7 - 1
Firmware/temperature.h

@@ -87,6 +87,8 @@ extern int current_voltage_raw_bed;
   extern volatile int babystepsTodo[3];
 #endif
 
+void resetPID(uint8_t extruder);
+
 inline void babystepsTodoZadd(int n)
 {
     if (n != 0) {
@@ -137,11 +139,15 @@ 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;
+    if (extruder<EXTRUDERS) {
+      target_temperature[extruder] = celsius;
+      resetPID(extruder);
+    }
 }
 
 static inline void setAllTargetHotends(const float &celsius)

+ 2 - 0
Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h

@@ -105,7 +105,9 @@ EXTRUDER SETTINGS
 #define HEATER_0_MINTEMP 15
 #define HEATER_1_MINTEMP 5
 #define HEATER_2_MINTEMP 5
+#define HEATER_MINTEMP_DELAY 15000                // [ms] ! if changed, check maximal allowed value @ ShortTimer
 #define BED_MINTEMP 15
+#define BED_MINTEMP_DELAY 50000                   // [ms] ! if changed, check maximal allowed value @ ShortTimer
 
 // Maxtemps
 #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)

+ 2 - 0
Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h

@@ -105,7 +105,9 @@ EXTRUDER SETTINGS
 #define HEATER_0_MINTEMP 15
 #define HEATER_1_MINTEMP 5
 #define HEATER_2_MINTEMP 5
+#define HEATER_MINTEMP_DELAY 15000                // [ms] ! if changed, check maximal allowed value @ ShortTimer
 #define BED_MINTEMP 15
+#define BED_MINTEMP_DELAY 50000                   // [ms] ! if changed, check maximal allowed value @ ShortTimer
 
 // Maxtemps
 #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)

+ 4 - 2
Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h

@@ -153,10 +153,12 @@
  *------------------------------------*/
 
 // Mintemps
-#define HEATER_0_MINTEMP 15
+#define HEATER_0_MINTEMP 30
 #define HEATER_1_MINTEMP 5
 #define HEATER_2_MINTEMP 5
-#define BED_MINTEMP 15
+#define HEATER_MINTEMP_DELAY 15000                // [ms] ! if changed, check maximal allowed value @ ShortTimer
+#define BED_MINTEMP 30
+#define BED_MINTEMP_DELAY 50000                   // [ms] ! if changed, check maximal allowed value @ ShortTimer
 
 // Maxtemps
 #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)

+ 4 - 2
Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h

@@ -154,10 +154,12 @@
  *------------------------------------*/
 
 // Mintemps
-#define HEATER_0_MINTEMP 15
+#define HEATER_0_MINTEMP 30
 #define HEATER_1_MINTEMP 5
 #define HEATER_2_MINTEMP 5
-#define BED_MINTEMP 15
+#define HEATER_MINTEMP_DELAY 15000                // [ms] ! if changed, check maximal allowed value @ ShortTimer
+#define BED_MINTEMP 30
+#define BED_MINTEMP_DELAY 50000                   // [ms] ! if changed, check maximal allowed value @ ShortTimer
 
 // Maxtemps
 #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)

+ 2 - 0
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -276,7 +276,9 @@
 #define HEATER_0_MINTEMP 15
 #define HEATER_1_MINTEMP 5
 #define HEATER_2_MINTEMP 5
+#define HEATER_MINTEMP_DELAY 15000                // [ms] ! if changed, check maximal allowed value @ ShortTimer
 #define BED_MINTEMP 15
+#define BED_MINTEMP_DELAY 50000                   // [ms] ! if changed, check maximal allowed value @ ShortTimer
 
 // Maxtemps
 #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP)