From e96df6763048bf21dbd71ed1742e34ac0854d53e Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Thu, 2 Apr 2015 05:10:14 -0700 Subject: [PATCH] Clarify thermal_runaway_protection - Add comments documenting `thermal_runaway_protection` - Add an enum for the thermal runaway states - Add macros for temperature helper functions - Fix a glitch with the z probe sled in homeaxis --- Marlin/Marlin_main.cpp | 59 ++++++++--------- Marlin/planner.cpp | 4 +- Marlin/temperature.cpp | 146 +++++++++++++++++++---------------------- Marlin/temperature.h | 46 +++++-------- 4 files changed, 115 insertions(+), 140 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 6b41be617..24d9f0d47 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -1460,7 +1460,7 @@ static void homeaxis(int axis) { sync_plan_position(); // Engage Servo endstop if enabled - #ifdef SERVO_ENDSTOPS && !defined(Z_PROBE_SLED) + #if defined(SERVO_ENDSTOPS) && !defined(Z_PROBE_SLED) #if SERVO_LEVELING if (axis == Z_AXIS) engage_z_probe(); else @@ -2781,7 +2781,7 @@ inline void gcode_M42() { } } - #if defined(FAN_PIN) && FAN_PIN > -1 + #if HAS_FAN if (pin_number == FAN_PIN) fanSpeed = pin_status; #endif @@ -3067,17 +3067,17 @@ inline void gcode_M104() { inline void gcode_M105() { if (setTargetedHotend(105)) return; - #if defined(TEMP_0_PIN) && TEMP_0_PIN > -1 + #if HAS_TEMP_0 SERIAL_PROTOCOLPGM("ok T:"); SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1); SERIAL_PROTOCOLPGM(" /"); SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder),1); - #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 + #if HAS_TEMP_BED SERIAL_PROTOCOLPGM(" B:"); SERIAL_PROTOCOL_F(degBed(),1); SERIAL_PROTOCOLPGM(" /"); SERIAL_PROTOCOL_F(degTargetBed(),1); - #endif //TEMP_BED_PIN + #endif for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) { SERIAL_PROTOCOLPGM(" T"); SERIAL_PROTOCOL(cur_extruder); @@ -3108,7 +3108,7 @@ inline void gcode_M105() { #endif #ifdef SHOW_TEMP_ADC_VALUES - #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 + #if HAS_TEMP_BED SERIAL_PROTOCOLPGM(" ADC B:"); SERIAL_PROTOCOL_F(degBed(),1); SERIAL_PROTOCOLPGM("C->"); @@ -3124,10 +3124,10 @@ inline void gcode_M105() { } #endif - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } -#if defined(FAN_PIN) && FAN_PIN > -1 +#if HAS_FAN /** * M106: Set Fan Speed @@ -3139,7 +3139,7 @@ inline void gcode_M105() { */ inline void gcode_M107() { fanSpeed = 0; } -#endif //FAN_PIN +#endif // HAS_FAN /** * M109: Wait for extruder(s) to reach temperature @@ -3197,10 +3197,10 @@ inline void gcode_M109() { SERIAL_PROTOCOLLN( timetemp ); } else { - SERIAL_PROTOCOLLN( "?" ); + SERIAL_PROTOCOLLNPGM("?"); } #else - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; #endif timetemp = millis(); } @@ -3223,7 +3223,7 @@ inline void gcode_M109() { starttime = previous_millis_cmd = millis(); } -#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 +#if HAS_TEMP_BED /** * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating @@ -3251,7 +3251,7 @@ inline void gcode_M109() { SERIAL_PROTOCOL((int)active_extruder); SERIAL_PROTOCOLPGM(" B:"); SERIAL_PROTOCOL_F(degBed(), 1); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } manage_heater(); manage_inactivity(); @@ -3452,27 +3452,26 @@ inline void gcode_M114() { SERIAL_PROTOCOLPGM(" Z:"); SERIAL_PROTOCOL(float(st_get_position(Z_AXIS))/axis_steps_per_unit[Z_AXIS]); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; #ifdef SCARA SERIAL_PROTOCOLPGM("SCARA Theta:"); SERIAL_PROTOCOL(delta[X_AXIS]); SERIAL_PROTOCOLPGM(" Psi+Theta:"); SERIAL_PROTOCOL(delta[Y_AXIS]); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; SERIAL_PROTOCOLPGM("SCARA Cal - Theta:"); SERIAL_PROTOCOL(delta[X_AXIS]+home_offset[X_AXIS]); SERIAL_PROTOCOLPGM(" Psi+Theta (90):"); SERIAL_PROTOCOL(delta[Y_AXIS]-delta[X_AXIS]-90+home_offset[Y_AXIS]); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; SERIAL_PROTOCOLPGM("SCARA step Cal - Theta:"); SERIAL_PROTOCOL(delta[X_AXIS]/90*axis_steps_per_unit[X_AXIS]); SERIAL_PROTOCOLPGM(" Psi+Theta:"); SERIAL_PROTOCOL((delta[Y_AXIS]-delta[X_AXIS])/90*axis_steps_per_unit[Y_AXIS]); - SERIAL_PROTOCOLLN(""); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; SERIAL_EOL; #endif } @@ -3915,7 +3914,7 @@ inline void gcode_M226() { SERIAL_PROTOCOL(servo_index); SERIAL_PROTOCOL(": "); SERIAL_PROTOCOL(servos[servo_index].read()); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } } @@ -3983,7 +3982,7 @@ inline void gcode_M226() { //Kc does not have scaling applied above, or in resetting defaults SERIAL_PROTOCOL(PID_PARAM(Kc, e)); #endif - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } else { SERIAL_ECHO_START; @@ -4008,7 +4007,7 @@ inline void gcode_M226() { SERIAL_PROTOCOL(unscalePID_i(bedKi)); SERIAL_PROTOCOL(" d:"); SERIAL_PROTOCOL(unscalePID_d(bedKd)); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } #endif // PIDTEMPBED @@ -4058,7 +4057,7 @@ inline void gcode_M226() { if (code_seen('C')) lcd_setcontrast(code_value_long() & 0x3F); SERIAL_PROTOCOLPGM("lcd contrast value: "); SERIAL_PROTOCOL(lcd_contrast); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } #endif // DOGLCD @@ -4331,7 +4330,7 @@ inline void gcode_M503() { zprobe_zoffset = -value; // compare w/ line 278 of ConfigurationStore.cpp SERIAL_ECHO_START; SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " " MSG_OK); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } else { SERIAL_ECHO_START; @@ -4340,14 +4339,14 @@ inline void gcode_M503() { SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MIN); SERIAL_ECHOPGM(MSG_Z_MAX); SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MAX); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } } else { SERIAL_ECHO_START; SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " : "); SERIAL_ECHO(-zprobe_zoffset); - SERIAL_PROTOCOLLN(""); + SERIAL_EOL; } } @@ -4852,20 +4851,20 @@ void process_commands() { gcode_M109(); break; - #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 + #if HAS_TEMP_BED case 190: // M190 - Wait for bed heater to reach target. gcode_M190(); break; - #endif //TEMP_BED_PIN + #endif // HAS_TEMP_BED - #if defined(FAN_PIN) && FAN_PIN > -1 + #if HAS_FAN case 106: //M106 Fan On gcode_M106(); break; case 107: //M107 Fan Off gcode_M107(); break; - #endif //FAN_PIN + #endif // HAS_FAN #ifdef BARICUDA // PWM for HEATER_1_PIN @@ -5704,7 +5703,7 @@ void handle_status_leds(void) { max_temp = max(max_temp, degHotend(cur_extruder)); max_temp = max(max_temp, degTargetHotend(cur_extruder)); } - #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 + #if HAS_TEMP_BED max_temp = max(max_temp, degTargetBed()); max_temp = max(max_temp, degBed()); #endif diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index d98ef63d4..1dcbc96af 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -427,7 +427,7 @@ void check_axes_activity() { disable_e3(); } - #if defined(FAN_PIN) && FAN_PIN > -1 // HAS_FAN + #if HAS_FAN #ifdef FAN_KICKSTART_TIME static unsigned long fan_kick_end; if (tail_fan_speed) { @@ -447,7 +447,7 @@ void check_axes_activity() { #else analogWrite(FAN_PIN, tail_fan_speed); #endif //!FAN_SOFT_PWM - #endif //FAN_PIN > -1 + #endif // HAS_FAN #ifdef AUTOTEMP getHighESpeed(); diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index b59ff29df..2442ad206 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -1,5 +1,5 @@ /* - temperature.c - temperature control + temperature.cpp - temperature control Part of Marlin Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm @@ -16,18 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - */ - -/* - This firmware is a mashup between Sprinter and grbl. - (https://github.com/kliment/Sprinter) - (https://github.com/simen/grbl/tree) - - It has preliminary support for Matthew Roberts advance algorithm - http://reprap.org/pipermail/reprap-dev/2011-May/003323.html - - */ - +*/ #include "Marlin.h" #include "ultralcd.h" @@ -87,14 +76,15 @@ unsigned char soft_pwm_bed; #define HAS_HEATER_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0) #define HAS_BED_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_BED_PERIOD) && THERMAL_RUNAWAY_PROTECTION_BED_PERIOD > 0 && TEMP_SENSOR_BED != 0) #if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION + enum TRState { TRInactive, TRFirstHeating, TRStable }; static bool thermal_runaway = false; - void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); + void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); #if HAS_HEATER_THERMAL_PROTECTION - static int thermal_runaway_state_machine[4]; // = {0,0,0,0}; + static TRState thermal_runaway_state_machine[4] = { TRInactive, TRInactive, TRInactive, TRInactive }; static unsigned long thermal_runaway_timer[4]; // = {0,0,0,0}; #endif #if HAS_BED_THERMAL_PROTECTION - static int thermal_runaway_bed_state_machine; + static TRState thermal_runaway_bed_state_machine = { TRInactive, TRInactive, TRInactive, TRInactive }; static unsigned long thermal_runaway_bed_timer; #endif #endif @@ -238,7 +228,7 @@ void PID_autotune(float temp, int extruder, int ncycles) soft_pwm[extruder] = bias = d = PID_MAX / 2; // PID Tuning loop - for(;;) { + for (;;) { unsigned long ms = millis(); @@ -609,7 +599,7 @@ void manage_heater() { // Loop through all extruders for (int e = 0; e < EXTRUDERS; e++) { - #if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 + #if HAS_HEATER_THERMAL_PROTECTION thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS); #endif @@ -637,7 +627,7 @@ void manage_heater() { disable_heater(); _temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP)); } - #endif //TEMP_SENSOR_1_AS_REDUNDANT + #endif // TEMP_SENSOR_1_AS_REDUNDANT } // Extruders Loop @@ -1014,69 +1004,69 @@ void setWatch() { } #if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION -void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) -{ -/* - SERIAL_ECHO_START; - SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:"); - SERIAL_ECHO(heater_id); - SERIAL_ECHO(" ; State:"); - SERIAL_ECHO(*state); - SERIAL_ECHO(" ; Timer:"); - SERIAL_ECHO(*timer); - SERIAL_ECHO(" ; Temperature:"); - SERIAL_ECHO(temperature); - SERIAL_ECHO(" ; Target Temp:"); - SERIAL_ECHO(target_temperature); - SERIAL_ECHOLN(""); -*/ - if ((target_temperature == 0) || thermal_runaway) - { - *state = 0; - *timer = 0; - return; - } - switch (*state) - { - case 0: // "Heater Inactive" state - if (target_temperature > 0) *state = 1; - break; - case 1: // "First Heating" state - if (temperature >= target_temperature) *state = 2; - break; - case 2: // "Temperature Stable" state - { - unsigned long ms = millis(); - if (temperature >= (target_temperature - hysteresis_degc)) - { - *timer = ms; - } - else if ( (ms - *timer) > ((unsigned long) period_seconds) * 1000) + + void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) { + /* + SERIAL_ECHO_START; + SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:"); + SERIAL_ECHO(heater_id); + SERIAL_ECHO(" ; State:"); + SERIAL_ECHO(*state); + SERIAL_ECHO(" ; Timer:"); + SERIAL_ECHO(*timer); + SERIAL_ECHO(" ; Temperature:"); + SERIAL_ECHO(temperature); + SERIAL_ECHO(" ; Target Temp:"); + SERIAL_ECHO(target_temperature); + SERIAL_ECHOLN(""); + */ + if (target_temperature == 0 || thermal_runaway) { + *state = TRInactive; + *timer = 0; + return; + } + + switch (*state) { + // Inactive state waits for a target temperature, then + case TRInactive: + if (target_temperature > 0) *state = TRFirstHeating; + break; + // When first heating, wait for the temperature to be reached then go to Stable state + case TRFirstHeating: + if (temperature >= target_temperature) *state = TRStable; + break; + // While the temperature is stable watch for a bad temperature + case TRStable: { - SERIAL_ERROR_START; - SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP); - SERIAL_ERRORLN((int)heater_id); - LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY); // translatable - thermal_runaway = true; - while(1) - { - disable_heater(); - disable_x(); - disable_y(); - disable_z(); - disable_e0(); - disable_e1(); - disable_e2(); - disable_e3(); - manage_heater(); - lcd_update(); + // Whenever the current temperature is over the target (-hysteresis) restart the timer + if (temperature >= target_temperature - hysteresis_degc) { + *timer = millis(); } - } - } break; + // If the timer goes too long without a reset, trigger shutdown + else if (millis() > *timer + period_seconds * 1000UL) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP); + SERIAL_ERRORLN((int)heater_id); + LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY); + thermal_runaway = true; + for (;;) { + disable_heater(); + disable_x(); + disable_y(); + disable_z(); + disable_e0(); + disable_e1(); + disable_e2(); + disable_e3(); + manage_heater(); + lcd_update(); + } + } + } break; + } } -} -#endif //THERMAL_RUNAWAY_PROTECTION_PERIOD +#endif // HAS_HEATER_THERMAL_PROTECTION void disable_heater() { for (int i=0; i. */ -#ifndef temperature_h -#define temperature_h +#ifndef TEMPERATURE_H +#define TEMPERATURE_H #include "Marlin.h" #include "planner.h" @@ -105,40 +105,27 @@ FORCE_INLINE bool isHeatingBed() { return target_temperature_bed > current_tempe FORCE_INLINE bool isCoolingHotend(uint8_t extruder) { return target_temperature[extruder] < current_temperature[extruder]; } FORCE_INLINE bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } -#define degHotend0() degHotend(0) -#define degTargetHotend0() degTargetHotend(0) -#define setTargetHotend0(_celsius) setTargetHotend((_celsius), 0) -#define isHeatingHotend0() isHeatingHotend(0) -#define isCoolingHotend0() isCoolingHotend(0) +#define HOTEND_ROUTINES(NR) \ + FORCE_INLINE float degHotend##NR() { return degHotend(NR); } \ + FORCE_INLINE float degTargetHotend##NR() { return degTargetHotend(NR); } \ + FORCE_INLINE void setTargetHotend##NR(const float c) { setTargetHotend(c, NR); } \ + FORCE_INLINE bool isHeatingHotend##NR() { return isHeatingHotend(NR); } \ + FORCE_INLINE bool isCoolingHotend##NR() { return isCoolingHotend(NR); } +HOTEND_ROUTINES(0); #if EXTRUDERS > 1 - #define degHotend1() degHotend(1) - #define degTargetHotend1() degTargetHotend(1) - #define setTargetHotend1(_celsius) setTargetHotend((_celsius), 1) - #define isHeatingHotend1() isHeatingHotend(1) - #define isCoolingHotend1() isCoolingHotend(1) + HOTEND_ROUTINES(1); #else - #define setTargetHotend1(_celsius) do{}while(0) + #define setTargetHotend1(c) do{}while(0) #endif #if EXTRUDERS > 2 - #define degHotend2() degHotend(2) - #define degTargetHotend2() degTargetHotend(2) - #define setTargetHotend2(_celsius) setTargetHotend((_celsius), 2) - #define isHeatingHotend2() isHeatingHotend(2) - #define isCoolingHotend2() isCoolingHotend(2) + HOTEND_ROUTINES(2); #else - #define setTargetHotend2(_celsius) do{}while(0) + #define setTargetHotend2(c) do{}while(0) #endif #if EXTRUDERS > 3 - #define degHotend3() degHotend(3) - #define degTargetHotend3() degTargetHotend(3) - #define setTargetHotend3(_celsius) setTargetHotend((_celsius), 3) - #define isHeatingHotend3() isHeatingHotend(3) - #define isCoolingHotend3() isCoolingHotend(3) + HOTEND_ROUTINES(3); #else - #define setTargetHotend3(_celsius) do{}while(0) -#endif -#if EXTRUDERS > 4 - #error Invalid number of extruders + #define setTargetHotend3(c) do{}while(0) #endif int getHeaterPower(int heater); @@ -161,5 +148,4 @@ FORCE_INLINE void autotempShutdown() { #endif } - -#endif +#endif // TEMPERATURE_H