🚸 Temperature Variance Monitor tweaks (#23571)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
John Lagonikas 2023-03-18 13:43:15 +02:00 committed by GitHub
parent 3c88270361
commit 5be895d906
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 10 deletions

View file

@ -368,10 +368,35 @@
#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER) #if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER)
/** /**
* Thermal Protection Variance Monitor - EXPERIMENTAL. * Thermal Protection Variance Monitor - EXPERIMENTAL
* Kill the machine on a stuck temperature sensor. Disable if you get false positives. * 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 #endif
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)

View file

@ -28,6 +28,7 @@
DefaultSerial1 USBSerial(false, UsbSerial); DefaultSerial1 USBSerial(false, UsbSerial);
uint32_t MarlinHAL::adc_result = 0; uint32_t MarlinHAL::adc_result = 0;
pin_t MarlinHAL::adc_pin = 0;
// U8glib required functions // U8glib required functions
extern "C" { extern "C" {

View file

@ -241,15 +241,18 @@ public:
// Begin ADC sampling on the given pin. Called from Temperature::isr! // Begin ADC sampling on the given pin. Called from Temperature::isr!
static uint32_t adc_result; static uint32_t adc_result;
static void adc_start(const pin_t pin) { static pin_t adc_pin;
adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
} static void adc_start(const pin_t pin) { adc_pin = pin; }
// Is the ADC ready for reading? // 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 // 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. * Set the PWM duty cycle for the pin to the given value.

View file

@ -63,6 +63,11 @@
#warning "Warning! Don't use dummy thermistors (998/999) for final build!" #warning "Warning! Don't use dummy thermistors (998/999) for final build!"
#endif #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) #if NONE(HAS_RESUME_CONTINUE, HOST_PROMPT_SUPPORT)
#warning "Your Configuration provides no method to acquire user feedback!" #warning "Your Configuration provides no method to acquire user feedback!"
#endif #endif

View file

@ -2915,11 +2915,18 @@ void Temperature::init() {
*/ */
#if ENABLED(THERMAL_PROTECTION_VARIANCE_MONITOR) #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 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 variance += ABS(current - last_temp); // no need for detection window now, a single change in variance is enough
last_temp = current; last_temp = current;
if (!NEAR_ZERO(variance)) { if (!NEAR_ZERO(variance)) {
variance_timer = millis() + SEC_TO_MS(period_seconds); variance_timer = millis() + SEC_TO_MS(VARIANCE_WINDOW);
variance = 0.0; variance = 0.0;
state = TRStable; // resume from where we detected the problem state = TRStable; // resume from where we detected the problem
} }
@ -2980,7 +2987,7 @@ void Temperature::init() {
state = TRMalfunction; state = TRMalfunction;
break; break;
} }
variance_timer = now + SEC_TO_MS(period_seconds); variance_timer = now + SEC_TO_MS(VARIANCE_WINDOW);
variance = 0.0; variance = 0.0;
last_temp = current; last_temp = current;
} }