From 5be895d906d43a64c5e429683d136388d20341e0 Mon Sep 17 00:00:00 2001 From: John Lagonikas <39417467+zeleps@users.noreply.github.com> Date: Sat, 18 Mar 2023 13:43:15 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20Temperature=20Variance=20Monitor?= =?UTF-8?q?=20tweaks=20(#23571)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/Configuration_adv.h | 31 ++++++++++++++++++++++++++++--- Marlin/src/HAL/LPC1768/HAL.cpp | 1 + Marlin/src/HAL/LPC1768/HAL.h | 13 ++++++++----- Marlin/src/inc/Warnings.cpp | 5 +++++ Marlin/src/module/temperature.cpp | 11 +++++++++-- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 284ecb6b1c..70bbf0a0e6 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -368,10 +368,35 @@ #if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER) /** - * Thermal Protection Variance Monitor - EXPERIMENTAL. - * Kill the machine on a stuck temperature sensor. Disable if you get false positives. + * Thermal Protection Variance Monitor - EXPERIMENTAL + * Kill the machine on a stuck temperature sensor. + * + * This feature may cause some thermally-stable systems to halt. Be sure to test it throughly under + * a variety of conditions. Disable if you get false positives. + * + * This feature ensures that temperature sensors are updating regularly. If sensors die or get "stuck", + * or if Marlin stops reading them, temperatures will remain constant while heaters may still be powered! + * This feature only monitors temperature changes so it should catch any issue, hardware or software. + * + * By default it uses the THERMAL_PROTECTION_*_PERIOD constants (above) for the time window, within which + * at least one temperature change must occur, to indicate that sensor polling is working. If any monitored + * heater's temperature remains totally constant (without even a fractional change) during this period, a + * thermal malfunction error occurs and the printer is halted. + * + * A very stable heater might produce a false positive and halt the printer. In this case, try increasing + * the corresponding THERMAL_PROTECTION_*_PERIOD constant a bit. Keep in mind that uncontrolled heating + * shouldn't be allowed to persist for more than a minite or two. + * + * Be careful to distinguish false positives from real sensor issues before disabling this feature. If the + * heater's temperature appears even slightly higher than expected after restarting, you may have a real + * thermal malfunction. Check the temperature graph in your host for any unusual bumps. */ - //#define THERMAL_PROTECTION_VARIANCE_MONITOR // Detect a sensor malfunction preventing temperature updates + //#define THERMAL_PROTECTION_VARIANCE_MONITOR + #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) + // Variance detection window to override the THERMAL_PROTECTION...PERIOD settings above. + // Keep in mind that some heaters heat up faster than others. + //#define THERMAL_PROTECTION_VARIANCE_MONITOR_PERIOD 30 // (s) Override all watch periods + #endif #endif #if ENABLED(PIDTEMP) diff --git a/Marlin/src/HAL/LPC1768/HAL.cpp b/Marlin/src/HAL/LPC1768/HAL.cpp index 9ff3a6ba59..746f43a2a4 100644 --- a/Marlin/src/HAL/LPC1768/HAL.cpp +++ b/Marlin/src/HAL/LPC1768/HAL.cpp @@ -28,6 +28,7 @@ DefaultSerial1 USBSerial(false, UsbSerial); uint32_t MarlinHAL::adc_result = 0; +pin_t MarlinHAL::adc_pin = 0; // U8glib required functions extern "C" { diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h index b0eeb983b4..63bec2b720 100644 --- a/Marlin/src/HAL/LPC1768/HAL.h +++ b/Marlin/src/HAL/LPC1768/HAL.h @@ -241,15 +241,18 @@ public: // Begin ADC sampling on the given pin. Called from Temperature::isr! static uint32_t adc_result; - static void adc_start(const pin_t pin) { - adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits - } + static pin_t adc_pin; + + static void adc_start(const pin_t pin) { adc_pin = pin; } // Is the ADC ready for reading? - static bool adc_ready() { return true; } + static bool adc_ready() { return LPC176x::adc_hardware.done(LPC176x::pin_get_adc_channel(adc_pin)); } // The current value of the ADC register - static uint16_t adc_value() { return uint16_t(adc_result); } + static uint16_t adc_value() { + adc_result = FilteredADC::read(adc_pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits + return uint16_t(adc_result); + } /** * Set the PWM duty cycle for the pin to the given value. diff --git a/Marlin/src/inc/Warnings.cpp b/Marlin/src/inc/Warnings.cpp index 405e7a351e..01246596c3 100644 --- a/Marlin/src/inc/Warnings.cpp +++ b/Marlin/src/inc/Warnings.cpp @@ -63,6 +63,11 @@ #warning "Warning! Don't use dummy thermistors (998/999) for final build!" #endif +#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER) \ + && NONE(THERMAL_PROTECTION_VARIANCE_MONITOR, NO_VARIANCE_MONITOR_WARNING) + #warning "THERMAL_PROTECTION_VARIANCE_MONITOR is recommended. See Configuration_adv.h for details. (Define NO_VARIANCE_MONITOR_WARNING to suppress this.)" +#endif + #if NONE(HAS_RESUME_CONTINUE, HOST_PROMPT_SUPPORT) #warning "Your Configuration provides no method to acquire user feedback!" #endif diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 578fd112d2..2bb88320b5 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -2915,11 +2915,18 @@ void Temperature::init() { */ #if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) + + #ifdef THERMAL_PROTECTION_VARIANCE_MONITOR_PERIOD + #define VARIANCE_WINDOW THERMAL_PROTECTION_VARIANCE_MONITOR_PERIOD + #else + #define VARIANCE_WINDOW period_seconds + #endif + if (state == TRMalfunction) { // temperature invariance may continue, regardless of heater state variance += ABS(current - last_temp); // no need for detection window now, a single change in variance is enough last_temp = current; if (!NEAR_ZERO(variance)) { - variance_timer = millis() + SEC_TO_MS(period_seconds); + variance_timer = millis() + SEC_TO_MS(VARIANCE_WINDOW); variance = 0.0; state = TRStable; // resume from where we detected the problem } @@ -2980,7 +2987,7 @@ void Temperature::init() { state = TRMalfunction; break; } - variance_timer = now + SEC_TO_MS(period_seconds); + variance_timer = now + SEC_TO_MS(VARIANCE_WINDOW); variance = 0.0; last_temp = current; }