Skip to content

Commit c8898b5

Browse files
ellenspthinkyhead
andcommitted
✨ Redundant Part Cooling Fan (#21888)
Co-authored-by: Scott Lahteine <[email protected]>
1 parent 781257b commit c8898b5

File tree

6 files changed

+61
-34
lines changed

6 files changed

+61
-34
lines changed

Marlin/Configuration_adv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,11 @@
532532
//#define USE_OCR2A_AS_TOP
533533
#endif
534534

535+
/**
536+
* Use one of the PWM fans as a redundant part-cooling fan
537+
*/
538+
//#define REDUNDANT_PART_COOLING_FAN 2 // Index of the fan to sync with FAN 0.
539+
535540
// @section extruder
536541

537542
/**

Marlin/src/gcode/temp/M106_M107.cpp

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,39 +60,40 @@
6060
*/
6161
void GcodeSuite::M106() {
6262
const uint8_t pfan = parser.byteval('P', _ALT_P);
63+
if (pfan >= _CNT_P) return;
64+
#if REDUNDANT_PART_COOLING_FAN
65+
if (pfan == REDUNDANT_PART_COOLING_FAN) return;
66+
#endif
6367

64-
if (pfan < _CNT_P) {
65-
66-
#if ENABLED(EXTRA_FAN_SPEED)
67-
const uint16_t t = parser.intval('T');
68-
if (t > 0) return thermalManager.set_temp_fan_speed(pfan, t);
69-
#endif
68+
#if ENABLED(EXTRA_FAN_SPEED)
69+
const uint16_t t = parser.intval('T');
70+
if (t > 0) return thermalManager.set_temp_fan_speed(pfan, t);
71+
#endif
7072

71-
const uint16_t dspeed = parser.seen_test('A') ? thermalManager.fan_speed[active_extruder] : 255;
73+
const uint16_t dspeed = parser.seen_test('A') ? thermalManager.fan_speed[active_extruder] : 255;
7274

73-
uint16_t speed = dspeed;
75+
uint16_t speed = dspeed;
7476

75-
// Accept 'I' if temperature presets are defined
76-
#if PREHEAT_COUNT
77-
const bool got_preset = parser.seenval('I');
78-
if (got_preset) speed = ui.material_preset[_MIN(parser.value_byte(), PREHEAT_COUNT - 1)].fan_speed;
79-
#else
80-
constexpr bool got_preset = false;
81-
#endif
77+
// Accept 'I' if temperature presets are defined
78+
#if PREHEAT_COUNT
79+
const bool got_preset = parser.seenval('I');
80+
if (got_preset) speed = ui.material_preset[_MIN(parser.value_byte(), PREHEAT_COUNT - 1)].fan_speed;
81+
#else
82+
constexpr bool got_preset = false;
83+
#endif
8284

83-
if (!got_preset && parser.seenval('S'))
84-
speed = parser.value_ushort();
85+
if (!got_preset && parser.seenval('S'))
86+
speed = parser.value_ushort();
8587

86-
TERN_(FOAMCUTTER_XYUV, speed *= 2.55); // Get command in % of max heat
88+
TERN_(FOAMCUTTER_XYUV, speed *= 2.55); // Get command in % of max heat
8789

88-
// Set speed, with constraint
89-
thermalManager.set_fan_speed(pfan, speed);
90+
// Set speed, with constraint
91+
thermalManager.set_fan_speed(pfan, speed);
9092

91-
TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
93+
TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
9294

93-
if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating())) // pfan == 0 when duplicating
94-
thermalManager.set_fan_speed(1 - pfan, speed);
95-
}
95+
if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating())) // pfan == 0 when duplicating
96+
thermalManager.set_fan_speed(1 - pfan, speed);
9697
}
9798

9899
/**
@@ -101,6 +102,9 @@ void GcodeSuite::M106() {
101102
void GcodeSuite::M107() {
102103
const uint8_t pfan = parser.byteval('P', _ALT_P);
103104
if (pfan >= _CNT_P) return;
105+
#if REDUNDANT_PART_COOLING_FAN
106+
if (pfan == REDUNDANT_PART_COOLING_FAN) return;
107+
#endif
104108

105109
thermalManager.set_fan_speed(pfan, 0);
106110

Marlin/src/inc/SanityCheck.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,6 +1890,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
18901890
#endif
18911891
#endif
18921892

1893+
#ifdef REDUNDANT_PART_COOLING_FAN
1894+
#if FAN_COUNT < 2
1895+
#error "REDUNDANT_PART_COOLING_FAN requires a board with at least two PWM fans."
1896+
#else
1897+
static_assert(WITHIN(REDUNDANT_PART_COOLING_FAN, 1, FAN_COUNT - 1), "REDUNDANT_PART_COOLING_FAN must be between 1 and " STRINGIFY(DECREMENT(FAN_COUNT)) ".");
1898+
#endif
1899+
#endif
1900+
18931901
/**
18941902
* Case Light requirements
18951903
*/

Marlin/src/lcd/menu/menu_temperature.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,14 @@ void Temperature::lcd_preheat(const uint8_t e, const int8_t indh, const int8_t i
5757
if (indb >= 0 && ui.material_preset[indb].bed_temp > 0) setTargetBed(ui.material_preset[indb].bed_temp);
5858
#endif
5959
#if HAS_FAN
60-
if (indh >= 0)
61-
set_fan_speed(active_extruder < (FAN_COUNT) ? active_extruder : 0, ui.material_preset[indh].fan_speed);
60+
if (indh >= 0) {
61+
const uint8_t fan_index = active_extruder < (FAN_COUNT) ? active_extruder : 0;
62+
if (true
63+
#if REDUNDANT_PART_COOLING_FAN
64+
&& fan_index != REDUNDANT_PART_COOLING_FAN
65+
#endif
66+
) set_fan_speed(fan_index, ui.material_preset[indh].fan_speed);
67+
}
6268
#endif
6369
ui.return_to_status();
6470
}
@@ -215,37 +221,37 @@ void menu_temperature() {
215221
#if HAS_FAN0
216222
_FAN_EDIT_ITEMS(0,FIRST_FAN_SPEED);
217223
#endif
218-
#if HAS_FAN1
224+
#if HAS_FAN1 && REDUNDANT_PART_COOLING_FAN != 1
219225
FAN_EDIT_ITEMS(1);
220226
#elif SNFAN(1)
221227
singlenozzle_item(1);
222228
#endif
223-
#if HAS_FAN2
229+
#if HAS_FAN2 && REDUNDANT_PART_COOLING_FAN != 2
224230
FAN_EDIT_ITEMS(2);
225231
#elif SNFAN(2)
226232
singlenozzle_item(2);
227233
#endif
228-
#if HAS_FAN3
234+
#if HAS_FAN3 && REDUNDANT_PART_COOLING_FAN != 3
229235
FAN_EDIT_ITEMS(3);
230236
#elif SNFAN(3)
231237
singlenozzle_item(3);
232238
#endif
233-
#if HAS_FAN4
239+
#if HAS_FAN4 && REDUNDANT_PART_COOLING_FAN != 4
234240
FAN_EDIT_ITEMS(4);
235241
#elif SNFAN(4)
236242
singlenozzle_item(4);
237243
#endif
238-
#if HAS_FAN5
244+
#if HAS_FAN5 && REDUNDANT_PART_COOLING_FAN != 5
239245
FAN_EDIT_ITEMS(5);
240246
#elif SNFAN(5)
241247
singlenozzle_item(5);
242248
#endif
243-
#if HAS_FAN6
249+
#if HAS_FAN6 && REDUNDANT_PART_COOLING_FAN != 6
244250
FAN_EDIT_ITEMS(6);
245251
#elif SNFAN(6)
246252
singlenozzle_item(6);
247253
#endif
248-
#if HAS_FAN7
254+
#if HAS_FAN7 && REDUNDANT_PART_COOLING_FAN != 7
249255
FAN_EDIT_ITEMS(7);
250256
#elif SNFAN(7)
251257
singlenozzle_item(7);

Marlin/src/module/temperature.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY,
333333
if (fan >= FAN_COUNT) return;
334334

335335
fan_speed[fan] = speed;
336+
#if REDUNDANT_PART_COOLING_FAN
337+
if (fan == 0) fan_speed[REDUNDANT_PART_COOLING_FAN] = speed;
338+
#endif
336339

337340
TERN_(REPORT_FAN_CHANGE, report_fan_speed(fan));
338341
}

buildroot/tests/mega2560

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ exec_test $1 $2 "Multiple runout sensors (x5) | Distinct runout states" "$3"
6868
#
6969
restore_configs
7070
opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO MIXING_STEPPERS 5 LCD_LANGUAGE ru \
71-
NUM_RUNOUT_SENSORS E_STEPPERS FIL_RUNOUT2_PIN 16 FIL_RUNOUT3_PIN 17 FIL_RUNOUT4_PIN 4 FIL_RUNOUT5_PIN 5
71+
NUM_RUNOUT_SENSORS E_STEPPERS REDUNDANT_PART_COOLING_FAN 1 \
72+
FIL_RUNOUT2_PIN 16 FIL_RUNOUT3_PIN 17 FIL_RUNOUT4_PIN 4 FIL_RUNOUT5_PIN 5
7273
opt_enable MIXING_EXTRUDER GRADIENT_MIX GRADIENT_VTOOL CR10_STOCKDISPLAY \
7374
USE_CONTROLLER_FAN CONTROLLER_FAN_EDITABLE CONTROLLER_FAN_IGNORE_Z \
7475
FILAMENT_RUNOUT_SENSOR ADVANCED_PAUSE_FEATURE NOZZLE_PARK_FEATURE

0 commit comments

Comments
 (0)