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
 
215
 
216
 #if HAS_PID_HEATING
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
     float input = 0.0;
219
     float input = 0.0;
220
     int cycles = 0;
220
     int cycles = 0;
221
     bool heating = true;
221
     bool heating = true;
224
     long t_high = 0, t_low = 0;
224
     long t_high = 0, t_low = 0;
225
 
225
 
226
     long bias, d;
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
     #if HAS_AUTO_FAN
264
     #if HAS_AUTO_FAN
232
       next_auto_fan_check_ms = temp_ms + 2500UL;
265
       next_auto_fan_check_ms = temp_ms + 2500UL;
233
     #endif
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
       SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
280
       SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
249
       return;
281
       return;
250
     }
282
     }
330
               ;
362
               ;
331
               bias += (d * (t_high - t_low)) / (t_low + t_high);
363
               bias += (d * (t_high - t_low)) / (t_low + t_high);
332
               bias = constrain(bias, 20, max_pow - 20);
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
               SERIAL_PROTOCOLPAIR(MSG_BIAS, bias);
367
               SERIAL_PROTOCOLPAIR(MSG_BIAS, bias);
336
               SERIAL_PROTOCOLPAIR(MSG_D, d);
368
               SERIAL_PROTOCOLPAIR(MSG_D, d);
394
         #endif
426
         #endif
395
 
427
 
396
         temp_ms = ms + 2000UL;
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
       } // every 2 seconds
439
       } // every 2 seconds
398
       // Timeout after 20 minutes since the last undershoot/overshoot cycle
440
       // Timeout after 20 minutes since the last undershoot/overshoot cycle
399
       if (((ms - t1) + (ms - t2)) > (20L * 60L * 1000L)) {
441
       if (((ms - t1) + (ms - t2)) > (20L * 60L * 1000L)) {

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

437
      * Perform auto-tuning for hotend or bed in response to M303
437
      * Perform auto-tuning for hotend or bed in response to M303
438
      */
438
      */
439
     #if HAS_PID_HEATING
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
     #endif
441
     #endif
442
 
442
 
443
     /**
443
     /**

Loading…
İptal
Kaydet