Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M81 - Conditional Delays #23396

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power

//#define POWER_OFF_TIMER // Enable M81 D<seconds> to power off after a delay
//#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown

//#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on)
//#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off)

Expand All @@ -384,12 +387,14 @@
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
#define AUTO_POWER_COOLER_FAN
//#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU if any extruder is over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU if the chamber is over this temperature
//#define AUTO_POWER_COOLER_TEMP 26 // (°C) Turn on PSU if the cooler is over this temperature
#define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration
//#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#endif
#if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN)
//#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) PSU on if the chamber is over this temperature
//#define AUTO_POWER_COOLER_TEMP 26 // (°C) PSU on if the cooler is over this temperature
#endif
#endif

//===========================================================================
Expand Down
4 changes: 4 additions & 0 deletions Marlin/src/MarlinCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,10 @@ void loop() {

queue.advance();

#if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
powerManager.checkAutoPowerOff();
#endif

endstops.event_handler();

TERN_(HAS_TFT_LVGL_UI, printer_state_polling());
Expand Down
70 changes: 55 additions & 15 deletions Marlin/src/feature/power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
#include "../inc/MarlinConfig.h"

#include "power.h"
#include "../module/planner.h"
#include "../module/stepper.h"
#include "../module/temperature.h"
#include "../MarlinCore.h"

#if ENABLED(PS_OFF_SOUND)
Expand Down Expand Up @@ -75,6 +77,10 @@ void Power::power_on() {

if (psu_on) return;

#if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
cancelAutoPowerOff();
#endif

OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_STATE);
psu_on = true;
safe_delay(PSU_POWERUP_DELAY);
Expand All @@ -89,7 +95,6 @@ void Power::power_on() {
/**
* Power off if the power is currently on.
* Processes any PSU_POWEROFF_GCODE and makes a PS_OFF_SOUND if enabled.
*
*/
void Power::power_off() {
if (!psu_on) return;
Expand All @@ -104,8 +109,56 @@ void Power::power_off() {

OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_STATE);
psu_on = false;

#if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
cancelAutoPowerOff();
#endif
}

#if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN)

bool Power::is_cooling_needed() {
#if HAS_HOTEND && AUTO_POWER_E_TEMP
HOTEND_LOOP() if (thermalManager.degHotend(e) >= (AUTO_POWER_E_TEMP)) return true;
#endif

#if HAS_HEATED_CHAMBER && AUTO_POWER_CHAMBER_TEMP
if (thermalManager.degChamber() >= (AUTO_POWER_CHAMBER_TEMP)) return true;
#endif

#if HAS_COOLER && AUTO_POWER_COOLER_TEMP
if (thermalManager.degCooler() >= (AUTO_POWER_COOLER_TEMP)) return true;
#endif

return false;
}

#endif

#if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)

#if ENABLED(POWER_OFF_TIMER)
millis_t Power::power_off_time = 0;
void Power::setPowerOffTimer(const millis_t delay_ms) { power_off_time = millis() + delay_ms; }
#endif

#if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
bool Power::power_off_on_cooldown = false;
void Power::setPowerOffOnCooldown(const bool ena) { power_off_on_cooldown = ena; }
#endif

void Power::cancelAutoPowerOff() {
TERN_(POWER_OFF_TIMER, power_off_time = 0);
TERN_(POWER_OFF_WAIT_FOR_COOLDOWN, power_off_on_cooldown = false);
}

void Power::checkAutoPowerOff() {
if (TERN0(POWER_OFF_WAIT_FOR_COOLDOWN, power_off_on_cooldown && is_cooling_needed())) return;
if (TERN0(POWER_OFF_TIMER, power_off_time && PENDING(millis(), power_off_time))) return;
power_off();
}

#endif // POWER_OFF_TIMER || POWER_OFF_WAIT_FOR_COOLDOWN

#if ENABLED(AUTO_POWER_CONTROL)

Expand Down Expand Up @@ -149,19 +202,7 @@ void Power::power_off() {

if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true;

#if HAS_HOTEND && AUTO_POWER_E_TEMP
HOTEND_LOOP() if (thermalManager.degHotend(e) >= (AUTO_POWER_E_TEMP)) return true;
#endif

#if HAS_HEATED_CHAMBER && AUTO_POWER_CHAMBER_TEMP
if (thermalManager.degChamber() >= (AUTO_POWER_CHAMBER_TEMP)) return true;
#endif

#if HAS_COOLER && AUTO_POWER_COOLER_TEMP
if (thermalManager.degCooler() >= (AUTO_POWER_COOLER_TEMP)) return true;
#endif

return false;
return is_cooling_needed();
}

/**
Expand Down Expand Up @@ -193,7 +234,6 @@ void Power::power_off() {

/**
* Power off with a delay. Power off is triggered by check() after the delay.
*
*/
void Power::power_off_soon() {
lastPowerOn = millis() - SEC_TO_MS(POWER_TIMEOUT) + SEC_TO_MS(POWER_OFF_DELAY);
Expand Down
40 changes: 28 additions & 12 deletions Marlin/src/feature/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,37 @@ class Power {
static void init();
static void power_on();
static void power_off();

#if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN)
#if ENABLED(POWER_OFF_TIMER)
static millis_t power_off_time;
static void setPowerOffTimer(const millis_t delay_ms);
#endif
#if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
static bool power_off_on_cooldown;
static void setPowerOffOnCooldown(const bool ena);
#endif
static void cancelAutoPowerOff();
static void checkAutoPowerOff();
#endif

#if ENABLED(AUTO_POWER_CONTROL) && POWER_OFF_DELAY > 0
static void power_off_soon();
#else
static void power_off_soon() { power_off(); }
#endif
#if ENABLED(AUTO_POWER_CONTROL) && POWER_OFF_DELAY > 0
static void power_off_soon();
#else
static void power_off_soon() { power_off(); }
#endif

#if ENABLED(AUTO_POWER_CONTROL)
static void check(const bool pause);
#if ENABLED(AUTO_POWER_CONTROL)
static void check(const bool pause);

private:
static millis_t lastPowerOn;
static bool is_power_needed();

#endif
private:
static millis_t lastPowerOn;
static bool is_power_needed();
static bool is_cooling_needed();
#elif ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
private:
static bool is_cooling_needed();
#endif
};

extern Power powerManager;
30 changes: 23 additions & 7 deletions Marlin/src/gcode/control/M80_M81.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,36 @@ void GcodeSuite::M81() {

print_job_timer.stop();

#if HAS_FAN
#if ENABLED(PROBING_FANS_OFF)
thermalManager.fans_paused = false;
ZERO(thermalManager.saved_fan_speed);
#endif
#if BOTH(HAS_FAN, PROBING_FANS_OFF)
thermalManager.fans_paused = false;
ZERO(thermalManager.saved_fan_speed);
#endif

LCD_MESSAGE_F(MACHINE_NAME " " STR_OFF ".");

bool delayed_power_off = false;

#if ENABLED(POWER_OFF_TIMER)
if (parser.seenval('D')) {
delayed_power_off = true;
powerManager.setPowerOffTimer(SEC_TO_MS(parser.value_ushort()));
}
#endif

#if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
if (parser.boolval('S')) {
delayed_power_off = true;
powerManager.setPowerOffOnCooldown(true);
}
#endif

if (delayed_power_off) return;

safe_delay(1000); // Wait 1 second before switching off

#if HAS_SUICIDE
suicide();
#elif ENABLED(PSU_CONTROL)
powerManager.power_off_soon();
#endif

LCD_MESSAGE_F(MACHINE_NAME " " STR_OFF ".");
}
2 changes: 2 additions & 0 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -3577,6 +3577,8 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
#error "PSU_CONTROL requires PS_ON_PIN."
#elif POWER_OFF_DELAY < 0
#error "POWER_OFF_DELAY must be a positive value."
#elif ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN) && !(defined(AUTO_POWER_E_TEMP) || defined(AUTO_POWER_CHAMBER_TEMP) || defined(AUTO_POWER_COOLER_TEMP))
#error "POWER_OFF_WAIT_FOR_COOLDOWN requires AUTO_POWER_E_TEMP, AUTO_POWER_CHAMBER_TEMP, and/or AUTO_POWER_COOLER_TEMP."
#endif
#endif

Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/lcd/e3v2/enhanced/dwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ void Popup_window_PauseOrStop() {
Draw_Select_Highlight(true);
DWIN_UpdateLCD();
}
else
else
DWIN_Popup_ConfirmCancel(ICON_BLTouch, select_print.now == PRINT_PAUSE_RESUME ? GET_TEXT_F(MSG_PAUSE_PRINT) : GET_TEXT_F(MSG_STOP_PRINT));
}

Expand Down Expand Up @@ -2015,7 +2015,7 @@ void HMI_LockScreen() {
#endif

//=============================================================================
// NEW MENU SUBSYSTEM
// NEW MENU SUBSYSTEM
//=============================================================================

// On click functions
Expand Down
7 changes: 6 additions & 1 deletion Marlin/src/module/temperature.h
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,12 @@ class Temperature {
static int16_t read_max_tc(TERN_(HAS_MULTI_MAX_TC, const uint8_t hindex=0));
#endif

static void update_autofans();
thinkyhead marked this conversation as resolved.
Show resolved Hide resolved
#if HAS_AUTO_FAN
#if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN)
static bool autofans_on;
#endif
static void update_autofans();
#endif

#if HAS_HOTEND
static float get_pid_output_hotend(const uint8_t e);
Expand Down
4 changes: 2 additions & 2 deletions buildroot/tests/rambo
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ opt_set MOTHERBOARD BOARD_RAMBO \
EXTRUDERS 2 TEMP_SENSOR_0 -2 TEMP_SENSOR_1 1 TEMP_SENSOR_BED 2 \
TEMP_SENSOR_PROBE 1 TEMP_PROBE_PIN 12 \
TEMP_SENSOR_CHAMBER 3 TEMP_CHAMBER_PIN 3 HEATER_CHAMBER_PIN 45 \
GRID_MAX_POINTS_X 16 \
GRID_MAX_POINTS_X 16 AUTO_POWER_E_TEMP 80 \
FANMUX0_PIN 53
opt_disable Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN USE_WATCHDOG
opt_enable USE_ZMAX_PLUG REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_PROGRESS_BAR_TEST \
Expand All @@ -32,7 +32,7 @@ opt_enable USE_ZMAX_PLUG REPRAP_DISCOUNT_SMART_CONTROLLER LCD_PROGRESS_BAR LCD_P
SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE \
BACKLASH_COMPENSATION BACKLASH_GCODE BAUD_RATE_GCODE BEZIER_CURVE_SUPPORT \
FWRETRACT ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS \
PSU_CONTROL PS_OFF_CONFIRM PS_OFF_SOUND AUTO_POWER_CONTROL \
PSU_CONTROL PS_OFF_CONFIRM PS_OFF_SOUND POWER_OFF_WAIT_FOR_COOLDOWN \
POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE POWER_LOSS_RECOVER_ZHOME POWER_LOSS_ZHOME_POS \
SLOW_PWM_HEATERS THERMAL_PROTECTION_CHAMBER LIN_ADVANCE EXTRA_LIN_ADVANCE_K \
HOST_ACTION_COMMANDS HOST_PROMPT_SUPPORT PINS_DEBUGGING MAX7219_DEBUG M114_DETAIL
Expand Down