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

Refactor heater watch, job timer auto-start #16725

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
Refactor heater watch, job timer auto-start
  • Loading branch information
thinkyhead committed Jan 30, 2020
commit 217515e60a8d8f2fc6f596e696a0d0589a921f9a
4 changes: 2 additions & 2 deletions Marlin/src/feature/pause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
#endif

// Re-enable the heaters if they timed out
HOTEND_LOOP() thermalManager.reset_heater_idle_timer(e);
HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e);

// Wait for the heaters to reach the target temperatures
ensure_safe_temperature();
Expand Down Expand Up @@ -633,7 +633,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
bool nozzle_timed_out = false;
HOTEND_LOOP() {
nozzle_timed_out |= thermalManager.hotend_idle[e].timed_out;
thermalManager.reset_heater_idle_timer(e);
thermalManager.reset_hotend_idle_timer(e);
}

if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // Load the new filament
Expand Down
30 changes: 15 additions & 15 deletions Marlin/src/gcode/temperature/M104_M109.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
*
*/

/**
* gcode/temperature/M104_M109.cpp
*
* Hotend target temperature control
*/

#include "../../inc/MarlinConfigPre.h"

#if EXTRUDERS
Expand Down Expand Up @@ -73,14 +79,11 @@ void GcodeSuite::M104() {
#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
/**
* Stop the timer at the end of print. Start is managed by 'heat and wait' M109.
* We use half EXTRUDE_MINTEMP here to allow nozzles to be put into hot
* standby mode, for instance in a dual extruder setup, without affecting
* the running print timer.
* Hotends use EXTRUDE_MINTEMP / 2 to allow nozzles to be put into hot standby
* mode, for instance in a dual extruder setup, without affecting the running
* print timer.
*/
if (temp <= (EXTRUDE_MINTEMP) / 2) {
print_job_timer.stop();
ui.reset_status();
}
thermalManager.check_timer_autostart(false, true);
#endif
}

Expand All @@ -90,8 +93,10 @@ void GcodeSuite::M104() {
}

/**
* M109: Sxxx Wait for extruder(s) to reach temperature. Waits only when heating.
* Rxxx Wait for extruder(s) to reach temperature. Waits when heating and cooling.
* M109: Sxxx Wait for hotend(s) to reach temperature. Waits only when heating.
* Rxxx Wait for hotend(s) to reach temperature. Waits when heating and cooling.
*
* With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating and stop it if turned off.
*/
void GcodeSuite::M109() {

Expand Down Expand Up @@ -125,12 +130,7 @@ void GcodeSuite::M109() {
* standby mode, (e.g., in a dual extruder setup) without affecting
* the running print timer.
*/
if (parser.value_celsius() <= (EXTRUDE_MINTEMP) / 2) {
print_job_timer.stop();
ui.reset_status();
}
else
startOrResumeJob();
thermalManager.check_timer_autostart(true, true);
#endif

#if HAS_DISPLAY
Expand Down
11 changes: 9 additions & 2 deletions Marlin/src/gcode/temperature/M140_M190.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
*
*/

/**
* gcode/temperature/M140_M190.cpp
*
* Bed target temperature control
*/

#include "../../inc/MarlinConfig.h"

#if HAS_HEATED_BED
Expand Down Expand Up @@ -50,6 +56,8 @@ void GcodeSuite::M140() {
/**
* M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
* Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
*
* With PRINTJOB_TIMER_AUTOSTART also start the job timer on heating.
*/
void GcodeSuite::M190() {
if (DEBUGGING(DRYRUN)) return;
Expand All @@ -58,8 +66,7 @@ void GcodeSuite::M190() {
if (no_wait_for_cooling || parser.seenval('R')) {
thermalManager.setTargetBed(parser.value_celsius());
#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
if (parser.value_celsius() > BED_MINTEMP)
startOrResumeJob();
thermalManager.check_timer_autostart(true, false);
#endif
}
else return;
Expand Down
9 changes: 7 additions & 2 deletions Marlin/src/gcode/temperature/M141_M191.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
*
*/

/**
* gcode/temperature/M141_M191.cpp
*
* Chamber target temperature control
*/

#include "../../inc/MarlinConfig.h"

#if HAS_HEATED_CHAMBER
Expand Down Expand Up @@ -59,8 +65,7 @@ void GcodeSuite::M191() {
if (no_wait_for_cooling || parser.seenval('R')) {
thermalManager.setTargetChamber(parser.value_celsius());
#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
if (parser.value_celsius() > CHAMBER_MINTEMP)
startOrResumeJob();
thermalManager.check_timer_autostart(true, false);
#endif
}
else return;
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/lcd/extensible_ui/ui_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ namespace ExtUI {

void enableHeater(const extruder_t extruder) {
#if HOTENDS && HEATER_IDLE_HANDLER
thermalManager.reset_heater_idle_timer(extruder - E0);
thermalManager.reset_hotend_idle_timer(extruder - E0);
#else
UNUSED(extruder);
#endif
Expand All @@ -190,7 +190,7 @@ namespace ExtUI {
#endif
default:
#if HOTENDS
thermalManager.reset_heater_idle_timer(heater - H0);
thermalManager.reset_hotend_idle_timer(heater - H0);
#endif
break;
}
Expand Down
61 changes: 37 additions & 24 deletions Marlin/src/module/temperature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ Temperature thermalManager;
#endif // FAN_COUNT > 0

#if WATCH_HOTENDS
heater_watch_t Temperature::watch_hotend[HOTENDS]; // = { { 0 } }
hotend_watch_t Temperature::watch_hotend[HOTENDS]; // = { { 0 } }
#endif
#if HEATER_IDLE_HANDLER
heater_idle_t Temperature::hotend_idle[HOTENDS]; // = { { 0 } }
hotend_idle_t Temperature::hotend_idle[HOTENDS]; // = { { 0 } }
#endif

#if HAS_HEATED_BED
Expand All @@ -236,13 +236,13 @@ Temperature thermalManager;
int16_t Temperature::maxtemp_raw_BED = HEATER_BED_RAW_HI_TEMP;
#endif
#if WATCH_BED
heater_watch_t Temperature::watch_bed; // = { 0 }
bed_watch_t Temperature::watch_bed; // = { 0 }
#endif
#if DISABLED(PIDTEMPBED)
millis_t Temperature::next_bed_check_ms;
#endif
#if HEATER_IDLE_HANDLER
heater_idle_t Temperature::bed_idle; // = { 0 }
hotend_idle_t Temperature::bed_idle; // = { 0 }
#endif
#endif // HAS_HEATED_BED

Expand All @@ -256,7 +256,7 @@ Temperature thermalManager;
int16_t Temperature::maxtemp_raw_CHAMBER = HEATER_CHAMBER_RAW_HI_TEMP;
#endif
#if WATCH_CHAMBER
heater_watch_t Temperature::watch_chamber{0};
chamber_watch_t Temperature::watch_chamber{0};
#endif
millis_t Temperature::next_chamber_check_ms;
#endif // HAS_HEATED_CHAMBER
Expand Down Expand Up @@ -1974,12 +1974,7 @@ void Temperature::init() {
*/
void Temperature::start_watching_hotend(const uint8_t E_NAME) {
const uint8_t ee = HOTEND_INDEX;
if (degTargetHotend(ee) && degHotend(ee) < degTargetHotend(ee) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
watch_hotend[ee].target = degHotend(ee) + WATCH_TEMP_INCREASE;
watch_hotend[ee].next_ms = millis() + (WATCH_TEMP_PERIOD) * 1000UL;
}
else
watch_hotend[ee].next_ms = 0;
watch_hotend[ee].restart(degHotend(ee), degTargetHotend(ee));
}
#endif

Expand All @@ -1990,12 +1985,7 @@ void Temperature::init() {
* This is called when the temperature is set. (M140, M190)
*/
void Temperature::start_watching_bed() {
if (degTargetBed() && degBed() < degTargetBed() - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) {
watch_bed.target = degBed() + WATCH_BED_TEMP_INCREASE;
watch_bed.next_ms = millis() + (WATCH_BED_TEMP_PERIOD) * 1000UL;
}
else
watch_bed.next_ms = 0;
watch_bed.restart(degBed(), degTargetBed());
}
#endif

Expand All @@ -2006,12 +1996,7 @@ void Temperature::init() {
* This is called when the temperature is set. (M141, M191)
*/
void Temperature::start_watching_chamber() {
if (degChamber() < degTargetChamber() - (WATCH_CHAMBER_TEMP_INCREASE + TEMP_CHAMBER_HYSTERESIS + 1)) {
watch_chamber.target = degChamber() + WATCH_CHAMBER_TEMP_INCREASE;
watch_chamber.next_ms = millis() + (WATCH_CHAMBER_TEMP_PERIOD) * 1000UL;
}
else
watch_chamber.next_ms = 0;
watch_chamber.restart(degChamber(), degTargetChamber());
}
#endif

Expand Down Expand Up @@ -2154,6 +2139,34 @@ void Temperature::disable_all_heaters() {
#endif
}

#if ENABLED(PRINTJOB_TIMER_AUTOSTART)

bool Temperature::over_autostart_threshold() {
#if HOTENDS
HOTEND_LOOP() if (degTargetHotend(e) < (EXTRUDE_MINTEMP) / 2) return true;
#endif
#if HAS_HEATED_BED
if (degTargetBed() > BED_MINTEMP) return true;
#endif
#if HAS_HEATED_CHAMBER
if (degTargetChamber() > CHAMBER_MINTEMP) return true;
#endif
return false;
}

void Temperature::check_timer_autostart(const bool can_start, const bool can_stop) {
if (over_autostart_threshold()) {
if (can_start) startOrResumeJob();
}
else if (can_stop) {
print_job_timer.stop();
ui.reset_status();
}
}

#endif


#if ENABLED(PROBING_HEATERS_OFF)

void Temperature::pause(const bool p) {
Expand All @@ -2166,7 +2179,7 @@ void Temperature::disable_all_heaters() {
#endif
}
else {
HOTEND_LOOP() reset_heater_idle_timer(e);
HOTEND_LOOP() reset_hotend_idle_timer(e);
#if HAS_HEATED_BED
reset_bed_idle_timer();
#endif
Expand Down
51 changes: 41 additions & 10 deletions Marlin/src/module/temperature.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,38 @@ typedef struct {
inline void start(const millis_t &ms) { timeout_ms = millis() + ms; timed_out = false; }
inline void reset() { timeout_ms = 0; timed_out = false; }
inline void expire() { start(0); }
} heater_idle_t;
} hotend_idle_t;

// Heater watch handling
typedef struct {
template <int INCREASE, int HYSTERESIS, millis_t PERIOD>
struct HeaterWatch {
uint16_t target;
millis_t next_ms;
inline bool elapsed(const millis_t &ms) { return next_ms && ELAPSED(ms, next_ms); }
inline bool elapsed() { return elapsed(millis()); }
} heater_watch_t;

inline void restart(const int16_t curr, const int16_t tgt) {
if (tgt) {
const int16_t newtarget = curr + INCREASE;
if (newtarget < tgt - HYSTERESIS - 1) {
target = newtarget;
next_ms = millis() + PERIOD * 1000UL;
return;
}
}
next_ms = 0;
}
};

#if WATCH_HOTENDS
typedef struct HeaterWatch<WATCH_TEMP_INCREASE, TEMP_HYSTERESIS, WATCH_TEMP_PERIOD> hotend_watch_t;
#endif
#if WATCH_BED
typedef struct HeaterWatch<WATCH_BED_TEMP_INCREASE, TEMP_BED_HYSTERESIS, WATCH_BED_TEMP_PERIOD> bed_watch_t;
#endif
#if WATCH_CHAMBER
typedef struct HeaterWatch<WATCH_CHAMBER_TEMP_INCREASE, TEMP_CHAMBER_HYSTERESIS, WATCH_CHAMBER_TEMP_PERIOD> chamber_watch_t;
#endif

// Temperature sensor read value ranges
typedef struct { int16_t raw_min, raw_max; } raw_range_t;
Expand Down Expand Up @@ -345,12 +368,12 @@ class Temperature {
FORCE_INLINE static bool targetHotEnoughToExtrude(const uint8_t e) { return !targetTooColdToExtrude(e); }

#if HEATER_IDLE_HANDLER
static heater_idle_t hotend_idle[HOTENDS];
static hotend_idle_t hotend_idle[HOTENDS];
#if HAS_HEATED_BED
static heater_idle_t bed_idle;
static hotend_idle_t bed_idle;
#endif
#if HAS_HEATED_CHAMBER
static heater_idle_t chamber_idle;
static hotend_idle_t chamber_idle;
#endif
#endif

Expand All @@ -363,7 +386,7 @@ class Temperature {
static volatile bool raw_temps_ready;

#if WATCH_HOTENDS
static heater_watch_t watch_hotend[HOTENDS];
static hotend_watch_t watch_hotend[HOTENDS];
#endif

#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
Expand All @@ -382,7 +405,7 @@ class Temperature {

#if HAS_HEATED_BED
#if WATCH_BED
static heater_watch_t watch_bed;
static bed_watch_t watch_bed;
#endif
#if DISABLED(PIDTEMPBED)
static millis_t next_bed_check_ms;
Expand All @@ -397,7 +420,7 @@ class Temperature {

#if HAS_HEATED_CHAMBER
#if WATCH_CHAMBER
static heater_watch_t watch_chamber;
static chamber_watch_t watch_chamber;
#endif
static millis_t next_chamber_check_ms;
#ifdef CHAMBER_MINTEMP
Expand Down Expand Up @@ -736,6 +759,14 @@ class Temperature {
*/
static void disable_all_heaters();

#if ENABLED(PRINTJOB_TIMER_AUTOSTART)
/**
* Methods to check if heaters are enabled, indicating an active job
*/
static bool over_autostart_threshold();
static void check_timer_autostart(const bool can_start, const bool can_stop);
#endif

/**
* Perform auto-tuning for hotend or bed in response to M303
*/
Expand Down Expand Up @@ -768,7 +799,7 @@ class Temperature {

#if HEATER_IDLE_HANDLER

static void reset_heater_idle_timer(const uint8_t E_NAME) {
static void reset_hotend_idle_timer(const uint8_t E_NAME) {
hotend_idle[HOTEND_INDEX].reset();
start_watching_hotend(HOTEND_INDEX);
}
Expand Down