Kaynağa Gözat

[1.1.x] M303 thermal runaway protection (#8209)

* Added M303 thermal runaway protection

Currently, thermal runaway protection is not available during M303.
Therefore, if someone plugs the thermistors in incorrectly and goes to
autotune their printer, the printer temperature could runaway and damage
could occur.

* Replace removed line, clarifying its logic
Rowan Meara 7 yıl önce
ebeveyn
işleme
39cc36d3f1
2 değiştirilmiş dosya ile 61 ekleme ve 19 silme
  1. 60
    18
      Marlin/temperature.cpp
  2. 1
    1
      Marlin/temperature.h

+ 60
- 18
Marlin/temperature.cpp Dosyayı Görüntüle

@@ -215,7 +215,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
215 215
 
216 216
 #if HAS_PID_HEATING
217 217
 
218
-  void Temperature::PID_autotune(float temp, int hotend, int ncycles, bool set_result/*=false*/) {
218
+  void Temperature::PID_autotune(const float temp, const int8_t hotend, const int8_t ncycles, const bool set_result/*=false*/) {
219 219
     float input = 0.0;
220 220
     int cycles = 0;
221 221
     bool heating = true;
@@ -224,27 +224,59 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
224 224
     long t_high = 0, t_low = 0;
225 225
 
226 226
     long bias, d;
227
-    float Ku, Tu;
228
-    float workKp = 0, workKi = 0, workKd = 0;
229
-    float max = 0, min = 10000;
227
+    float Ku, Tu,
228
+          workKp = 0, workKi = 0, workKd = 0,
229
+          max = 0, min = 10000;
230
+
231
+    #if WATCH_THE_BED || WATCH_HOTENDS
232
+      const float watch_temp_target =
233
+        #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
234
+          hotend < 0 ? temp - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1) : temp - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)
235
+        #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
236
+          temp - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)
237
+        #else
238
+          temp - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)
239
+        #endif
240
+      ;
241
+      const int8_t watch_temp_period =
242
+        #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
243
+          hotend < 0 ? temp - THERMAL_PROTECTION_BED_PERIOD : THERMAL_PROTECTION_PERIOD
244
+        #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
245
+          THERMAL_PROTECTION_BED_PERIOD
246
+        #else
247
+          THERMAL_PROTECTION_PERIOD
248
+        #endif
249
+      ;
250
+      const int8_t hysteresis =
251
+        #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
252
+          hotend < 0 ? TEMP_BED_HYSTERESIS : TEMP_HYSTERESIS
253
+        #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
254
+          TEMP_BED_HYSTERESIS
255
+        #else
256
+          TEMP_HYSTERESIS
257
+        #endif
258
+      ;
259
+      millis_t temp_change_ms = temp_ms + watch_temp_period * 1000UL;
260
+      float next_watch_temp = 0.0;
261
+      bool heated = false;
262
+    #endif
230 263
 
231 264
     #if HAS_AUTO_FAN
232 265
       next_auto_fan_check_ms = temp_ms + 2500UL;
233 266
     #endif
234 267
 
235
-    if (hotend >=
236
-        #if ENABLED(PIDTEMP)
237
-          HOTENDS
238
-        #else
239
-          0
240
-        #endif
241
-      || hotend <
242
-        #if ENABLED(PIDTEMPBED)
243
-          -1
244
-        #else
245
-          0
246
-        #endif
247
-    ) {
268
+    #if ENABLED(PIDTEMP)
269
+      #define _TOP_HOTEND HOTENDS - 1
270
+    #else
271
+      #define _TOP_HOTEND -1
272
+    #endif
273
+    #if ENABLED(PIDTEMPBED)
274
+      #define _BOT_HOTEND -1
275
+    #else
276
+      #define _BOT_HOTEND 0
277
+    #endif
278
+
279
+    if (!WITHIN(hotend, _BOT_HOTEND, _TOP_HOTEND)) {
248 280
       SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
249 281
       return;
250 282
     }
@@ -330,7 +362,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
330 362
               ;
331 363
               bias += (d * (t_high - t_low)) / (t_low + t_high);
332 364
               bias = constrain(bias, 20, max_pow - 20);
333
-              d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
365
+              d = (bias > max_pow >> 1) ? max_pow - 1 - bias : bias;
334 366
 
335 367
               SERIAL_PROTOCOLPAIR(MSG_BIAS, bias);
336 368
               SERIAL_PROTOCOLPAIR(MSG_D, d);
@@ -394,6 +426,16 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
394 426
         #endif
395 427
 
396 428
         temp_ms = ms + 2000UL;
429
+
430
+        #if WATCH_THE_BED || WATCH_HOTENDS
431
+          if (!heated && input > next_watch_temp) {
432
+            if (input > watch_temp_target) heated = true;
433
+            next_watch_temp = input + hysteresis;
434
+            temp_change_ms = ms + watch_temp_period * 1000UL;
435
+          }
436
+          else if ((!heated && ELAPSED(ms, temp_change_ms)) || (heated && input < temp - MAX_OVERSHOOT_PID_AUTOTUNE))
437
+            _temp_error(hotend, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
438
+        #endif
397 439
       } // every 2 seconds
398 440
       // Timeout after 20 minutes since the last undershoot/overshoot cycle
399 441
       if (((ms - t1) + (ms - t2)) > (20L * 60L * 1000L)) {

+ 1
- 1
Marlin/temperature.h Dosyayı Görüntüle

@@ -437,7 +437,7 @@ class Temperature {
437 437
      * Perform auto-tuning for hotend or bed in response to M303
438 438
      */
439 439
     #if HAS_PID_HEATING
440
-      static void PID_autotune(float temp, int hotend, int ncycles, bool set_result=false);
440
+      static void PID_autotune(const float temp, const int8_t hotend, const int8_t ncycles, const bool set_result=false);
441 441
     #endif
442 442
 
443 443
     /**

Loading…
İptal
Kaydet