Browse Source

Refactor heater watch, job timer auto-start (#16725)

Scott Lahteine 5 years ago
parent
commit
9caf5c05e7
No account linked to committer's email address

+ 2
- 2
Marlin/src/feature/pause.cpp View File

564
       #endif
564
       #endif
565
 
565
 
566
       // Re-enable the heaters if they timed out
566
       // Re-enable the heaters if they timed out
567
-      HOTEND_LOOP() thermalManager.reset_heater_idle_timer(e);
567
+      HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e);
568
 
568
 
569
       // Wait for the heaters to reach the target temperatures
569
       // Wait for the heaters to reach the target temperatures
570
       ensure_safe_temperature();
570
       ensure_safe_temperature();
633
   bool nozzle_timed_out = false;
633
   bool nozzle_timed_out = false;
634
   HOTEND_LOOP() {
634
   HOTEND_LOOP() {
635
     nozzle_timed_out |= thermalManager.hotend_idle[e].timed_out;
635
     nozzle_timed_out |= thermalManager.hotend_idle[e].timed_out;
636
-    thermalManager.reset_heater_idle_timer(e);
636
+    thermalManager.reset_hotend_idle_timer(e);
637
   }
637
   }
638
 
638
 
639
   if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // Load the new filament
639
   if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // Load the new filament

+ 15
- 15
Marlin/src/gcode/temperature/M104_M109.cpp View File

20
  *
20
  *
21
  */
21
  */
22
 
22
 
23
+/**
24
+ * gcode/temperature/M104_M109.cpp
25
+ *
26
+ * Hotend target temperature control
27
+ */
28
+
23
 #include "../../inc/MarlinConfigPre.h"
29
 #include "../../inc/MarlinConfigPre.h"
24
 
30
 
25
 #if EXTRUDERS
31
 #if EXTRUDERS
73
     #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
79
     #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
74
       /**
80
       /**
75
        * Stop the timer at the end of print. Start is managed by 'heat and wait' M109.
81
        * Stop the timer at the end of print. Start is managed by 'heat and wait' M109.
76
-       * We use half EXTRUDE_MINTEMP here to allow nozzles to be put into hot
77
-       * standby mode, for instance in a dual extruder setup, without affecting
78
-       * the running print timer.
82
+       * Hotends use EXTRUDE_MINTEMP / 2 to allow nozzles to be put into hot standby
83
+       * mode, for instance in a dual extruder setup, without affecting the running
84
+       * print timer.
79
        */
85
        */
80
-      if (temp <= (EXTRUDE_MINTEMP) / 2) {
81
-        print_job_timer.stop();
82
-        ui.reset_status();
83
-      }
86
+      thermalManager.check_timer_autostart(false, true);
84
     #endif
87
     #endif
85
   }
88
   }
86
 
89
 
90
 }
93
 }
91
 
94
 
92
 /**
95
 /**
93
- * M109: Sxxx Wait for extruder(s) to reach temperature. Waits only when heating.
94
- *       Rxxx Wait for extruder(s) to reach temperature. Waits when heating and cooling.
96
+ * M109: Sxxx Wait for hotend(s) to reach temperature. Waits only when heating.
97
+ *       Rxxx Wait for hotend(s) to reach temperature. Waits when heating and cooling.
98
+ *
99
+ * With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating and stop it if turned off.
95
  */
100
  */
96
 void GcodeSuite::M109() {
101
 void GcodeSuite::M109() {
97
 
102
 
125
        * standby mode, (e.g., in a dual extruder setup) without affecting
130
        * standby mode, (e.g., in a dual extruder setup) without affecting
126
        * the running print timer.
131
        * the running print timer.
127
        */
132
        */
128
-      if (parser.value_celsius() <= (EXTRUDE_MINTEMP) / 2) {
129
-        print_job_timer.stop();
130
-        ui.reset_status();
131
-      }
132
-      else
133
-        startOrResumeJob();
133
+      thermalManager.check_timer_autostart(true, true);
134
     #endif
134
     #endif
135
 
135
 
136
     #if HAS_DISPLAY
136
     #if HAS_DISPLAY

+ 9
- 2
Marlin/src/gcode/temperature/M140_M190.cpp View File

20
  *
20
  *
21
  */
21
  */
22
 
22
 
23
+/**
24
+ * gcode/temperature/M140_M190.cpp
25
+ *
26
+ * Bed target temperature control
27
+ */
28
+
23
 #include "../../inc/MarlinConfig.h"
29
 #include "../../inc/MarlinConfig.h"
24
 
30
 
25
 #if HAS_HEATED_BED
31
 #if HAS_HEATED_BED
50
 /**
56
 /**
51
  * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
57
  * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
52
  *       Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
58
  *       Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
59
+ *
60
+ * With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating.
53
  */
61
  */
54
 void GcodeSuite::M190() {
62
 void GcodeSuite::M190() {
55
   if (DEBUGGING(DRYRUN)) return;
63
   if (DEBUGGING(DRYRUN)) return;
58
   if (no_wait_for_cooling || parser.seenval('R')) {
66
   if (no_wait_for_cooling || parser.seenval('R')) {
59
     thermalManager.setTargetBed(parser.value_celsius());
67
     thermalManager.setTargetBed(parser.value_celsius());
60
     #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
68
     #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
61
-      if (parser.value_celsius() > BED_MINTEMP)
62
-        startOrResumeJob();
69
+      thermalManager.check_timer_autostart(true, false);
63
     #endif
70
     #endif
64
   }
71
   }
65
   else return;
72
   else return;

+ 7
- 2
Marlin/src/gcode/temperature/M141_M191.cpp View File

20
  *
20
  *
21
  */
21
  */
22
 
22
 
23
+/**
24
+ * gcode/temperature/M141_M191.cpp
25
+ *
26
+ * Chamber target temperature control
27
+ */
28
+
23
 #include "../../inc/MarlinConfig.h"
29
 #include "../../inc/MarlinConfig.h"
24
 
30
 
25
 #if HAS_HEATED_CHAMBER
31
 #if HAS_HEATED_CHAMBER
59
   if (no_wait_for_cooling || parser.seenval('R')) {
65
   if (no_wait_for_cooling || parser.seenval('R')) {
60
     thermalManager.setTargetChamber(parser.value_celsius());
66
     thermalManager.setTargetChamber(parser.value_celsius());
61
     #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
67
     #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
62
-      if (parser.value_celsius() > CHAMBER_MINTEMP)
63
-        startOrResumeJob();
68
+      thermalManager.check_timer_autostart(true, false);
64
     #endif
69
     #endif
65
   }
70
   }
66
   else return;
71
   else return;

+ 2
- 2
Marlin/src/lcd/extensible_ui/ui_api.cpp View File

171
 
171
 
172
   void enableHeater(const extruder_t extruder) {
172
   void enableHeater(const extruder_t extruder) {
173
     #if HOTENDS && HEATER_IDLE_HANDLER
173
     #if HOTENDS && HEATER_IDLE_HANDLER
174
-      thermalManager.reset_heater_idle_timer(extruder - E0);
174
+      thermalManager.reset_hotend_idle_timer(extruder - E0);
175
     #else
175
     #else
176
       UNUSED(extruder);
176
       UNUSED(extruder);
177
     #endif
177
     #endif
190
         #endif
190
         #endif
191
         default:
191
         default:
192
           #if HOTENDS
192
           #if HOTENDS
193
-            thermalManager.reset_heater_idle_timer(heater - H0);
193
+            thermalManager.reset_hotend_idle_timer(heater - H0);
194
           #endif
194
           #endif
195
           break;
195
           break;
196
       }
196
       }

+ 37
- 24
Marlin/src/module/temperature.cpp View File

220
 #endif // FAN_COUNT > 0
220
 #endif // FAN_COUNT > 0
221
 
221
 
222
 #if WATCH_HOTENDS
222
 #if WATCH_HOTENDS
223
-  heater_watch_t Temperature::watch_hotend[HOTENDS]; // = { { 0 } }
223
+  hotend_watch_t Temperature::watch_hotend[HOTENDS]; // = { { 0 } }
224
 #endif
224
 #endif
225
 #if HEATER_IDLE_HANDLER
225
 #if HEATER_IDLE_HANDLER
226
-  heater_idle_t Temperature::hotend_idle[HOTENDS]; // = { { 0 } }
226
+  hotend_idle_t Temperature::hotend_idle[HOTENDS]; // = { { 0 } }
227
 #endif
227
 #endif
228
 
228
 
229
 #if HAS_HEATED_BED
229
 #if HAS_HEATED_BED
236
     int16_t Temperature::maxtemp_raw_BED = HEATER_BED_RAW_HI_TEMP;
236
     int16_t Temperature::maxtemp_raw_BED = HEATER_BED_RAW_HI_TEMP;
237
   #endif
237
   #endif
238
   #if WATCH_BED
238
   #if WATCH_BED
239
-    heater_watch_t Temperature::watch_bed; // = { 0 }
239
+    bed_watch_t Temperature::watch_bed; // = { 0 }
240
   #endif
240
   #endif
241
   #if DISABLED(PIDTEMPBED)
241
   #if DISABLED(PIDTEMPBED)
242
     millis_t Temperature::next_bed_check_ms;
242
     millis_t Temperature::next_bed_check_ms;
243
   #endif
243
   #endif
244
   #if HEATER_IDLE_HANDLER
244
   #if HEATER_IDLE_HANDLER
245
-    heater_idle_t Temperature::bed_idle; // = { 0 }
245
+    hotend_idle_t Temperature::bed_idle; // = { 0 }
246
   #endif
246
   #endif
247
 #endif // HAS_HEATED_BED
247
 #endif // HAS_HEATED_BED
248
 
248
 
256
       int16_t Temperature::maxtemp_raw_CHAMBER = HEATER_CHAMBER_RAW_HI_TEMP;
256
       int16_t Temperature::maxtemp_raw_CHAMBER = HEATER_CHAMBER_RAW_HI_TEMP;
257
     #endif
257
     #endif
258
     #if WATCH_CHAMBER
258
     #if WATCH_CHAMBER
259
-      heater_watch_t Temperature::watch_chamber{0};
259
+      chamber_watch_t Temperature::watch_chamber{0};
260
     #endif
260
     #endif
261
     millis_t Temperature::next_chamber_check_ms;
261
     millis_t Temperature::next_chamber_check_ms;
262
   #endif // HAS_HEATED_CHAMBER
262
   #endif // HAS_HEATED_CHAMBER
1974
    */
1974
    */
1975
   void Temperature::start_watching_hotend(const uint8_t E_NAME) {
1975
   void Temperature::start_watching_hotend(const uint8_t E_NAME) {
1976
     const uint8_t ee = HOTEND_INDEX;
1976
     const uint8_t ee = HOTEND_INDEX;
1977
-    if (degTargetHotend(ee) && degHotend(ee) < degTargetHotend(ee) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
1978
-      watch_hotend[ee].target = degHotend(ee) + WATCH_TEMP_INCREASE;
1979
-      watch_hotend[ee].next_ms = millis() + (WATCH_TEMP_PERIOD) * 1000UL;
1980
-    }
1981
-    else
1982
-      watch_hotend[ee].next_ms = 0;
1977
+    watch_hotend[ee].restart(degHotend(ee), degTargetHotend(ee));
1983
   }
1978
   }
1984
 #endif
1979
 #endif
1985
 
1980
 
1990
    * This is called when the temperature is set. (M140, M190)
1985
    * This is called when the temperature is set. (M140, M190)
1991
    */
1986
    */
1992
   void Temperature::start_watching_bed() {
1987
   void Temperature::start_watching_bed() {
1993
-    if (degTargetBed() && degBed() < degTargetBed() - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) {
1994
-      watch_bed.target = degBed() + WATCH_BED_TEMP_INCREASE;
1995
-      watch_bed.next_ms = millis() + (WATCH_BED_TEMP_PERIOD) * 1000UL;
1996
-    }
1997
-    else
1998
-      watch_bed.next_ms = 0;
1988
+    watch_bed.restart(degBed(), degTargetBed());
1999
   }
1989
   }
2000
 #endif
1990
 #endif
2001
 
1991
 
2006
    * This is called when the temperature is set. (M141, M191)
1996
    * This is called when the temperature is set. (M141, M191)
2007
    */
1997
    */
2008
   void Temperature::start_watching_chamber() {
1998
   void Temperature::start_watching_chamber() {
2009
-    if (degChamber() < degTargetChamber() - (WATCH_CHAMBER_TEMP_INCREASE + TEMP_CHAMBER_HYSTERESIS + 1)) {
2010
-      watch_chamber.target = degChamber() + WATCH_CHAMBER_TEMP_INCREASE;
2011
-      watch_chamber.next_ms = millis() + (WATCH_CHAMBER_TEMP_PERIOD) * 1000UL;
2012
-    }
2013
-    else
2014
-      watch_chamber.next_ms = 0;
1999
+    watch_chamber.restart(degChamber(), degTargetChamber());
2015
   }
2000
   }
2016
 #endif
2001
 #endif
2017
 
2002
 
2154
   #endif
2139
   #endif
2155
 }
2140
 }
2156
 
2141
 
2142
+#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
2143
+
2144
+  bool Temperature::over_autostart_threshold() {
2145
+    #if HOTENDS
2146
+      HOTEND_LOOP() if (degTargetHotend(e) < (EXTRUDE_MINTEMP) / 2) return true;
2147
+    #endif
2148
+    #if HAS_HEATED_BED
2149
+      if (degTargetBed() > BED_MINTEMP) return true;
2150
+    #endif
2151
+    #if HAS_HEATED_CHAMBER
2152
+      if (degTargetChamber() > CHAMBER_MINTEMP) return true;
2153
+    #endif
2154
+    return false;
2155
+  }
2156
+
2157
+  void Temperature::check_timer_autostart(const bool can_start, const bool can_stop) {
2158
+    if (over_autostart_threshold()) {
2159
+      if (can_start) startOrResumeJob();
2160
+    }
2161
+    else if (can_stop) {
2162
+      print_job_timer.stop();
2163
+      ui.reset_status();
2164
+    }
2165
+  }
2166
+
2167
+#endif
2168
+
2169
+
2157
 #if ENABLED(PROBING_HEATERS_OFF)
2170
 #if ENABLED(PROBING_HEATERS_OFF)
2158
 
2171
 
2159
   void Temperature::pause(const bool p) {
2172
   void Temperature::pause(const bool p) {
2166
         #endif
2179
         #endif
2167
       }
2180
       }
2168
       else {
2181
       else {
2169
-        HOTEND_LOOP() reset_heater_idle_timer(e);
2182
+        HOTEND_LOOP() reset_hotend_idle_timer(e);
2170
         #if HAS_HEATED_BED
2183
         #if HAS_HEATED_BED
2171
           reset_bed_idle_timer();
2184
           reset_bed_idle_timer();
2172
         #endif
2185
         #endif

+ 41
- 10
Marlin/src/module/temperature.h View File

228
   inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; }
228
   inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; }
229
   inline void reset() { timeout_ms = 0; timed_out = false; }
229
   inline void reset() { timeout_ms = 0; timed_out = false; }
230
   inline void expire() { start(0); }
230
   inline void expire() { start(0); }
231
-} heater_idle_t;
231
+} hotend_idle_t;
232
 
232
 
233
 // Heater watch handling
233
 // Heater watch handling
234
-typedef struct {
234
+template <int INCREASE, int HYSTERESIS, millis_t PERIOD>
235
+struct HeaterWatch {
235
   uint16_t target;
236
   uint16_t target;
236
   millis_t next_ms;
237
   millis_t next_ms;
237
   inline bool elapsed(const millis_t &ms) { return next_ms && ELAPSED(ms, next_ms); }
238
   inline bool elapsed(const millis_t &ms) { return next_ms && ELAPSED(ms, next_ms); }
238
   inline bool elapsed() { return elapsed(millis()); }
239
   inline bool elapsed() { return elapsed(millis()); }
239
-} heater_watch_t;
240
+
241
+  inline void restart(const int16_t curr, const int16_t tgt) {
242
+    if (tgt) {
243
+      const int16_t newtarget = curr + INCREASE;
244
+      if (newtarget < tgt - HYSTERESIS - 1) {
245
+        target = newtarget;
246
+        next_ms = millis() + PERIOD * 1000UL;
247
+        return;
248
+      }
249
+    }
250
+    next_ms = 0;
251
+  }
252
+};
253
+
254
+#if WATCH_HOTENDS
255
+  typedef struct HeaterWatch<WATCH_TEMP_INCREASE, TEMP_HYSTERESIS, WATCH_TEMP_PERIOD> hotend_watch_t;
256
+#endif
257
+#if WATCH_BED
258
+  typedef struct HeaterWatch<WATCH_BED_TEMP_INCREASE, TEMP_BED_HYSTERESIS, WATCH_BED_TEMP_PERIOD> bed_watch_t;
259
+#endif
260
+#if WATCH_CHAMBER
261
+  typedef struct HeaterWatch<WATCH_CHAMBER_TEMP_INCREASE, TEMP_CHAMBER_HYSTERESIS, WATCH_CHAMBER_TEMP_PERIOD> chamber_watch_t;
262
+#endif
240
 
263
 
241
 // Temperature sensor read value ranges
264
 // Temperature sensor read value ranges
242
 typedef struct { int16_t raw_min, raw_max; } raw_range_t;
265
 typedef struct { int16_t raw_min, raw_max; } raw_range_t;
345
     FORCE_INLINE static bool targetHotEnoughToExtrude(const uint8_t e) { return !targetTooColdToExtrude(e); }
368
     FORCE_INLINE static bool targetHotEnoughToExtrude(const uint8_t e) { return !targetTooColdToExtrude(e); }
346
 
369
 
347
     #if HEATER_IDLE_HANDLER
370
     #if HEATER_IDLE_HANDLER
348
-      static heater_idle_t hotend_idle[HOTENDS];
371
+      static hotend_idle_t hotend_idle[HOTENDS];
349
       #if HAS_HEATED_BED
372
       #if HAS_HEATED_BED
350
-        static heater_idle_t bed_idle;
373
+        static hotend_idle_t bed_idle;
351
       #endif
374
       #endif
352
       #if HAS_HEATED_CHAMBER
375
       #if HAS_HEATED_CHAMBER
353
-        static heater_idle_t chamber_idle;
376
+        static hotend_idle_t chamber_idle;
354
       #endif
377
       #endif
355
     #endif
378
     #endif
356
 
379
 
363
     static volatile bool raw_temps_ready;
386
     static volatile bool raw_temps_ready;
364
 
387
 
365
     #if WATCH_HOTENDS
388
     #if WATCH_HOTENDS
366
-      static heater_watch_t watch_hotend[HOTENDS];
389
+      static hotend_watch_t watch_hotend[HOTENDS];
367
     #endif
390
     #endif
368
 
391
 
369
     #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
392
     #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
382
 
405
 
383
     #if HAS_HEATED_BED
406
     #if HAS_HEATED_BED
384
       #if WATCH_BED
407
       #if WATCH_BED
385
-        static heater_watch_t watch_bed;
408
+        static bed_watch_t watch_bed;
386
       #endif
409
       #endif
387
       #if DISABLED(PIDTEMPBED)
410
       #if DISABLED(PIDTEMPBED)
388
         static millis_t next_bed_check_ms;
411
         static millis_t next_bed_check_ms;
397
 
420
 
398
     #if HAS_HEATED_CHAMBER
421
     #if HAS_HEATED_CHAMBER
399
       #if WATCH_CHAMBER
422
       #if WATCH_CHAMBER
400
-        static heater_watch_t watch_chamber;
423
+        static chamber_watch_t watch_chamber;
401
       #endif
424
       #endif
402
       static millis_t next_chamber_check_ms;
425
       static millis_t next_chamber_check_ms;
403
       #ifdef CHAMBER_MINTEMP
426
       #ifdef CHAMBER_MINTEMP
736
      */
759
      */
737
     static void disable_all_heaters();
760
     static void disable_all_heaters();
738
 
761
 
762
+    #if ENABLED(PRINTJOB_TIMER_AUTOSTART)
763
+      /**
764
+       * Methods to check if heaters are enabled, indicating an active job
765
+       */
766
+      static bool over_autostart_threshold();
767
+      static void check_timer_autostart(const bool can_start, const bool can_stop);
768
+    #endif
769
+
739
     /**
770
     /**
740
      * Perform auto-tuning for hotend or bed in response to M303
771
      * Perform auto-tuning for hotend or bed in response to M303
741
      */
772
      */
768
 
799
 
769
     #if HEATER_IDLE_HANDLER
800
     #if HEATER_IDLE_HANDLER
770
 
801
 
771
-      static void reset_heater_idle_timer(const uint8_t E_NAME) {
802
+      static void reset_hotend_idle_timer(const uint8_t E_NAME) {
772
         hotend_idle[HOTEND_INDEX].reset();
803
         hotend_idle[HOTEND_INDEX].reset();
773
         start_watching_hotend(HOTEND_INDEX);
804
         start_watching_hotend(HOTEND_INDEX);
774
       }
805
       }

Loading…
Cancel
Save