Browse Source

M872 wait for probe temperature (#19344)

Neskik 4 years ago
parent
commit
1917ed8741
No account linked to committer's email address

Marlin/src/gcode/calibrate/G76_M871.cpp → Marlin/src/gcode/calibrate/G76_M871-M872.cpp View File

@@ -37,6 +37,17 @@
37 37
 #include "../../module/probe.h"
38 38
 #include "../../feature/probe_temp_comp.h"
39 39
 
40
+#include "../../lcd/ultralcd.h"
41
+#include "../../MarlinCore.h" // for wait_for_heatup and idle()
42
+
43
+#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
44
+  #include "../../module/printcounter.h"
45
+#endif
46
+
47
+#if ENABLED(PRINTER_EVENTS_LEDS)
48
+  #include "../../feature/leds/leds.h"
49
+#endif
50
+
40 51
 /**
41 52
  * G76: calibrate probe and/or bed temperature offsets
42 53
  *  Notes:
@@ -303,17 +314,17 @@ void GcodeSuite::M871() {
303 314
   }
304 315
   else if (parser.seen("BPE")) {
305 316
     if (!parser.seenval('V')) return;
306
-    const int16_t val = parser.value_int();
317
+    const int16_t offset_val = parser.value_int();
307 318
     if (!parser.seenval('I')) return;
308 319
     const int16_t idx = parser.value_int();
309 320
     const TempSensorID mod = (parser.seen('B') ? TSI_BED :
310
-                              #if ENABLED(USE_TEMP_EXT_COMPENSATION)
311
-                                parser.seen('E') ? TSI_EXT :
312
-                              #endif
313
-                              TSI_PROBE
321
+                                #if ENABLED(USE_TEMP_EXT_COMPENSATION)
322
+                                  parser.seen('E') ? TSI_EXT :
323
+                                #endif
324
+                                TSI_PROBE
314 325
                               );
315
-    if (idx > 0 && temp_comp.set_offset(mod, idx - 1, val))
316
-      SERIAL_ECHOLNPAIR("Set value: ", val);
326
+    if (idx > 0 && temp_comp.set_offset(mod, idx - 1, offset_val))
327
+      SERIAL_ECHOLNPAIR("Set value: ", offset_val);
317 328
     else
318 329
       SERIAL_ECHOLNPGM("!Invalid index. Failed to set value (note: value at index 0 is constant).");
319 330
 
@@ -322,4 +333,25 @@ void GcodeSuite::M871() {
322 333
     temp_comp.print_offsets();
323 334
 }
324 335
 
336
+/**
337
+ * M872: Wait for probe temperature sensor to reach a target
338
+ *
339
+ * Select only one of these flags:
340
+ *    R - Wait for heating or cooling
341
+ *    S - Wait only for heating
342
+ */
343
+void GcodeSuite::M872() {
344
+  if (DEBUGGING(DRYRUN)) return;
345
+
346
+  const bool no_wait_for_cooling = parser.seenval('S');
347
+  if (!no_wait_for_cooling && ! parser.seenval('R')) {
348
+    SERIAL_ERROR_MSG("No target temperature set.");
349
+    return;
350
+  }
351
+
352
+  const float target_temp = parser.value_celsius();
353
+  ui.set_status_P(thermalManager.isProbeBelowTemp(target_temp) ? GET_TEXT(MSG_PROBE_HEATING) : GET_TEXT(MSG_PROBE_COOLING));
354
+  thermalManager.wait_for_probe(target_temp, no_wait_for_cooling);
355
+}
356
+
325 357
 #endif // PROBE_TEMP_COMPENSATION

+ 1
- 0
Marlin/src/gcode/gcode.cpp View File

@@ -819,6 +819,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
819 819
 
820 820
       #if ENABLED(PROBE_TEMP_COMPENSATION)
821 821
         case 871: M871(); break;                                  // M871: Print/reset/clear first layer temperature offset values
822
+        case 872: M872(); break;                                  // M872: Wait for probe temp
822 823
       #endif
823 824
 
824 825
       #if ENABLED(LIN_ADVANCE)

+ 5
- 1
Marlin/src/gcode/gcode.h View File

@@ -253,6 +253,7 @@
253 253
  * M868 - Report or set position encoder module error correction threshold.
254 254
  * M869 - Report position encoder module error.
255 255
  * M871 - Print/reset/clear first layer temperature offset values. (Requires PROBE_TEMP_COMPENSATION)
256
+ * M872 - Wait for probe temp (Requires PROBE_TEMP_COMPENSATION)
256 257
  * M876 - Handle Prompt Response. (Requires HOST_PROMPT_SUPPORT and not EMERGENCY_PARSER)
257 258
  * M900 - Get or Set Linear Advance K-factor. (Requires LIN_ADVANCE)
258 259
  * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660 or L6470)
@@ -820,7 +821,10 @@ private:
820 821
     FORCE_INLINE static void M869() { I2CPEM.M869(); }
821 822
   #endif
822 823
 
823
-  TERN_(PROBE_TEMP_COMPENSATION, static void M871());
824
+  #if ENABLED(PROBE_TEMP_COMPENSATION)
825
+    static void M871();
826
+    static void M872();
827
+  #endif
824 828
 
825 829
   TERN_(LIN_ADVANCE, static void M900());
826 830
 

+ 2
- 0
Marlin/src/lcd/language/language_en.h View File

@@ -470,6 +470,8 @@ namespace Language_en {
470 470
   PROGMEM Language_Str MSG_COOLING                         = _UxGT("Cooling...");
471 471
   PROGMEM Language_Str MSG_BED_HEATING                     = _UxGT("Bed Heating...");
472 472
   PROGMEM Language_Str MSG_BED_COOLING                     = _UxGT("Bed Cooling...");
473
+  PROGMEM Language_Str MSG_PROBE_HEATING                   = _UxGT("Probe Heating...");
474
+  PROGMEM Language_Str MSG_PROBE_COOLING                   = _UxGT("Probe Cooling...");
473 475
   PROGMEM Language_Str MSG_CHAMBER_HEATING                 = _UxGT("Chamber Heating...");
474 476
   PROGMEM Language_Str MSG_CHAMBER_COOLING                 = _UxGT("Chamber Cooling...");
475 477
   PROGMEM Language_Str MSG_DELTA_CALIBRATE                 = _UxGT("Delta Calibration");

+ 2
- 0
Marlin/src/lcd/language/language_fr.h View File

@@ -413,6 +413,8 @@ namespace Language_fr {
413 413
   PROGMEM Language_Str MSG_COOLING                         = _UxGT("Refroidissement");
414 414
   PROGMEM Language_Str MSG_BED_HEATING                     = _UxGT("Lit en chauffe...");
415 415
   PROGMEM Language_Str MSG_BED_COOLING                     = _UxGT("Refroid. du lit...");
416
+  PROGMEM Language_Str MSG_PROBE_HEATING                   = _UxGT("Probe en chauffe...");
417
+  PROGMEM Language_Str MSG_PROBE_COOLING                   = _UxGT("Refroid. Probe...");
416 418
   PROGMEM Language_Str MSG_CHAMBER_HEATING                 = _UxGT("Chauffe caisson...");
417 419
   PROGMEM Language_Str MSG_CHAMBER_COOLING                 = _UxGT("Refroid. caisson...");
418 420
   PROGMEM Language_Str MSG_DELTA_CALIBRATE                 = _UxGT("Calibration Delta");

+ 98
- 18
Marlin/src/module/temperature.cpp View File

@@ -440,7 +440,6 @@ volatile bool Temperature::raw_temps_ready = false;
440 440
 
441 441
     SHV(bias = d = (MAX_BED_POWER) >> 1, bias = d = (PID_MAX) >> 1);
442 442
 
443
-    wait_for_heatup = true; // Can be interrupted with M108
444 443
     #if ENABLED(PRINTER_EVENT_LEDS)
445 444
       const float start_temp = GHV(temp_bed.celsius, temp_hotend[heater].celsius);
446 445
       LEDColor color = ONHEATINGSTART();
@@ -449,6 +448,7 @@ volatile bool Temperature::raw_temps_ready = false;
449 448
     TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = false);
450 449
 
451 450
     // PID Tuning loop
451
+    wait_for_heatup = true; // Can be interrupted with M108
452 452
     while (wait_for_heatup) {
453 453
 
454 454
       const millis_t ms = millis();
@@ -632,6 +632,7 @@ volatile bool Temperature::raw_temps_ready = false;
632 632
       }
633 633
       TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update());
634 634
     }
635
+    wait_for_heatup = false;
635 636
 
636 637
     disable_all_heaters();
637 638
 
@@ -3060,10 +3061,10 @@ void Temperature::tick() {
3060 3061
         printerEventLEDs.onHotendHeatingStart();
3061 3062
       #endif
3062 3063
 
3063
-      float target_temp = -1.0, old_temp = 9999.0;
3064 3064
       bool wants_to_cool = false;
3065
-      wait_for_heatup = true;
3065
+      float target_temp = -1.0, old_temp = 9999.0;
3066 3066
       millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
3067
+      wait_for_heatup = true;
3067 3068
       do {
3068 3069
         // Target temperature might be changed during the loop
3069 3070
         if (target_temp != degTargetHotend(target_extruder)) {
@@ -3137,6 +3138,7 @@ void Temperature::tick() {
3137 3138
       } while (wait_for_heatup && TEMP_CONDITIONS);
3138 3139
 
3139 3140
       if (wait_for_heatup) {
3141
+        wait_for_heatup = false;
3140 3142
         #if ENABLED(DWIN_CREALITY_LCD)
3141 3143
           HMI_flag.heat_flag = 0;
3142 3144
           duration_t elapsed = print_job_timer.duration();  // print timer
@@ -3145,9 +3147,10 @@ void Temperature::tick() {
3145 3147
           ui.reset_status();
3146 3148
         #endif
3147 3149
         TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onHeatingDone());
3150
+        return true;
3148 3151
       }
3149 3152
 
3150
-      return wait_for_heatup;
3153
+      return false;
3151 3154
     }
3152 3155
 
3153 3156
   #endif // HAS_TEMP_HOTEND
@@ -3176,11 +3179,6 @@ void Temperature::tick() {
3176 3179
         #define TEMP_BED_CONDITIONS (wants_to_cool ? isCoolingBed() : isHeatingBed())
3177 3180
       #endif
3178 3181
 
3179
-      float target_temp = -1, old_temp = 9999;
3180
-      bool wants_to_cool = false;
3181
-      wait_for_heatup = true;
3182
-      millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
3183
-
3184 3182
       #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
3185 3183
         KEEPALIVE_STATE(NOT_BUSY);
3186 3184
       #endif
@@ -3190,6 +3188,10 @@ void Temperature::tick() {
3190 3188
         printerEventLEDs.onBedHeatingStart();
3191 3189
       #endif
3192 3190
 
3191
+      bool wants_to_cool = false;
3192
+      float target_temp = -1, old_temp = 9999;
3193
+      millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
3194
+      wait_for_heatup = true;
3193 3195
       do {
3194 3196
         // Target temperature might be changed during the loop
3195 3197
         if (target_temp != degTargetBed()) {
@@ -3264,9 +3266,13 @@ void Temperature::tick() {
3264 3266
 
3265 3267
       } while (wait_for_heatup && TEMP_BED_CONDITIONS);
3266 3268
 
3267
-      if (wait_for_heatup) ui.reset_status();
3269
+      if (wait_for_heatup) {
3270
+        wait_for_heatup = false;
3271
+        ui.reset_status();
3272
+        return true;
3273
+      }
3268 3274
 
3269
-      return wait_for_heatup;
3275
+      return false;
3270 3276
     }
3271 3277
 
3272 3278
     void Temperature::wait_for_bed_heating() {
@@ -3280,6 +3286,77 @@ void Temperature::tick() {
3280 3286
 
3281 3287
   #endif // HAS_HEATED_BED
3282 3288
 
3289
+  #if HAS_TEMP_PROBE
3290
+
3291
+    #ifndef MIN_DELTA_SLOPE_DEG_PROBE
3292
+      #define MIN_DELTA_SLOPE_DEG_PROBE 1.0
3293
+    #endif
3294
+    #ifndef MIN_DELTA_SLOPE_TIME_PROBE
3295
+      #define MIN_DELTA_SLOPE_TIME_PROBE 600
3296
+    #endif
3297
+
3298
+    bool Temperature::wait_for_probe(const float target_temp, bool no_wait_for_cooling/*=true*/) {
3299
+
3300
+      const bool wants_to_cool = isProbeAboveTemp(target_temp);
3301
+      const bool will_wait = !(wants_to_cool && no_wait_for_cooling);
3302
+      if (will_wait)
3303
+        SERIAL_ECHOLNPAIR("Waiting for probe to ", (wants_to_cool ? PSTR("cool down") : PSTR("heat up")), " to ", target_temp, " degrees.");
3304
+
3305
+      #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
3306
+        KEEPALIVE_STATE(NOT_BUSY);
3307
+      #endif
3308
+
3309
+      float old_temp = 9999;
3310
+      millis_t next_temp_ms = 0, next_delta_check_ms = 0;
3311
+      wait_for_heatup = true;
3312
+      while (will_wait && wait_for_heatup) {
3313
+
3314
+        // Print Temp Reading every 10 seconds while heating up.
3315
+        millis_t now = millis();
3316
+        if (!next_temp_ms || ELAPSED(now, next_temp_ms)) {
3317
+          next_temp_ms = now + 10000UL;
3318
+          print_heater_states(active_extruder);
3319
+          SERIAL_EOL();
3320
+        }
3321
+
3322
+        idle();
3323
+        gcode.reset_stepper_timeout(); // Keep steppers powered
3324
+
3325
+        // Break after MIN_DELTA_SLOPE_TIME_PROBE seconds if the temperature
3326
+        // did not drop at least MIN_DELTA_SLOPE_DEG_PROBE. This avoids waiting
3327
+        // forever as the probe is not actively heated.
3328
+        if (!next_delta_check_ms || ELAPSED(now, next_delta_check_ms)) {
3329
+          const float temp = degProbe(),
3330
+                      delta_temp = old_temp > temp ? old_temp - temp : temp - old_temp;
3331
+          if (delta_temp < float(MIN_DELTA_SLOPE_DEG_PROBE)) {
3332
+            SERIAL_ECHOLNPGM("Timed out waiting for probe temperature.");
3333
+            break;
3334
+          }
3335
+          next_delta_check_ms = now + 1000UL * MIN_DELTA_SLOPE_TIME_PROBE;
3336
+          old_temp = temp;
3337
+        }
3338
+
3339
+        // Loop until the temperature is very close target
3340
+        if (!(wants_to_cool ? isProbeAboveTemp(target_temp) : isProbeBelowTemp(target_temp))) {
3341
+            SERIAL_ECHOLN(wants_to_cool ? PSTR("Cooldown") : PSTR("Heatup"));
3342
+            SERIAL_ECHOLNPGM(" complete, target probe temperature reached.");
3343
+            break;
3344
+        }
3345
+      }
3346
+
3347
+      if (wait_for_heatup) {
3348
+        wait_for_heatup = false;
3349
+        ui.reset_status();
3350
+        return true;
3351
+      }
3352
+      else if (will_wait)
3353
+        SERIAL_ECHOLNPGM("Canceled wait for probe temperature.");
3354
+
3355
+      return false;
3356
+    }
3357
+
3358
+  #endif // HAS_TEMP_PROBE
3359
+
3283 3360
   #if HAS_HEATED_CHAMBER
3284 3361
 
3285 3362
     #ifndef MIN_COOLING_SLOPE_DEG_CHAMBER
@@ -3300,15 +3377,14 @@ void Temperature::tick() {
3300 3377
         #define TEMP_CHAMBER_CONDITIONS (wants_to_cool ? isCoolingChamber() : isHeatingChamber())
3301 3378
       #endif
3302 3379
 
3303
-      float target_temp = -1, old_temp = 9999;
3304
-      bool wants_to_cool = false;
3305
-      wait_for_heatup = true;
3306
-      millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
3307
-
3308 3380
       #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
3309 3381
         KEEPALIVE_STATE(NOT_BUSY);
3310 3382
       #endif
3311 3383
 
3384
+      bool wants_to_cool = false;
3385
+      float target_temp = -1, old_temp = 9999;
3386
+      millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
3387
+      wait_for_heatup = true;
3312 3388
       do {
3313 3389
         // Target temperature might be changed during the loop
3314 3390
         if (target_temp != degTargetChamber()) {
@@ -3367,9 +3443,13 @@ void Temperature::tick() {
3367 3443
         }
3368 3444
       } while (wait_for_heatup && TEMP_CHAMBER_CONDITIONS);
3369 3445
 
3370
-      if (wait_for_heatup) ui.reset_status();
3446
+      if (wait_for_heatup) {
3447
+        wait_for_heatup = false;
3448
+        ui.reset_status();
3449
+        return true;
3450
+      }
3371 3451
 
3372
-      return wait_for_heatup;
3452
+      return false;
3373 3453
     }
3374 3454
 
3375 3455
   #endif // HAS_HEATED_CHAMBER

+ 3
- 0
Marlin/src/module/temperature.h View File

@@ -654,6 +654,9 @@ class Temperature {
654 654
         FORCE_INLINE static int16_t rawProbeTemp()    { return temp_probe.raw; }
655 655
       #endif
656 656
       FORCE_INLINE static float degProbe()            { return temp_probe.celsius; }
657
+      FORCE_INLINE static bool isProbeBelowTemp(const float target_temp) { return temp_probe.celsius < target_temp; }
658
+      FORCE_INLINE static bool isProbeAboveTemp(const float target_temp) { return temp_probe.celsius > target_temp; }
659
+      static bool wait_for_probe(const float target_temp, bool no_wait_for_cooling=true);
657 660
     #endif
658 661
 
659 662
     #if WATCH_PROBE

Loading…
Cancel
Save