Improve temperature runaway, idle timeout (#19339)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
ellensp
2020-09-14 16:58:39 +12:00
committed by GitHub
parent cf8316bfbb
commit 979876e958
33 changed files with 153 additions and 201 deletions

View File

@@ -40,7 +40,7 @@
#define HOTEND_INDEX TERN(HAS_MULTI_HOTEND, e, 0)
#define E_NAME TERN_(HAS_MULTI_HOTEND, e)
// Identifiers for other heaters
// Heater identifiers. Positive values are hotends. Negative values are other heaters.
typedef enum : int8_t {
INDEX_NONE = -5,
H_PROBE, H_REDUNDANT, H_CHAMBER, H_BED,
@@ -211,16 +211,6 @@ struct PIDHeaterInfo : public HeaterInfo {
typedef temp_info_t chamber_info_t;
#endif
// Heater idle handling
typedef struct {
millis_t timeout_ms;
bool timed_out;
inline void update(const millis_t &ms) { if (!timed_out && timeout_ms && ELAPSED(ms, timeout_ms)) timed_out = true; }
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); }
} hotend_idle_t;
// Heater watch handling
template <int INCREASE, int HYSTERESIS, millis_t PERIOD>
struct HeaterWatch {
@@ -346,9 +336,38 @@ class Temperature {
FORCE_INLINE static bool targetHotEnoughToExtrude(const uint8_t e) { return !targetTooColdToExtrude(e); }
#if HEATER_IDLE_HANDLER
static hotend_idle_t hotend_idle[HOTENDS];
TERN_(HAS_HEATED_BED, static hotend_idle_t bed_idle);
TERN_(HAS_HEATED_CHAMBER, static hotend_idle_t chamber_idle);
// Heater idle handling. Marlin creates one per hotend and one for the heated bed.
typedef struct {
millis_t timeout_ms;
bool timed_out;
inline void update(const millis_t &ms) { if (!timed_out && timeout_ms && ELAPSED(ms, timeout_ms)) timed_out = true; }
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;
// Indices and size for the heater_idle array
#define _ENUM_FOR_E(N) IDLE_INDEX_E##N,
enum IdleIndex : uint8_t {
REPEAT(HOTENDS, _ENUM_FOR_E)
#if ENABLED(HAS_HEATED_BED)
IDLE_INDEX_BED,
#endif
NR_HEATER_IDLE
};
#undef _ENUM_FOR_E
// Convert the given heater_id_t to idle array index
static inline IdleIndex idle_index_for_id(const int8_t heater_id) {
#if HAS_HEATED_BED
if (heater_id == H_BED) return IDLE_INDEX_BED;
#endif
return (IdleIndex)_MAX(heater_id, 0);
}
static heater_idle_t heater_idle[NR_HEATER_IDLE];
#endif
private:
@@ -747,13 +766,13 @@ class Temperature {
#if HEATER_IDLE_HANDLER
static void reset_hotend_idle_timer(const uint8_t E_NAME) {
hotend_idle[HOTEND_INDEX].reset();
heater_idle[HOTEND_INDEX].reset();
start_watching_hotend(HOTEND_INDEX);
}
#if HAS_HEATED_BED
static void reset_bed_idle_timer() {
bed_idle.reset();
heater_idle[IDLE_INDEX_BED].reset();
start_watching_bed();
}
#endif
@@ -815,22 +834,47 @@ class Temperature {
static void min_temp_error(const heater_id_t e);
static void max_temp_error(const heater_id_t e);
#define HAS_THERMAL_PROTECTION (EITHER(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER) || HAS_THERMALLY_PROTECTED_BED)
#define HAS_THERMAL_PROTECTION ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_CHAMBER, HAS_THERMALLY_PROTECTED_BED)
#if HAS_THERMAL_PROTECTION
// Indices and size for the tr_state_machine array. One for each protected heater.
#define _ENUM_FOR_E(N) RUNAWAY_IND_E##N,
enum RunawayIndex : uint8_t {
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
REPEAT(HOTENDS, _ENUM_FOR_E)
#endif
#if ENABLED(HAS_THERMALLY_PROTECTED_BED)
RUNAWAY_IND_BED,
#endif
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
RUNAWAY_IND_CHAMBER,
#endif
NR_HEATER_RUNAWAY
};
#undef _ENUM_FOR_E
// Convert the given heater_id_t to runaway state array index
static inline RunawayIndex runaway_index_for_id(const int8_t heater_id) {
#if HAS_THERMALLY_PROTECTED_CHAMBER
if (heater_id == H_CHAMBER) return RUNAWAY_IND_CHAMBER;
#endif
#if HAS_THERMALLY_PROTECTED_BED
if (heater_id == H_BED) return RUNAWAY_IND_BED;
#endif
return (RunawayIndex)_MAX(heater_id, 0);
}
enum TRState : char { TRInactive, TRFirstHeating, TRStable, TRRunaway };
typedef struct {
millis_t timer = 0;
TRState state = TRInactive;
float running_temp;
void run(const float &current, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc);
} tr_state_machine_t;
TERN_(THERMAL_PROTECTION_HOTENDS, static tr_state_machine_t tr_state_machine[HOTENDS]);
TERN_(HAS_THERMALLY_PROTECTED_BED, static tr_state_machine_t tr_state_machine_bed);
TERN_(THERMAL_PROTECTION_CHAMBER, static tr_state_machine_t tr_state_machine_chamber);
static void thermal_runaway_protection(tr_state_machine_t &state, const float &current, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc);
static tr_state_machine_t tr_state_machine[NR_HEATER_RUNAWAY];
#endif // HAS_THERMAL_PROTECTION
};