diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 47b42aa8dddb..085c5379a911 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -552,10 +552,14 @@ #endif #endif -// When first starting the main fan, run it at full speed for the -// given number of milliseconds. This gets the fan spinning reliably -// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu) -//#define FAN_KICKSTART_TIME 100 +/** + * Fan Kickstart + * When part cooling or controller fans first start, run at a speed that + * gets it spinning reliably for a short time before setting the requested speed. + * (Does not work on Sanguinololu with FAN_SOFT_PWM.) + */ +//#define FAN_KICKSTART_TIME 100 // (ms) +//#define FAN_KICKSTART_POWER 180 // 64-255 // Some coolers may require a non-zero "off" state. //#define FAN_OFF_PWM 1 diff --git a/Marlin/src/feature/controllerfan.cpp b/Marlin/src/feature/controllerfan.cpp index f42bf52ae40a..2f25832cdc2d 100644 --- a/Marlin/src/feature/controllerfan.cpp +++ b/Marlin/src/feature/controllerfan.cpp @@ -72,6 +72,22 @@ void ControllerFan::update() { ? settings.active_speed : settings.idle_speed ); + speed = CALC_FAN_SPEED(speed); + + #if FAN_KICKSTART_TIME + static millis_t fan_kick_end = 0; + if (speed > FAN_OFF_PWM) { + if (!fan_kick_end) { + fan_kick_end = ms + FAN_KICKSTART_TIME; // May be longer based on slow update interval for controller fn check. Sets minimum + speed = FAN_KICKSTART_POWER; + } + else if (PENDING(ms, fan_kick_end)) + speed = FAN_KICKSTART_POWER; + } + else + fan_kick_end = 0; + #endif + #if ENABLED(FAN_SOFT_PWM) thermalManager.soft_pwm_controller_speed = speed; #else diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index ba8c3587fec0..27185400f951 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -1074,3 +1074,14 @@ #if ANY(DISABLE_INACTIVE_X, DISABLE_INACTIVE_Y, DISABLE_INACTIVE_Z, DISABLE_INACTIVE_I, DISABLE_INACTIVE_J, DISABLE_INACTIVE_K, DISABLE_INACTIVE_U, DISABLE_INACTIVE_V, DISABLE_INACTIVE_W, DISABLE_INACTIVE_E) #define HAS_DISABLE_INACTIVE_AXIS 1 #endif + +// Fan Kickstart +#if FAN_KICKSTART_TIME && !defined(FAN_KICKSTART_POWER) + #define FAN_KICKSTART_POWER 180 +#endif + +#if FAN_MIN_PWM == 0 && FAN_MAX_PWM == 255 + #define CALC_FAN_SPEED(f) (f ?: FAN_OFF_PWM) +#else + #define CALC_FAN_SPEED(f) (f ? map(f, 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : FAN_OFF_PWM) +#endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 02d798543c1f..679463798a1f 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1513,6 +1513,11 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "To use BED_LIMIT_SWITCHING you must disable PIDTEMPBED." #endif +// Fan Kickstart +#if FAN_KICKSTART_TIME && defined(FAN_KICKSTART_POWER) && !WITHIN(FAN_KICKSTART_POWER, 64, 255) + #error "FAN_KICKSTART_POWER must be an integer from 64 to 255." +#endif + /** * Synchronous M106/M107 checks */ diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 91a994470a31..3263e7660a40 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -1282,16 +1282,10 @@ void Planner::recalculate(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t safe_exit_s void Planner::sync_fan_speeds(uint8_t (&fan_speed)[FAN_COUNT]) { - #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255 - #define CALC_FAN_SPEED(f) (fan_speed[f] ? map(fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : FAN_OFF_PWM) - #else - #define CALC_FAN_SPEED(f) (fan_speed[f] ?: FAN_OFF_PWM) - #endif - #if ENABLED(FAN_SOFT_PWM) - #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(F); + #define _FAN_SET(F) thermalManager.soft_pwm_amount_fan[F] = CALC_FAN_SPEED(fan_speed[F]); #else - #define _FAN_SET(F) hal.set_pwm_duty(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(F)); + #define _FAN_SET(F) hal.set_pwm_duty(pin_t(FAN##F##_PIN), CALC_FAN_SPEED(fan_speed[F])); #endif #define FAN_SET(F) do{ kickstart_fan(fan_speed, ms, F); _FAN_SET(F); }while(0) @@ -1306,13 +1300,13 @@ void Planner::recalculate(TERN_(HINTS_SAFE_EXIT_SPEED, const_float_t safe_exit_s void Planner::kickstart_fan(uint8_t (&fan_speed)[FAN_COUNT], const millis_t &ms, const uint8_t f) { static millis_t fan_kick_end[FAN_COUNT] = { 0 }; - if (fan_speed[f]) { + if (fan_speed[f] > FAN_OFF_PWM) { if (fan_kick_end[f] == 0) { fan_kick_end[f] = ms + FAN_KICKSTART_TIME; - fan_speed[f] = 255; + fan_speed[f] = FAN_KICKSTART_POWER; } else if (PENDING(ms, fan_kick_end[f])) - fan_speed[f] = 255; + fan_speed[f] = FAN_KICKSTART_POWER; } else fan_kick_end[f] = 0; diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 349264606aec..7515396fbefb 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -306,19 +306,19 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); #endif #if EITHER(AUTO_POWER_E_FANS, HAS_FANCHECK) - uint8_t Temperature::autofan_speed[HOTENDS]; // = { 0 } + uint8_t Temperature::autofan_speed[HOTENDS] = ARRAY_N_1(HOTENDS, FAN_OFF_PWM); #endif #if ENABLED(AUTO_POWER_CHAMBER_FAN) - uint8_t Temperature::chamberfan_speed; // = 0 + uint8_t Temperature::chamberfan_speed = FAN_OFF_PWM; #endif #if ENABLED(AUTO_POWER_COOLER_FAN) - uint8_t Temperature::coolerfan_speed; // = 0 + uint8_t Temperature::coolerfan_speed = FAN_OFF_PWM; #endif #if BOTH(FAN_SOFT_PWM, USE_CONTROLLER_FAN) - uint8_t Temperature::soft_pwm_controller_speed; + uint8_t Temperature::soft_pwm_controller_speed = FAN_OFF_PWM; #endif // Init fans according to whether they're native PWM or Software PWM @@ -342,11 +342,11 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); // HAS_FAN does not include CONTROLLER_FAN #if HAS_FAN - uint8_t Temperature::fan_speed[FAN_COUNT]; // = { 0 } + uint8_t Temperature::fan_speed[FAN_COUNT] = ARRAY_N_1(FAN_COUNT, FAN_OFF_PWM); #if ENABLED(EXTRA_FAN_SPEED) - Temperature::extra_fan_t Temperature::extra_fan_speed[FAN_COUNT]; + Temperature::extra_fan_t Temperature::extra_fan_speed[FAN_COUNT] = ARRAY_N_1(FAN_COUNT, FAN_OFF_PWM); /** * Handle the M106 P T command: @@ -373,7 +373,7 @@ PGMSTR(str_t_heating_failed, STR_T_HEATING_FAILED); #if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE) bool Temperature::fans_paused; // = false; - uint8_t Temperature::saved_fan_speed[FAN_COUNT]; // = { 0 } + uint8_t Temperature::saved_fan_speed[FAN_COUNT] = ARRAY_N_1(FAN_COUNT, FAN_OFF_PWM); #endif #if ENABLED(ADAPTIVE_FAN_SLOWING) diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 4eb72a5b7d1d..80aedd3bdd87 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -917,7 +917,7 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0. #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed; gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time)); - thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0; + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = FAN_OFF_PWM; #endif }