Browse Source

✨ M81 D / S - Power-off Delay (#23396)

John Lagonikas 2 years ago
parent
commit
9a194826e3
No account linked to committer's email address

+ 8
- 3
Marlin/Configuration.h View File

374
   //#define PSU_DEFAULT_OFF         // Keep power off until enabled directly with M80
374
   //#define PSU_DEFAULT_OFF         // Keep power off until enabled directly with M80
375
   //#define PSU_POWERUP_DELAY 250   // (ms) Delay for the PSU to warm up to full power
375
   //#define PSU_POWERUP_DELAY 250   // (ms) Delay for the PSU to warm up to full power
376
 
376
 
377
+  //#define POWER_OFF_TIMER               // Enable M81 D<seconds> to power off after a delay
378
+  //#define POWER_OFF_WAIT_FOR_COOLDOWN   // Enable M81 S to power off only after cooldown
379
+
377
   //#define PSU_POWERUP_GCODE  "M355 S1"  // G-code to run after power-on (e.g., case light on)
380
   //#define PSU_POWERUP_GCODE  "M355 S1"  // G-code to run after power-on (e.g., case light on)
378
   //#define PSU_POWEROFF_GCODE "M355 S0"  // G-code to run before power-off (e.g., case light off)
381
   //#define PSU_POWEROFF_GCODE "M355 S0"  // G-code to run before power-off (e.g., case light off)
379
 
382
 
384
     #define AUTO_POWER_CONTROLLERFAN
387
     #define AUTO_POWER_CONTROLLERFAN
385
     #define AUTO_POWER_CHAMBER_FAN
388
     #define AUTO_POWER_CHAMBER_FAN
386
     #define AUTO_POWER_COOLER_FAN
389
     #define AUTO_POWER_COOLER_FAN
387
-    //#define AUTO_POWER_E_TEMP        50 // (°C) Turn on PSU if any extruder is over this temperature
388
-    //#define AUTO_POWER_CHAMBER_TEMP  30 // (°C) Turn on PSU if the chamber is over this temperature
389
-    //#define AUTO_POWER_COOLER_TEMP   26 // (°C) Turn on PSU if the cooler is over this temperature
390
     #define POWER_TIMEOUT              30 // (s) Turn off power if the machine is idle for this duration
390
     #define POWER_TIMEOUT              30 // (s) Turn off power if the machine is idle for this duration
391
     //#define POWER_OFF_DELAY          60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
391
     //#define POWER_OFF_DELAY          60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
392
   #endif
392
   #endif
393
+  #if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN) 
394
+    //#define AUTO_POWER_E_TEMP        50 // (°C) PSU on if any extruder is over this temperature
395
+    //#define AUTO_POWER_CHAMBER_TEMP  30 // (°C) PSU on if the chamber is over this temperature
396
+    //#define AUTO_POWER_COOLER_TEMP   26 // (°C) PSU on if the cooler is over this temperature
397
+  #endif
393
 #endif
398
 #endif
394
 
399
 
395
 //===========================================================================
400
 //===========================================================================

+ 4
- 0
Marlin/src/MarlinCore.cpp View File

1652
 
1652
 
1653
     queue.advance();
1653
     queue.advance();
1654
 
1654
 
1655
+    #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
1656
+      powerManager.checkAutoPowerOff();
1657
+    #endif
1658
+
1655
     endstops.event_handler();
1659
     endstops.event_handler();
1656
 
1660
 
1657
     TERN_(HAS_TFT_LVGL_UI, printer_state_polling());
1661
     TERN_(HAS_TFT_LVGL_UI, printer_state_polling());

+ 55
- 15
Marlin/src/feature/power.cpp View File

27
 #include "../inc/MarlinConfig.h"
27
 #include "../inc/MarlinConfig.h"
28
 
28
 
29
 #include "power.h"
29
 #include "power.h"
30
+#include "../module/planner.h"
30
 #include "../module/stepper.h"
31
 #include "../module/stepper.h"
32
+#include "../module/temperature.h"
31
 #include "../MarlinCore.h"
33
 #include "../MarlinCore.h"
32
 
34
 
33
 #if ENABLED(PS_OFF_SOUND)
35
 #if ENABLED(PS_OFF_SOUND)
75
 
77
 
76
   if (psu_on) return;
78
   if (psu_on) return;
77
 
79
 
80
+  #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
81
+    cancelAutoPowerOff();
82
+  #endif
83
+
78
   OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_STATE);
84
   OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_STATE);
79
   psu_on = true;
85
   psu_on = true;
80
   safe_delay(PSU_POWERUP_DELAY);
86
   safe_delay(PSU_POWERUP_DELAY);
89
 /**
95
 /**
90
  * Power off if the power is currently on.
96
  * Power off if the power is currently on.
91
  * Processes any PSU_POWEROFF_GCODE and makes a PS_OFF_SOUND if enabled.
97
  * Processes any PSU_POWEROFF_GCODE and makes a PS_OFF_SOUND if enabled.
92
- *
93
  */
98
  */
94
 void Power::power_off() {
99
 void Power::power_off() {
95
   if (!psu_on) return;
100
   if (!psu_on) return;
104
 
109
 
105
   OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_STATE);
110
   OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_STATE);
106
   psu_on = false;
111
   psu_on = false;
112
+
113
+  #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
114
+    cancelAutoPowerOff();
115
+  #endif
107
 }
116
 }
108
 
117
 
118
+#if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN)
119
+
120
+  bool Power::is_cooling_needed() {
121
+    #if HAS_HOTEND && AUTO_POWER_E_TEMP
122
+      HOTEND_LOOP() if (thermalManager.degHotend(e) >= (AUTO_POWER_E_TEMP)) return true;
123
+    #endif
124
+
125
+    #if HAS_HEATED_CHAMBER && AUTO_POWER_CHAMBER_TEMP
126
+      if (thermalManager.degChamber() >= (AUTO_POWER_CHAMBER_TEMP)) return true;
127
+    #endif
128
+
129
+    #if HAS_COOLER && AUTO_POWER_COOLER_TEMP
130
+      if (thermalManager.degCooler() >= (AUTO_POWER_COOLER_TEMP)) return true;
131
+    #endif
132
+
133
+    return false;
134
+  }
135
+
136
+#endif
137
+
138
+#if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
139
+
140
+  #if ENABLED(POWER_OFF_TIMER)
141
+    millis_t Power::power_off_time = 0;
142
+    void Power::setPowerOffTimer(const millis_t delay_ms) { power_off_time = millis() + delay_ms; }
143
+  #endif
144
+
145
+  #if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
146
+    bool Power::power_off_on_cooldown = false;
147
+    void Power::setPowerOffOnCooldown(const bool ena) { power_off_on_cooldown = ena; }
148
+  #endif
149
+
150
+  void Power::cancelAutoPowerOff() {
151
+    TERN_(POWER_OFF_TIMER, power_off_time = 0);
152
+    TERN_(POWER_OFF_WAIT_FOR_COOLDOWN, power_off_on_cooldown = false);
153
+  }
154
+
155
+  void Power::checkAutoPowerOff() {
156
+    if (TERN0(POWER_OFF_WAIT_FOR_COOLDOWN, power_off_on_cooldown && is_cooling_needed())) return;
157
+    if (TERN0(POWER_OFF_TIMER, power_off_time && PENDING(millis(), power_off_time))) return;
158
+    power_off();
159
+  }
160
+
161
+#endif // POWER_OFF_TIMER || POWER_OFF_WAIT_FOR_COOLDOWN
109
 
162
 
110
 #if ENABLED(AUTO_POWER_CONTROL)
163
 #if ENABLED(AUTO_POWER_CONTROL)
111
 
164
 
149
 
202
 
150
     if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true;
203
     if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true;
151
 
204
 
152
-    #if HAS_HOTEND && AUTO_POWER_E_TEMP
153
-      HOTEND_LOOP() if (thermalManager.degHotend(e) >= (AUTO_POWER_E_TEMP)) return true;
154
-    #endif
155
-
156
-    #if HAS_HEATED_CHAMBER && AUTO_POWER_CHAMBER_TEMP
157
-      if (thermalManager.degChamber() >= (AUTO_POWER_CHAMBER_TEMP)) return true;
158
-    #endif
159
-
160
-    #if HAS_COOLER && AUTO_POWER_COOLER_TEMP
161
-      if (thermalManager.degCooler() >= (AUTO_POWER_COOLER_TEMP)) return true;
162
-    #endif
163
-
164
-    return false;
205
+    return is_cooling_needed();
165
   }
206
   }
166
 
207
 
167
   /**
208
   /**
193
 
234
 
194
     /**
235
     /**
195
      * Power off with a delay. Power off is triggered by check() after the delay.
236
      * Power off with a delay. Power off is triggered by check() after the delay.
196
-     *
197
      */
237
      */
198
     void Power::power_off_soon() {
238
     void Power::power_off_soon() {
199
       lastPowerOn = millis() - SEC_TO_MS(POWER_TIMEOUT) + SEC_TO_MS(POWER_OFF_DELAY);
239
       lastPowerOn = millis() - SEC_TO_MS(POWER_TIMEOUT) + SEC_TO_MS(POWER_OFF_DELAY);

+ 28
- 12
Marlin/src/feature/power.h View File

36
     static void init();
36
     static void init();
37
     static void power_on();
37
     static void power_on();
38
     static void power_off();
38
     static void power_off();
39
+    
40
+    #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
41
+      #if ENABLED(POWER_OFF_TIMER)
42
+        static millis_t power_off_time;
43
+        static void setPowerOffTimer(const millis_t delay_ms);
44
+      #endif
45
+      #if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
46
+        static bool power_off_on_cooldown;
47
+        static void setPowerOffOnCooldown(const bool ena);
48
+      #endif
49
+      static void cancelAutoPowerOff();
50
+      static void checkAutoPowerOff();
51
+    #endif
39
 
52
 
40
-  #if ENABLED(AUTO_POWER_CONTROL) && POWER_OFF_DELAY > 0
41
-    static void power_off_soon();
42
-  #else
43
-    static void power_off_soon() { power_off(); }
44
-  #endif
53
+    #if ENABLED(AUTO_POWER_CONTROL) && POWER_OFF_DELAY > 0
54
+      static void power_off_soon();
55
+    #else
56
+      static void power_off_soon() { power_off(); }
57
+    #endif
45
 
58
 
46
-  #if ENABLED(AUTO_POWER_CONTROL)
47
-    static void check(const bool pause);
59
+    #if ENABLED(AUTO_POWER_CONTROL)
60
+      static void check(const bool pause);
48
 
61
 
49
-    private:
50
-      static millis_t lastPowerOn;
51
-      static bool is_power_needed();
52
-
53
-  #endif
62
+      private:
63
+        static millis_t lastPowerOn;
64
+        static bool is_power_needed();
65
+        static bool is_cooling_needed();
66
+    #elif ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
67
+      private:
68
+        static bool is_cooling_needed();
69
+    #endif
54
 };
70
 };
55
 
71
 
56
 extern Power powerManager;
72
 extern Power powerManager;

+ 23
- 7
Marlin/src/gcode/control/M80_M81.cpp View File

79
 
79
 
80
   print_job_timer.stop();
80
   print_job_timer.stop();
81
 
81
 
82
-  #if HAS_FAN
83
-    #if ENABLED(PROBING_FANS_OFF)
84
-      thermalManager.fans_paused = false;
85
-      ZERO(thermalManager.saved_fan_speed);
86
-    #endif
82
+  #if BOTH(HAS_FAN, PROBING_FANS_OFF)
83
+    thermalManager.fans_paused = false;
84
+    ZERO(thermalManager.saved_fan_speed);
85
+  #endif
86
+
87
+  LCD_MESSAGE_F(MACHINE_NAME " " STR_OFF ".");
88
+
89
+  bool delayed_power_off = false;
90
+
91
+  #if ENABLED(POWER_OFF_TIMER)
92
+    if (parser.seenval('D')) {
93
+      delayed_power_off = true;
94
+      powerManager.setPowerOffTimer(SEC_TO_MS(parser.value_ushort()));
95
+    }
87
   #endif
96
   #endif
88
 
97
 
98
+  #if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
99
+    if (parser.boolval('S')) {
100
+      delayed_power_off = true;
101
+      powerManager.setPowerOffOnCooldown(true);
102
+    }
103
+  #endif
104
+
105
+  if (delayed_power_off) return;
106
+
89
   safe_delay(1000); // Wait 1 second before switching off
107
   safe_delay(1000); // Wait 1 second before switching off
90
 
108
 
91
   #if HAS_SUICIDE
109
   #if HAS_SUICIDE
93
   #elif ENABLED(PSU_CONTROL)
111
   #elif ENABLED(PSU_CONTROL)
94
     powerManager.power_off_soon();
112
     powerManager.power_off_soon();
95
   #endif
113
   #endif
96
-
97
-  LCD_MESSAGE_F(MACHINE_NAME " " STR_OFF ".");
98
 }
114
 }

+ 2
- 0
Marlin/src/inc/SanityCheck.h View File

3577
     #error "PSU_CONTROL requires PS_ON_PIN."
3577
     #error "PSU_CONTROL requires PS_ON_PIN."
3578
   #elif POWER_OFF_DELAY < 0
3578
   #elif POWER_OFF_DELAY < 0
3579
     #error "POWER_OFF_DELAY must be a positive value."
3579
     #error "POWER_OFF_DELAY must be a positive value."
3580
+  #elif ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN) && !(defined(AUTO_POWER_E_TEMP) || defined(AUTO_POWER_CHAMBER_TEMP) || defined(AUTO_POWER_COOLER_TEMP))
3581
+    #error "POWER_OFF_WAIT_FOR_COOLDOWN requires AUTO_POWER_E_TEMP, AUTO_POWER_CHAMBER_TEMP, and/or AUTO_POWER_COOLER_TEMP."
3580
   #endif
3582
   #endif
3581
 #endif
3583
 #endif
3582
 
3584
 

+ 2
- 2
Marlin/src/lcd/e3v2/enhanced/dwin.cpp View File

481
     Draw_Select_Highlight(true);
481
     Draw_Select_Highlight(true);
482
   DWIN_UpdateLCD();
482
   DWIN_UpdateLCD();
483
   }
483
   }
484
-  else 
484
+  else
485
     DWIN_Popup_ConfirmCancel(ICON_BLTouch, select_print.now == PRINT_PAUSE_RESUME ? GET_TEXT_F(MSG_PAUSE_PRINT) : GET_TEXT_F(MSG_STOP_PRINT));
485
     DWIN_Popup_ConfirmCancel(ICON_BLTouch, select_print.now == PRINT_PAUSE_RESUME ? GET_TEXT_F(MSG_PAUSE_PRINT) : GET_TEXT_F(MSG_STOP_PRINT));
486
 }
486
 }
487
 
487
 
2015
 #endif
2015
 #endif
2016
 
2016
 
2017
 //=============================================================================
2017
 //=============================================================================
2018
-// NEW MENU SUBSYSTEM 
2018
+// NEW MENU SUBSYSTEM
2019
 //=============================================================================
2019
 //=============================================================================
2020
 
2020
 
2021
 // On click functions
2021
 // On click functions

+ 6
- 1
Marlin/src/module/temperature.h View File

993
       static int16_t read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex=0));
993
       static int16_t read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex=0));
994
     #endif
994
     #endif
995
 
995
 
996
-    static void update_autofans();
996
+    #if HAS_AUTO_FAN
997
+      #if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
998
+        static bool autofans_on;
999
+      #endif
1000
+      static void update_autofans();
1001
+    #endif
997
 
1002
 
998
     #if HAS_HOTEND
1003
     #if HAS_HOTEND
999
       static float get_pid_output_hotend(const uint8_t e);
1004
       static float get_pid_output_hotend(const uint8_t e);

+ 2
- 2
buildroot/tests/rambo View File

14
         EXTRUDERS 2 TEMP_SENSOR_0 -2 TEMP_SENSOR_1 1 TEMP_SENSOR_BED 2 \
14
         EXTRUDERS 2 TEMP_SENSOR_0 -2 TEMP_SENSOR_1 1 TEMP_SENSOR_BED 2 \
15
         TEMP_SENSOR_PROBE 1 TEMP_PROBE_PIN 12 \
15
         TEMP_SENSOR_PROBE 1 TEMP_PROBE_PIN 12 \
16
         TEMP_SENSOR_CHAMBER 3 TEMP_CHAMBER_PIN 3 HEATER_CHAMBER_PIN 45 \
16
         TEMP_SENSOR_CHAMBER 3 TEMP_CHAMBER_PIN 3 HEATER_CHAMBER_PIN 45 \
17
-        GRID_MAX_POINTS_X 16 \
17
+        GRID_MAX_POINTS_X 16 AUTO_POWER_E_TEMP 80 \
18
         FANMUX0_PIN 53
18
         FANMUX0_PIN 53
19
 opt_disable Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN USE_WATCHDOG
19
 opt_disable Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN USE_WATCHDOG
20
 opt_enable USE_ZMAX_PLUG REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TEST \
20
 opt_enable USE_ZMAX_PLUG REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TEST \
32
            SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \
32
            SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \
33
            BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \
33
            BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \
34
            FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \
34
            FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \
35
-           PSU_CONTROL PS_OFF_CONFIRM PS_OFF_SOUND AUTO_POWER_CONTROL \
35
+           PSU_CONTROL PS_OFF_CONFIRM PS_OFF_SOUND POWER_OFF_WAIT_FOR_COOLDOWN \
36
            POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE POWER_LOSS_RECOVER_ZHOME POWER_LOSS_ZHOME_POS \
36
            POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE POWER_LOSS_RECOVER_ZHOME POWER_LOSS_ZHOME_POS \
37
            SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER LIN_ADVANCE EXTRA_LIN_ADVANCE_K \
37
            SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER LIN_ADVANCE EXTRA_LIN_ADVANCE_K \
38
            HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL
38
            HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL

Loading…
Cancel
Save