diff --git a/Firmware/Configuration_prusa.h b/Firmware/Configuration_prusa.h index b1cc9ffc..7cf413c3 100644 --- a/Firmware/Configuration_prusa.h +++ b/Firmware/Configuration_prusa.h @@ -262,8 +262,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o #define EXTRUDER_2_AUTO_FAN_PIN -1 #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 #define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed - - +#define SAFETYTIMER /*------------------------------------ LOAD/UNLOAD FILAMENT SETTINGS diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 7360ab9a..e2018ee1 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -54,6 +54,7 @@ #include "pins_arduino.h" #include "math.h" #include "util.h" +#include "Timer.h" #include @@ -6733,6 +6734,31 @@ void handle_status_leds(void) { } #endif +#ifdef SAFETYTIMER +/** + * @brief Turn off heating after 15 minutes of inactivity + */ +static void handleSafetyTimer() +{ + static_assert(EXTRUDERS == 1,"Implemented only for one extruder."); + static Timer safetyTimer; + if (IS_SD_PRINTING || is_usb_printing || (custom_message_type == 4) || (lcd_commands_type == LCD_COMMAND_V2_CAL) || + (!degTargetBed() && !degTargetHotend(0))) + { + safetyTimer.stop(); + } + else if ((degTargetBed() || degTargetHotend(0)) && (!safetyTimer.running())) + { + safetyTimer.start(); + } + else if (safetyTimer.expired(15*60*1000)) + { + setTargetBed(0); + setTargetHotend(0, 0); + } +} +#endif //SAFETYTIMER + void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h { if (fsensor_enabled && filament_autoload_enabled && !fsensor_M600 && !moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) @@ -6773,6 +6799,10 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s if (fsensor_autoload_enabled) fsensor_autoload_check_stop(); +#ifdef SAFETYTIMER + handleSafetyTimer(); +#endif //SAFETYTIMER + #if defined(KILL_PIN) && KILL_PIN > -1 static int killCount = 0; // make the inactivity button a bit less responsive const int KILL_DELAY = 10000; diff --git a/Firmware/Timer.cpp b/Firmware/Timer.cpp new file mode 100644 index 00000000..78f47a45 --- /dev/null +++ b/Firmware/Timer.cpp @@ -0,0 +1,55 @@ +/** + * @file + * @author Marek Bel + */ + +#include "Timer.h" +#include "Arduino.h" + +Timer::Timer() : m_isRunning(false), m_started() +{ +} + +/** + * @brief Start timer + */ +void Timer::start() +{ + m_started = millis(); + m_isRunning = true; +} + +/** + * @brief Timer has expired + * + * Timer is considered expired after msPeriod has passed from time the timer was started. + * This function must be called at least each (unsigned long maximum value - msPeriod) milliseconds to be sure to + * catch first expiration. + * This function is expected to handle wrap around of time register well. + * + * @param msPeriod Time interval in milliseconds. + * @retval true Timer has expired + * @retval false Timer not expired yet, or is not running, or time window in which is timer considered expired passed. + */ +bool Timer::expired(unsigned long msPeriod) +{ + if (!m_isRunning) return false; + bool expired = false; + const unsigned long now = millis(); + if (m_started <= m_started + msPeriod) + { + if ((now >= m_started + msPeriod) || (now < m_started)) + { + expired = true; + } + } + else + { + if ((now >= m_started + msPeriod) && (now < m_started)) + { + expired = true; + } + } + if (expired) m_isRunning = false; + return expired; +} diff --git a/Firmware/Timer.h b/Firmware/Timer.h new file mode 100644 index 00000000..0d3a89dc --- /dev/null +++ b/Firmware/Timer.h @@ -0,0 +1,30 @@ +/* + * @file + * @author Marek Bel + */ + +#ifndef TIMER_H +#define TIMER_H + +/** + * @brief simple timer + * + * Simple and memory saving implementation. Should handle timer register wrap around well. + * Maximum period is at least 49 days. Resolution is one millisecond. To save memory, doesn't store timer period. + * If you wish timer which is storing period, derive from this. If you need time intervals smaller than 65 seconds + * consider implementing timer with smaller underlying type. + */ +class Timer +{ +public: + Timer(); + void start(); + void stop(){m_isRunning = false;} + bool running(){return m_isRunning;} + bool expired(unsigned long msPeriod); +private: + bool m_isRunning; + unsigned long m_started; +}; + +#endif /* TIMER_H */