diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 837716120d..760d3943e4 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -1908,12 +1908,11 @@ * RAMPS-based boards use SERVO3_PIN for the first runout sensor. * For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc. */ -//#define FILAMENT_RUNOUT_SENSOR +#define FILAMENT_RUNOUT_SENSOR #if ENABLED(FILAMENT_RUNOUT_SENSOR) - #define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500. - #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. + #define FIL_RUNOUT_ENABLED { true } // Default enabled state for sensors E0[, E1[, E2[, E3...]]]. Override with M591EnnSn followed by M500. + #define FIL_RUNOUT_MODE { 7 } // Default mode for sensors E0[, E1[, E2[, E3...]]]. 0:NONE 1:Switch NO 2:Switch NC 7:Motion Sensor Override with M591EnPnn - #define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present. #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. //#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder. @@ -1957,58 +1956,11 @@ // NOTE: After 'M412 H1' the host handles filament runout and this script does not apply. #define FILAMENT_RUNOUT_SCRIPT "M600" - // After a runout is detected, continue printing this length of filament - // before executing the runout script. Useful for a sensor at the end of - // a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead. - //#define FILAMENT_RUNOUT_DISTANCE_MM 25 - - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - // Enable this option to use an encoder disc that toggles the runout pin - // as the filament moves. (Be sure to set FILAMENT_RUNOUT_DISTANCE_MM - // large enough to avoid false positives.) - //#define FILAMENT_MOTION_SENSOR - - #if ENABLED(FILAMENT_MOTION_SENSOR) - //#define FILAMENT_SWITCH_AND_MOTION - #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - #define NUM_MOTION_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_MOTION#_PIN for each. - //#define FIL_MOTION1_PIN -1 - - // Override individually if the motion sensors vary - //#define FIL_MOTION1_STATE LOW - //#define FIL_MOTION1_PULLUP - //#define FIL_MOTION1_PULLDOWN - - //#define FIL_MOTION2_STATE LOW - //#define FIL_MOTION2_PULLUP - //#define FIL_MOTION2_PULLDOWN - - //#define FIL_MOTION3_STATE LOW - //#define FIL_MOTION3_PULLUP - //#define FIL_MOTION3_PULLDOWN - - //#define FIL_MOTION4_STATE LOW - //#define FIL_MOTION4_PULLUP - //#define FIL_MOTION4_PULLDOWN - - //#define FIL_MOTION5_STATE LOW - //#define FIL_MOTION5_PULLUP - //#define FIL_MOTION5_PULLDOWN - - //#define FIL_MOTION6_STATE LOW - //#define FIL_MOTION6_PULLUP - //#define FIL_MOTION6_PULLDOWN - - //#define FIL_MOTION7_STATE LOW - //#define FIL_MOTION7_PULLUP - //#define FIL_MOTION7_PULLDOWN - - //#define FIL_MOTION8_STATE LOW - //#define FIL_MOTION8_PULLUP - //#define FIL_MOTION8_PULLDOWN - #endif - #endif - #endif + // In Mode 1 or 2, continue printing this length of filament after a run out occurs before executing the + // runout script. Useful for a sensor at the end of a feed tube or debounce on a flakey sensor. + // In Mode 7, extrusion distance to expect a change of state. + // Override with M591EnLnn + #define FILAMENT_RUNOUT_DISTANCE_MM 5 #endif //=========================================================================== @@ -2431,7 +2383,7 @@ * P1 Raise the nozzle always to Z-park height. * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. */ -//#define NOZZLE_PARK_FEATURE +#define NOZZLE_PARK_FEATURE #if ENABLED(NOZZLE_PARK_FEATURE) // Specify a park position as { X, Y, Z_raise } diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index cf203c447d..85dfa993bf 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -2655,7 +2655,7 @@ * Currently handles M108, M112, M410, M876 * NOTE: Not yet implemented for all platforms. */ -//#define EMERGENCY_PARSER +#define EMERGENCY_PARSER /** * Realtime Reporting (requires EMERGENCY_PARSER) @@ -2888,7 +2888,7 @@ * * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park. */ -//#define ADVANCED_PAUSE_FEATURE +#define ADVANCED_PAUSE_FEATURE #if ENABLED(ADVANCED_PAUSE_FEATURE) #define PAUSE_PARK_RETRACT_FEEDRATE 60 // (mm/s) Initial retract feedrate. #define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract. diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index 0a3084dbaa..0c470e40cd 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -60,7 +60,6 @@ template class TFilamentMonitor; class FilamentSensorCore; class RunoutResponseDelayed; -class RunoutResponseDebounced; /********************************* TEMPLATE SPECIALIZATION *********************************/ @@ -249,14 +248,14 @@ class FilamentSensorCore : public FilamentSensorBase { change = old_state ^ new_state; old_state = new_state; - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - if (change) { - SERIAL_ECHOPGM("Motion detected:"); - for(uint8_t e = 0; e < NUM_RUNOUT_SENSORS; ++e) - if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e); - SERIAL_EOL(); - } - #endif + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + if (change) { + SERIAL_ECHOPGM("Motion detected:"); + for (uint8_t e = 0; e < TERN(FILAMENT_SWITCH_AND_MOTION, NUM_MOTION_SENSORS, NUM_RUNOUT_SENSORS); ++e) + if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e); + SERIAL_EOL(); + } + #endif motion_detected |= change; } @@ -304,12 +303,12 @@ typedef struct { #endif } countdown_t; -// RunoutResponseDelayed triggers a runout event only if the length -// of filament specified by FIL_RUNOUT_DISTANCE_MM has been fed -// during a runout condition. -class RunoutResponseDelayed { - private: - static countdown_t mm_countdown; + // RunoutResponseDelayed triggers a runout event only if the length + // of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed + // during a runout condition. + class RunoutResponseDelayed { + private: + static countdown_t mm_countdown; public: static float runout_distance_mm[NUM_RUNOUT_SENSORS]; @@ -322,33 +321,83 @@ class RunoutResponseDelayed { #endif } - static void run() { - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - static millis_t t = 0; - const millis_t ms = millis(); - if (ELAPSED(ms, t)) { - t = millis() + 1000UL; - for(uint8_t i; i < NUM_RUNOUT_SENSORS; ++i) - SERIAL_ECHO(i ? F(", ") : F("Remaining mm: "), mm_countdown[i]); + static void run() { + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + static millis_t t = 0; + const millis_t ms = millis(); + if (ELAPSED(ms, t)) { + t = millis() + 1000UL; + for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) + SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]); #if ENABLED(FILAMENT_SWITCH_AND_MOTION) for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]); #endif - SERIAL_EOL(); - } - #endif - } + SERIAL_EOL(); + } + #endif + } - static runout_flags_t has_run_out() { - runout_flags_t runout_flags{0}; - for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (runout_count[i] < 0) runout_flags.set(i); + static runout_flags_t has_run_out() { + runout_flags_t runout_flags{0}; + for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (mm_countdown.runout[i] < 0) runout_flags.set(i); + #if ENABLED(FILAMENT_SWITCH_AND_MOTION) + for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) if (mm_countdown.motion[i] < 0) runout_flags.set(i); + #endif return runout_flags; - } - - static void block_completed(const block_t * const) { } + } static void filament_present(const uint8_t extruder) { - runout_count[extruder] = runout_distance_mm[extruder]; + if (mm_countdown.runout[extruder] < runout_distance_mm[extruder] || did_pause_print) { + // Reset runout only if it is smaller than runout_distance or printing is paused. + // On Bowden systems retract may be larger than runout_distance_mm, so if retract + // was added leave it in place, or the following unretract will cause runout event. + mm_countdown.runout[extruder] = runout_distance_mm[extruder]; + mm_countdown.runout_reset.clear(extruder); + } + else { + // If runout is larger than runout distance, we cannot reset right now, as Bowden and retract + // distance larger than runout_distance_mm leads to negative runout right after unretract. + // But we cannot ignore filament_present event. After unretract, runout will become smaller + // than runout_distance_mm and should be reset after that. So activate delayed reset. + mm_countdown.runout_reset.set(extruder); + } + } + + #if ENABLED(FILAMENT_SWITCH_AND_MOTION) + static void filament_motion_present(const uint8_t extruder) { + // Same logic as filament_present + if (mm_countdown.motion[extruder] < runout_distance_mm || did_pause_print) { + mm_countdown.motion[extruder] = runout_distance_mm; + mm_countdown.motion_reset.clear(extruder); + } + else + mm_countdown.motion_reset.set(extruder); + } + #endif + + static void block_completed(const block_t * const b) { + const int32_t esteps = b->steps.e; + if (!esteps) return; + + // No calculation unless paused or printing + if (!should_monitor_runout()) return; + + // No need to ignore retract/unretract movement since they complement each other + const uint8_t e = b->extruder; + const float mm = (b->direction_bits.e ? esteps : -esteps) * planner.mm_per_step[E_AXIS_N(e)]; + + if (e < NUM_RUNOUT_SENSORS) { + mm_countdown.runout[e] -= mm; + if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset. + } + + #if ENABLED(FILAMENT_SWITCH_AND_MOTION) + if (e < NUM_MOTION_SENSORS) { + mm_countdown.motion[e] -= mm; + if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset. + } + #endif } }; diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 0d501dcd30..de35ccc666 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -865,10 +865,6 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 407: M407(); break; // M407: Display measured filament diameter #endif - #if HAS_FILAMENT_SENSOR - case 412: M412(); break; // M412: Enable/Disable filament runout detection - #endif - #if HAS_MULTI_LANGUAGE case 414: M414(); break; // M414: Select multi language menu #endif diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index bacc189a8e..8790074329 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -58,6 +58,10 @@ #include "probe.h" #endif +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + #include "../feature/runout.h" +#endif + Endstops endstops; // private: