Skip to content

Commit 13b1dcd

Browse files
ladismrkoljvgadreau
authored andcommitted
Add Chamber servo vent, auto fan (MarlinFirmware#19519)
1 parent f8a4700 commit 13b1dcd

File tree

6 files changed

+193
-39
lines changed

6 files changed

+193
-39
lines changed

Marlin/Configuration_adv.h

+35-10
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@
3232
*/
3333
#define CONFIGURATION_ADV_H_VERSION 020007
3434

35-
// @section temperature
36-
3735
//===========================================================================
3836
//============================= Thermal Settings ============================
3937
//===========================================================================
38+
// @section temperature
4039

4140
/**
4241
* Thermocouple sensors are quite sensitive to noise. Any noise induced in
@@ -125,22 +124,48 @@
125124
#define HEATER_BED_INVERTING true
126125
#endif
127126

128-
/**
129-
* Heated Chamber settings
130-
*/
127+
//
128+
// Heated Bed Bang-Bang options
129+
//
130+
#if DISABLED(PIDTEMPBED)
131+
#define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control
132+
#if ENABLED(BED_LIMIT_SWITCHING)
133+
#define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS
134+
#endif
135+
#endif
136+
137+
//
138+
// Heated Chamber options
139+
//
131140
#if TEMP_SENSOR_CHAMBER
132141
#define CHAMBER_MINTEMP 5
133142
#define CHAMBER_MAXTEMP 60
134143
#define TEMP_CHAMBER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target
135144
//#define CHAMBER_LIMIT_SWITCHING
136145
//#define HEATER_CHAMBER_PIN 44 // Chamber heater on/off pin
137146
//#define HEATER_CHAMBER_INVERTING false
138-
#endif
139147

140-
#if DISABLED(PIDTEMPBED)
141-
#define BED_CHECK_INTERVAL 5000 // ms between checks in bang-bang control
142-
#if ENABLED(BED_LIMIT_SWITCHING)
143-
#define BED_HYSTERESIS 2 // Only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS
148+
//#define CHAMBER_FAN // Enable a fan on the chamber
149+
#if ENABLED(CHAMBER_FAN)
150+
#define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve.
151+
#if CHAMBER_FAN_MODE == 0
152+
#define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255)
153+
#elif CHAMBER_FAN_MODE == 1
154+
#define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target
155+
#define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target
156+
#elif CHAMBER_FAN_MODE == 2
157+
#define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255)
158+
#define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target
159+
#endif
160+
#endif
161+
162+
//#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber
163+
#if ENABLED(CHAMBER_VENT)
164+
#define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo
165+
#define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber
166+
#define LOW_EXCESS_HEAT_LIMIT 3
167+
#define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20
168+
#define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5
144169
#endif
145170
#endif
146171

Marlin/src/inc/Conditionals_LCD.h

+1-16
Original file line numberDiff line numberDiff line change
@@ -603,10 +603,6 @@
603603
#define DO_SWITCH_EXTRUDER 1
604604
#endif
605605

606-
#ifdef SWITCHING_NOZZLE_E1_SERVO_NR
607-
#define SWITCHING_NOZZLE_TWO_SERVOS 1
608-
#endif
609-
610606
/**
611607
* Default hotend offsets, if not defined
612608
*/
@@ -657,14 +653,7 @@
657653
#ifndef Z_PROBE_SERVO_NR
658654
#define Z_PROBE_SERVO_NR 0
659655
#endif
660-
#ifndef NUM_SERVOS
661-
#define NUM_SERVOS (Z_PROBE_SERVO_NR + 1)
662-
#endif
663656
#undef DEACTIVATE_SERVOS_AFTER_MOVE
664-
#if NUM_SERVOS == 1
665-
#undef SERVO_DELAY
666-
#define SERVO_DELAY { 50 }
667-
#endif
668657

669658
// Always disable probe pin inverting for BLTouch
670659
#undef Z_MIN_PROBE_ENDSTOP_INVERTING
@@ -675,14 +664,10 @@
675664
#endif
676665
#endif
677666

678-
#ifndef NUM_SERVOS
679-
#define NUM_SERVOS 0
680-
#endif
681-
682667
/**
683668
* Set a flag for a servo probe (or BLTouch)
684669
*/
685-
#if defined(Z_PROBE_SERVO_NR) && Z_PROBE_SERVO_NR >= 0
670+
#ifdef Z_PROBE_SERVO_NR
686671
#define HAS_Z_SERVO_PROBE 1
687672
#endif
688673
#if ANY(HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE)

Marlin/src/inc/Conditionals_adv.h

+45
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,51 @@
2626
* Defines that depend on advanced configuration.
2727
*/
2828

29+
#ifdef SWITCHING_NOZZLE_E1_SERVO_NR
30+
#define SWITCHING_NOZZLE_TWO_SERVOS 1
31+
#endif
32+
33+
// Determine NUM_SERVOS if none was supplied
34+
#ifndef NUM_SERVOS
35+
#define NUM_SERVOS 0
36+
#if ANY(CHAMBER_VENT, HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE)
37+
#if NUM_SERVOS <= Z_PROBE_SERVO_NR
38+
#undef NUM_SERVOS
39+
#define NUM_SERVOS (Z_PROBE_SERVO_NR + 1)
40+
#endif
41+
#if NUM_SERVOS <= CHAMBER_VENT_SERVO_NR
42+
#undef NUM_SERVOS
43+
#define NUM_SERVOS (CHAMBER_VENT_SERVO_NR + 1)
44+
#endif
45+
#if NUM_SERVOS <= SWITCHING_TOOLHEAD_SERVO_NR
46+
#undef NUM_SERVOS
47+
#define NUM_SERVOS (SWITCHING_TOOLHEAD_SERVO_NR + 1)
48+
#endif
49+
#if NUM_SERVOS <= SWITCHING_NOZZLE_SERVO_NR
50+
#undef NUM_SERVOS
51+
#define NUM_SERVOS (SWITCHING_NOZZLE_SERVO_NR + 1)
52+
#endif
53+
#if NUM_SERVOS <= SWITCHING_NOZZLE_E1_SERVO_NR
54+
#undef NUM_SERVOS
55+
#define NUM_SERVOS (SWITCHING_NOZZLE_E1_SERVO_NR + 1)
56+
#endif
57+
#if NUM_SERVOS <= SWITCHING_EXTRUDER_SERVO_NR
58+
#undef NUM_SERVOS
59+
#define NUM_SERVOS (SWITCHING_EXTRUDER_SERVO_NR + 1)
60+
#endif
61+
#if NUM_SERVOS <= SWITCHING_EXTRUDER_E23_SERVO_NR
62+
#undef NUM_SERVOS
63+
#define NUM_SERVOS (SWITCHING_EXTRUDER_E23_SERVO_NR + 1)
64+
#endif
65+
#endif
66+
#endif
67+
68+
// Convenience override for a BLTouch alone
69+
#if ENABLED(BLTOUCH) && NUM_SERVOS == 1
70+
#undef SERVO_DELAY
71+
#define SERVO_DELAY { 50 }
72+
#endif
73+
2974
#if EXTRUDERS == 0
3075
#define NO_VOLUMETRICS
3176
#undef TEMP_SENSOR_0

Marlin/src/inc/SanityCheck.h

+28-4
Original file line numberDiff line numberDiff line change
@@ -1249,8 +1249,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
12491249
* NUM_SERVOS is required for a Z servo probe
12501250
*/
12511251
#if HAS_Z_SERVO_PROBE
1252-
#ifndef NUM_SERVOS
1253-
#error "You must set NUM_SERVOS for a Z servo probe (Z_PROBE_SERVO_NR)."
1252+
#if !NUM_SERVOS
1253+
#error "NUM_SERVOS is required for a Z servo probe (Z_PROBE_SERVO_NR)."
1254+
#elif Z_PROBE_SERVO_NR >= NUM_SERVOS
1255+
#error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS."
12541256
#elif Z_PROBE_SERVO_NR == 0 && !PIN_EXISTS(SERVO0)
12551257
#error "SERVO0_PIN must be defined for your servo or BLTOUCH probe."
12561258
#elif Z_PROBE_SERVO_NR == 1 && !PIN_EXISTS(SERVO1)
@@ -1259,8 +1261,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
12591261
#error "SERVO2_PIN must be defined for your servo or BLTOUCH probe."
12601262
#elif Z_PROBE_SERVO_NR == 3 && !PIN_EXISTS(SERVO3)
12611263
#error "SERVO3_PIN must be defined for your servo or BLTOUCH probe."
1262-
#elif Z_PROBE_SERVO_NR >= NUM_SERVOS
1263-
#error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS."
12641264
#endif
12651265
#endif
12661266

@@ -1807,6 +1807,30 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
18071807
#error "TEMP_SENSOR_CHAMBER requires TEMP_CHAMBER_PIN. Please add it to your configuration."
18081808
#endif
18091809

1810+
#if ENABLED(CHAMBER_FAN) && !(defined(CHAMBER_FAN_MODE) && WITHIN(CHAMBER_FAN_MODE, 0, 2))
1811+
#error "CHAMBER_FAN_MODE must be between 0 and 2. Please update your Configuration_adv.h."
1812+
#endif
1813+
1814+
#if ENABLED(CHAMBER_VENT)
1815+
#ifndef CHAMBER_VENT_SERVO_NR
1816+
#error "CHAMBER_VENT_SERVO_NR is required for CHAMBER SERVO. Update your Configuration_adv.h."
1817+
#elif !NUM_SERVOS
1818+
#error "NUM_SERVOS is required for a Heated Chamber vent servo (CHAMBER_VENT_SERVO_NR)."
1819+
#elif CHAMBER_VENT_SERVO_NR >= NUM_SERVOS
1820+
#error "CHAMBER_VENT_SERVO_NR must be smaller than NUM_SERVOS."
1821+
#elif HAS_Z_SERVO_PROBE && CHAMBER_VENT_SERVO_NR == Z_PROBE_SERVO_NR
1822+
#error "CHAMBER SERVO is already used by BLTOUCH. Please change."
1823+
#elif CHAMBER_VENT_SERVO_NR == 0 && !PIN_EXISTS(SERVO0)
1824+
#error "SERVO0_PIN must be defined for your Heated Chamber vent servo."
1825+
#elif CHAMBER_VENT_SERVO_NR == 1 && !PIN_EXISTS(SERVO1)
1826+
#error "SERVO1_PIN must be defined for your Heated Chamber vent servo."
1827+
#elif CHAMBER_VENT_SERVO_NR == 2 && !PIN_EXISTS(SERVO2)
1828+
#error "SERVO2_PIN must be defined for your Heated Chamber vent servo."
1829+
#elif CHAMBER_VENT_SERVO_NR == 3 && !PIN_EXISTS(SERVO3)
1830+
#error "SERVO3_PIN must be defined for your Heated Chamber vent servo."
1831+
#endif
1832+
#endif
1833+
18101834
#if TEMP_SENSOR_PROBE
18111835
#if !PIN_EXISTS(TEMP_PROBE)
18121836
#error "TEMP_SENSOR_PROBE requires TEMP_PROBE_PIN. Please add it to your configuration."

Marlin/src/module/temperature.cpp

+83-9
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@
111111
#include "../libs/buzzer.h"
112112
#endif
113113

114+
#if HAS_SERVOS
115+
#include "./servo.h"
116+
#endif
114117
#if HOTEND_USES_THERMISTOR
115118
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
116119
static const temp_entry_t* heater_ttbl_map[2] = { HEATER_0_TEMPTABLE, HEATER_1_TEMPTABLE };
@@ -271,6 +274,11 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY,
271274
#if HAS_TEMP_CHAMBER
272275
chamber_info_t Temperature::temp_chamber; // = { 0 }
273276
#if HAS_HEATED_CHAMBER
277+
int16_t fan_chamber_pwm;
278+
bool flag_chamber_off;
279+
bool flag_chamber_excess_heat = false;
280+
millis_t next_cool_check_ms_2 = 0;
281+
float old_temp = 9999;
274282
#ifdef CHAMBER_MINTEMP
275283
int16_t Temperature::mintemp_raw_CHAMBER = HEATER_CHAMBER_RAW_LO_TEMP;
276284
#endif
@@ -1189,18 +1197,84 @@ void Temperature::manage_heater() {
11891197
}
11901198
#endif
11911199

1200+
#if EITHER(CHAMBER_FAN, CHAMBER_VENT)
1201+
if (temp_chamber.target > CHAMBER_MINTEMP) {
1202+
flag_chamber_off = false;
1203+
1204+
#if ENABLED(CHAMBER_FAN)
1205+
#if CHAMBER_FAN_MODE == 0
1206+
fan_chamber_pwm = CHAMBER_FAN_BASE
1207+
#elif CHAMBER_FAN_MODE == 1
1208+
fan_chamber_pwm = temp_chamber.celsius > temp_chamber.target ? CHAMBER_FAN_BASE + ((temp_chamber.celsius - temp_chamber.target) * CHAMBER_FAN_FACTOR ) : 0;
1209+
#elif CHAMBER_FAN_MODE == 2
1210+
fan_chamber_pwm = (CHAMBER_FAN_BASE) + (CHAMBER_FAN_FACTOR) * ABS(temp_chamber.celsius - temp_chamber.target);
1211+
if (temp_chamber.soft_pwm_amount)
1212+
fan_chamber_pwm += (CHAMBER_FAN_FACTOR) * 2;
1213+
#endif
1214+
fan_chamber_pwm = _MIN(225, fan_chamber_pwm);
1215+
thermalManager.set_fan_speed(2, fan_chamber_pwm); // TODO: instead of fan 2, set to chamber fan
1216+
#endif
1217+
1218+
#if ENABLED(CHAMBER_VENT)
1219+
#ifndef MIN_COOLING_SLOPE_TIME_CHAMBER_VENT
1220+
#define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20
1221+
#endif
1222+
#ifndef MIN_COOLING_SLOPE_DEG_CHAMBER_VENT
1223+
#define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5
1224+
#endif
1225+
if( (temp_chamber.celsius - temp_chamber.target >= HIGH_EXCESS_HEAT_LIMIT) && !flag_chamber_excess_heat) {
1226+
// open vent after MIN_COOLING_SLOPE_TIME_CHAMBER_VENT seconds
1227+
// if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_CHAMBER_VENT
1228+
if (next_cool_check_ms_2 == 0 || ELAPSED(ms, next_cool_check_ms_2)) {
1229+
if (old_temp - temp_chamber.celsius < float(MIN_COOLING_SLOPE_DEG_CHAMBER_VENT)) flag_chamber_excess_heat = true; //the bed is heating the chamber too much
1230+
next_cool_check_ms_2 = ms + 1000UL * MIN_COOLING_SLOPE_TIME_CHAMBER_VENT;
1231+
old_temp = temp_chamber.celsius;
1232+
}
1233+
}
1234+
else {
1235+
next_cool_check_ms_2 = 0;
1236+
old_temp = 9999;
1237+
}
1238+
if (flag_chamber_excess_heat && (temp_chamber.celsius - temp_chamber.target <= -LOW_EXCESS_HEAT_LIMIT) ) {
1239+
flag_chamber_excess_heat = false;
1240+
}
1241+
#endif
1242+
}
1243+
else if (!flag_chamber_off) {
1244+
#if ENABLED(CHAMBER_FAN)
1245+
flag_chamber_off = true;
1246+
thermalManager.set_fan_speed(2, 0);
1247+
#endif
1248+
#if ENABLED(CHAMBER_VENT)
1249+
flag_chamber_excess_heat = false;
1250+
MOVE_SERVO(CHAMBER_VENT_SERVO_NR, 90);
1251+
#endif
1252+
}
1253+
#endif
1254+
11921255
if (ELAPSED(ms, next_chamber_check_ms)) {
11931256
next_chamber_check_ms = ms + CHAMBER_CHECK_INTERVAL;
11941257

11951258
if (WITHIN(temp_chamber.celsius, CHAMBER_MINTEMP, CHAMBER_MAXTEMP)) {
1196-
#if ENABLED(CHAMBER_LIMIT_SWITCHING)
1197-
if (temp_chamber.celsius >= temp_chamber.target + TEMP_CHAMBER_HYSTERESIS)
1198-
temp_chamber.soft_pwm_amount = 0;
1199-
else if (temp_chamber.celsius <= temp_chamber.target - (TEMP_CHAMBER_HYSTERESIS))
1200-
temp_chamber.soft_pwm_amount = MAX_CHAMBER_POWER >> 1;
1201-
#else
1202-
temp_chamber.soft_pwm_amount = temp_chamber.celsius < temp_chamber.target ? MAX_CHAMBER_POWER >> 1 : 0;
1203-
#endif
1259+
if (!flag_chamber_excess_heat){
1260+
#if ENABLED(CHAMBER_LIMIT_SWITCHING)
1261+
if (temp_chamber.celsius >= temp_chamber.target + TEMP_CHAMBER_HYSTERESIS)
1262+
temp_chamber.soft_pwm_amount = 0;
1263+
else if (temp_chamber.celsius <= temp_chamber.target - (TEMP_CHAMBER_HYSTERESIS))
1264+
temp_chamber.soft_pwm_amount = (MAX_CHAMBER_POWER) >> 1;
1265+
#else
1266+
temp_chamber.soft_pwm_amount = temp_chamber.celsius < temp_chamber.target ? (MAX_CHAMBER_POWER) >> 1 : 0;
1267+
#endif
1268+
#if ENABLED(CHAMBER_VENT)
1269+
if (!flag_chamber_off) MOVE_SERVO(CHAMBER_VENT_SERVO_NR, 0);
1270+
#endif
1271+
}
1272+
else {
1273+
temp_chamber.soft_pwm_amount = 0;
1274+
#if ENABLED(CHAMBER_VENT)
1275+
if (!flag_chamber_off) MOVE_SERVO(CHAMBER_VENT_SERVO_NR, temp_chamber.celsius <= temp_chamber.target ? 0 : 90);
1276+
#endif
1277+
}
12041278
}
12051279
else {
12061280
temp_chamber.soft_pwm_amount = 0;
@@ -3365,7 +3439,7 @@ void Temperature::tick() {
33653439
#define MIN_COOLING_SLOPE_DEG_CHAMBER 1.50
33663440
#endif
33673441
#ifndef MIN_COOLING_SLOPE_TIME_CHAMBER
3368-
#define MIN_COOLING_SLOPE_TIME_CHAMBER 60
3442+
#define MIN_COOLING_SLOPE_TIME_CHAMBER 120
33693443
#endif
33703444

33713445
bool Temperature::wait_for_chamber(const bool no_wait_for_cooling/*=true*/) {

Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
// Servos
4242
//
4343
#define SERVO0_PIN PA1
44+
#define SERVO1_PIN PC9
4445

4546
//
4647
// Trinamic Stallguard pins

0 commit comments

Comments
 (0)