From 66efa0b09b89b22eecc04ff370b1f4458f790116 Mon Sep 17 00:00:00 2001 From: InsanityAutomation Date: Sat, 12 Mar 2022 15:53:04 -0500 Subject: [PATCH] Initial commit - Flexible Runout Configuration M591 --- Marlin/src/feature/host_actions.cpp | 2 +- Marlin/src/feature/mmu/mmu2.cpp | 2 +- Marlin/src/feature/runout.cpp | 18 +- Marlin/src/feature/runout.h | 155 ++++++------------ Marlin/src/gcode/feature/pause/M600.cpp | 2 +- .../feature/runout/{M412.cpp => M591.cpp} | 70 +++++--- Marlin/src/gcode/gcode.cpp | 9 +- Marlin/src/gcode/gcode.h | 5 +- Marlin/src/gcode/host/M115.cpp | 2 +- Marlin/src/inc/Conditionals_adv.h | 3 - Marlin/src/inc/SanityCheck.h | 4 - Marlin/src/lcd/e3v2/jyersui/dwin.cpp | 32 ++-- Marlin/src/lcd/e3v2/proui/dwin.cpp | 16 +- Marlin/src/lcd/e3v2/proui/endstop_diag.cpp | 2 +- .../generic/filament_runout_screen.cpp | 21 +-- Marlin/src/lcd/extui/ui_api.cpp | 11 +- Marlin/src/lcd/extui/ui_api.h | 10 +- Marlin/src/lcd/menu/menu_advanced.cpp | 4 +- Marlin/src/lcd/menu/menu_configuration.cpp | 2 +- Marlin/src/lcd/menu/menu_filament.cpp | 2 +- Marlin/src/module/endstops.cpp | 22 ++- Marlin/src/module/settings.cpp | 66 +++++--- Marlin/src/module/stepper.cpp | 4 +- 23 files changed, 221 insertions(+), 243 deletions(-) rename Marlin/src/gcode/feature/runout/{M412.cpp => M591.cpp} (53%) diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp index c03a6bc597..3385076701 100644 --- a/Marlin/src/feature/host_actions.cpp +++ b/Marlin/src/feature/host_actions.cpp @@ -177,7 +177,7 @@ void HostUI::action(FSTR_P const fstr, const bool eol) { #endif #if HAS_FILAMENT_SENSOR if (runout.filament_ran_out) { // Disable a triggered sensor - runout.enabled = false; + runout.enabled[active_extruder] = false; runout.reset(); } #endif diff --git a/Marlin/src/feature/mmu/mmu2.cpp b/Marlin/src/feature/mmu/mmu2.cpp index 2813337c63..2bb69fa9c6 100644 --- a/Marlin/src/feature/mmu/mmu2.cpp +++ b/Marlin/src/feature/mmu/mmu2.cpp @@ -140,7 +140,7 @@ uint8_t MMU2::get_current_tool() { } #if EITHER(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR) - #define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE) + #define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != (runout.mode[0]==2 ? HIGH, LOW)) #endif void MMU2::mmu_loop() { diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index 98b6bd0510..7791637699 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -32,9 +32,9 @@ FilamentMonitor runout; -bool FilamentMonitorBase::enabled = true, +bool FilamentMonitorBase::enabled[HOTENDS] = {true}, FilamentMonitorBase::filament_ran_out; // = false - +uint8_t FilamentMonitorBase::mode[HOTENDS] = FILAMENT_RUNOUT_DEFAULT_MODE; // Initialized by settings.load #if ENABLED(HOST_ACTION_COMMANDS) bool FilamentMonitorBase::host_handling; // = false #endif @@ -45,15 +45,11 @@ bool FilamentMonitorBase::enabled = true, #include "../core/debug_out.h" #endif -#if HAS_FILAMENT_RUNOUT_DISTANCE - float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM; - volatile float RunoutResponseDelayed::runout_mm_countdown[NUM_RUNOUT_SENSORS]; - #if ENABLED(FILAMENT_MOTION_SENSOR) - uint8_t FilamentSensorEncoder::motion_detected; - #endif -#else - int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0 -#endif + +float RunoutResponseDelayed::runout_distance_mm[HOTENDS] = FILAMENT_RUNOUT_DISTANCE_MM; +volatile float RunoutResponseDelayed::runout_mm_countdown[HOTENDS]; +uint8_t FilamentSensorCore::motion_detected; + // // Filament Runout event handler diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index e74d857a79..2844264481 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -47,16 +47,14 @@ void event_filament_runout(const uint8_t extruder); template class TFilamentMonitor; -class FilamentSensorEncoder; -class FilamentSensorSwitch; +class FilamentSensorCore; class RunoutResponseDelayed; -class RunoutResponseDebounced; /********************************* TEMPLATE SPECIALIZATION *********************************/ typedef TFilamentMonitor< - TERN(HAS_FILAMENT_RUNOUT_DISTANCE, RunoutResponseDelayed, RunoutResponseDebounced), - TERN(FILAMENT_MOTION_SENSOR, FilamentSensorEncoder, FilamentSensorSwitch) + RunoutResponseDelayed, + FilamentSensorCore > FilamentMonitor; extern FilamentMonitor runout; @@ -65,7 +63,8 @@ extern FilamentMonitor runout; class FilamentMonitorBase { public: - static bool enabled, filament_ran_out; + static bool enabled[HOTENDS], filament_ran_out; + static uint8_t mode[HOTENDS]; #if ENABLED(HOST_ACTION_COMMANDS) static bool host_handling; @@ -99,10 +98,8 @@ class TFilamentMonitor : public FilamentMonitorBase { response.filament_present(extruder); } - #if HAS_FILAMENT_RUNOUT_DISTANCE - static float& runout_distance() { return response.runout_distance_mm; } - static void set_runout_distance(const_float_t mm) { response.runout_distance_mm = mm; } - #endif + static float& runout_distance(uint8_t extruder=0) { return response.runout_distance_mm[extruder]; } + static void set_runout_distance(const_float_t mm, uint8_t extruder=0) { response.runout_distance_mm[extruder] = mm; } // Handle a block completion. RunoutResponseDelayed uses this to // add up the length of filament moved while the filament is out. @@ -116,11 +113,11 @@ class TFilamentMonitor : public FilamentMonitorBase { // Give the response a chance to update its counter. static void run() { if (enabled && !filament_ran_out && (printingIsActive() || did_pause_print)) { - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here + cli(); // Prevent RunoutResponseDelayed::block_completed from accumulating here response.run(); sensor.run(); const uint8_t runout_flags = response.has_run_out(); - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei()); + sei(); #if MULTI_FILAMENT_SENSOR #if ENABLED(WATCH_ALL_RUNOUT_SENSORS) const bool ran_out = !!runout_flags; // any sensor triggers @@ -215,45 +212,49 @@ class FilamentSensorBase { static uint8_t poll_runout_states() { return poll_runout_pins() ^ uint8_t(0 #if NUM_RUNOUT_SENSORS >= 1 - | (FIL_RUNOUT1_STATE ? 0 : _BV(1 - 1)) + | ((runout.mode[0]==2) ? 0 : _BV(1 - 1)) #endif #if NUM_RUNOUT_SENSORS >= 2 - | (FIL_RUNOUT2_STATE ? 0 : _BV(2 - 1)) + | ((runout.mode[1]==2) ? 0 : _BV(2 - 1)) #endif #if NUM_RUNOUT_SENSORS >= 3 - | (FIL_RUNOUT3_STATE ? 0 : _BV(3 - 1)) + | ((runout.mode[2]==2) ? 0 : _BV(3 - 1)) #endif #if NUM_RUNOUT_SENSORS >= 4 - | (FIL_RUNOUT4_STATE ? 0 : _BV(4 - 1)) + | ((runout.mode[3]==2) ? 0 : _BV(4 - 1)) #endif #if NUM_RUNOUT_SENSORS >= 5 - | (FIL_RUNOUT5_STATE ? 0 : _BV(5 - 1)) + | ((runout.mode[4]==2) ? 0 : _BV(5 - 1)) #endif #if NUM_RUNOUT_SENSORS >= 6 - | (FIL_RUNOUT6_STATE ? 0 : _BV(6 - 1)) + | ((runout.mode[5]==2) ? 0 : _BV(6 - 1)) #endif #if NUM_RUNOUT_SENSORS >= 7 - | (FIL_RUNOUT7_STATE ? 0 : _BV(7 - 1)) + | ((runout.mode[6]==2) ? 0 : _BV(7 - 1)) #endif #if NUM_RUNOUT_SENSORS >= 8 - | (FIL_RUNOUT8_STATE ? 0 : _BV(8 - 1)) + | ((runout.mode[7]==2) ? 0 : _BV(8 - 1)) #endif ); } }; -#if ENABLED(FILAMENT_MOTION_SENSOR) - - /** - * This sensor uses a magnetic encoder disc and a Hall effect - * sensor (or a slotted disc and optical sensor). The state - * will toggle between 0 and 1 on filament movement. It can detect - * filament runout and stripouts or jams. - */ - class FilamentSensorEncoder : public FilamentSensorBase { - private: + class FilamentSensorCore : public FilamentSensorBase { + private: static uint8_t motion_detected; + static bool poll_runout_state(const uint8_t extruder) { + const uint8_t runout_states = poll_runout_states(); + #if MULTI_FILAMENT_SENSOR + if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()) + && !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled) + ) return TEST(runout_states, extruder); // A specific extruder ran out + #else + UNUSED(extruder); + #endif + return !!runout_states; // Any extruder ran out + } + static void poll_motion_sensor() { static uint8_t old_state; const uint8_t new_state = poll_runout_pins(), @@ -274,6 +275,7 @@ class FilamentSensorBase { public: static void block_completed(const block_t * const b) { + if (runout.mode[active_extruder]!=7) return; // If the sensor wheel has moved since the last call to // this method reset the runout counter for the extruder. if (TEST(motion_detected, b->extruder)) @@ -283,54 +285,32 @@ class FilamentSensorBase { motion_detected = 0; } - static void run() { poll_motion_sensor(); } - }; - -#else - - /** - * This is a simple endstop switch in the path of the filament. - * It can detect filament runout, but not stripouts or jams. - */ - class FilamentSensorSwitch : public FilamentSensorBase { - private: - static bool poll_runout_state(const uint8_t extruder) { - const uint8_t runout_states = poll_runout_states(); - #if MULTI_FILAMENT_SENSOR - if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()) - && !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled) - ) return TEST(runout_states, extruder); // A specific extruder ran out - #else - UNUSED(extruder); - #endif - return !!runout_states; // Any extruder ran out - } - - public: - static void block_completed(const block_t * const) {} - static void run() { - LOOP_L_N(s, NUM_RUNOUT_SENSORS) { - const bool out = poll_runout_state(s); - if (!out) filament_present(s); - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - static uint8_t was_out; // = 0 - if (out != TEST(was_out, s)) { - TBI(was_out, s); - SERIAL_ECHOLNF(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN")); - } - #endif + if(runout.mode[active_extruder]==7) + { + poll_motion_sensor(); + } + else if(runout.mode[active_extruder]!=0) { + LOOP_L_N(s, NUM_RUNOUT_SENSORS) { + const bool out = poll_runout_state(s); + if (!out) filament_present(s); + #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) + static uint8_t was_out; // = 0 + if (out != TEST(was_out, s)) { + TBI(was_out, s); + SERIAL_ECHOLNF(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN")); + } + #endif + } } } }; -#endif // !FILAMENT_MOTION_SENSOR + /********************************* RESPONSE TYPE *********************************/ -#if HAS_FILAMENT_RUNOUT_DISTANCE - // RunoutResponseDelayed triggers a runout event only if the length // of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed // during a runout condition. @@ -339,7 +319,7 @@ class FilamentSensorBase { static volatile float runout_mm_countdown[NUM_RUNOUT_SENSORS]; public: - static float runout_distance_mm; + static float runout_distance_mm[HOTENDS]; static void reset() { LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i); @@ -365,7 +345,7 @@ class FilamentSensorBase { } static void filament_present(const uint8_t extruder) { - runout_mm_countdown[extruder] = runout_distance_mm; + runout_mm_countdown[extruder] = runout_distance_mm[extruder]; } static void block_completed(const block_t * const b) { @@ -378,36 +358,3 @@ class FilamentSensorBase { } }; -#else // !HAS_FILAMENT_RUNOUT_DISTANCE - - // RunoutResponseDebounced triggers a runout event after a runout - // condition has been detected runout_threshold times in a row. - - class RunoutResponseDebounced { - private: - static constexpr int8_t runout_threshold = FILAMENT_RUNOUT_THRESHOLD; - static int8_t runout_count[NUM_RUNOUT_SENSORS]; - - public: - static void reset() { - LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i); - } - - static void run() { - LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_count[i] >= 0) runout_count[i]--; - } - - static uint8_t has_run_out() { - uint8_t runout_flags = 0; - LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_count[i] < 0) SBI(runout_flags, i); - return runout_flags; - } - - static void block_completed(const block_t * const) { } - - static void filament_present(const uint8_t extruder) { - runout_count[extruder] = runout_threshold; - } - }; - -#endif // !HAS_FILAMENT_RUNOUT_DISTANCE diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp index 1679c90687..0b5a4d8c03 100644 --- a/Marlin/src/gcode/feature/pause/M600.cpp +++ b/Marlin/src/gcode/feature/pause/M600.cpp @@ -88,7 +88,7 @@ void GcodeSuite::M600() { // In this case, for duplicating modes set DXC_ext to the extruder that ran out. #if MULTI_FILAMENT_SENSOR if (idex_is_duplicating()) - DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT2_STATE) ? 1 : 0; + DXC_ext = (READ(FIL_RUNOUT2_PIN) == (runout.mode[1]==2 ? HIGH, LOW) ? 1 : 0; #else DXC_ext = active_extruder; #endif diff --git a/Marlin/src/gcode/feature/runout/M412.cpp b/Marlin/src/gcode/feature/runout/M591.cpp similarity index 53% rename from Marlin/src/gcode/feature/runout/M412.cpp rename to Marlin/src/gcode/feature/runout/M591.cpp index bcf1e9f1b1..e80252677a 100644 --- a/Marlin/src/gcode/feature/runout/M412.cpp +++ b/Marlin/src/gcode/feature/runout/M591.cpp @@ -27,18 +27,37 @@ #include "../../gcode.h" #include "../../../feature/runout.h" + +void GcodeSuite::M412() { + SERIAL_ECHOLNPGM_P("M412 is Deprecated, please us M591."); + M591(); +} /** - * M412: Enable / Disable filament runout detection + 591: Configure filament runout detection * * Parameters * R : Reset the runout sensor * S : Reset and enable/disable the runout sensor * H : Enable/disable host handling of filament runout - * D : Extra distance to continue after runout is triggered + * L : Extra distance to continue after runout is triggered or motion interval + * D : Alias for L + * P : Mode : + 0 = none + 1 = simple sensor (high signal when filament present) + 2 = simple sensor (low signal when filament present) + 7 = motion encoder sensor */ -void GcodeSuite::M412() { - if (parser.seen("RS" - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, "D") +void GcodeSuite::M591() { + #if HOTENDS > 1 + if(parser.seen("E")) + const uint8_t tool = parser.value_ushort(); + else + tool = active_extruder; + #else + const uint8_t tool = 0; + #endif + + if (parser.seen("RSDP" TERN_(HOST_ACTION_COMMANDS, "H") )) { #if ENABLED(HOST_ACTION_COMMANDS) @@ -46,18 +65,24 @@ void GcodeSuite::M412() { #endif const bool seenR = parser.seen_test('R'), seenS = parser.seen('S'); if (seenR || seenS) runout.reset(); - if (seenS) runout.enabled = parser.value_bool(); - #if HAS_FILAMENT_RUNOUT_DISTANCE - if (parser.seen('D')) runout.set_runout_distance(parser.value_linear_units()); - #endif + if (seenS) runout.enabled[tool] = parser.value_bool(); + if (parser.seen('D')) runout.set_runout_distance(parser.value_linear_units(), tool); + if (parser.seen('L')) runout.set_runout_distance(parser.value_linear_units(), tool); + if (parser.seen('P')) { + uint8_t tmp_mode = parser.value_int(); + if(tmp_mode > 3 || tmp_mode==7) { + runout.mode[tool] = tmp_mode; + runout.reset(); + } + } + } else { SERIAL_ECHO_START(); SERIAL_ECHOPGM("Filament runout "); - serialprint_onoff(runout.enabled); - #if HAS_FILAMENT_RUNOUT_DISTANCE - SERIAL_ECHOPGM(" ; Distance ", runout.runout_distance(), "mm"); - #endif + serialprint_onoff(runout.enabled[active_extruder]); + SERIAL_ECHOPGM(" ; Distance ", runout.runout_distance(active_extruder), "mm"); + SERIAL_ECHOPGM(" ; Mode ", runout.mode[active_extruder]); #if ENABLED(HOST_ACTION_COMMANDS) SERIAL_ECHOPGM(" ; Host handling "); serialprint_onoff(runout.host_handling); @@ -66,16 +91,17 @@ void GcodeSuite::M412() { } } -void GcodeSuite::M412_report(const bool forReplay/*=true*/) { +void GcodeSuite::M591_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F(STR_FILAMENT_RUNOUT_SENSOR)); - SERIAL_ECHOPGM( - " M412 S", runout.enabled - #if HAS_FILAMENT_RUNOUT_DISTANCE - , " D", LINEAR_UNIT(runout.runout_distance()) - #endif - , " ; Sensor " - ); - serialprintln_onoff(runout.enabled); + LOOP_S_L_N(e, 1, HOTENDS) + SERIAL_ECHOPGM( + " M591 E", e + , " S", runout.enabled[e] + , " D", LINEAR_UNIT(runout.runout_distance(e)) + , " P", runout.mode[e] + , " ; " + ); + } #endif // HAS_FILAMENT_SENSOR diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index c365f8a67b..a31341d036 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -822,10 +822,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 @@ -892,6 +888,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 575: M575(); break; // M575: Set serial baudrate #endif + #if HAS_FILAMENT_SENSOR + case 412: M412(); break; // Alias to M591 + case 591: M591(); break; // M591 Configure filament runout detection + #endif + #if ENABLED(ADVANCED_PAUSE_FEATURE) case 600: M600(); break; // M600: Pause for Filament Change case 603: M603(); break; // M603: Configure Filament Change diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index 6e331c1273..46f4a5ddce 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -230,7 +230,6 @@ * M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR) * M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR) * M410 - Quickstop. Abort all planned moves. - * M412 - Enable / Disable Filament Runout Detection. (Requires FILAMENT_RUNOUT_SENSOR) * M413 - Enable / Disable Power-Loss Recovery. (Requires POWER_LOSS_RECOVERY) * M414 - Set language by index. (Requires LCD_LANGUAGE_2...) * M420 - Enable/Disable Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING or ABL) @@ -255,6 +254,7 @@ * M554 - Get or set IP gateway. (Requires enabled Ethernet port) * M569 - Enable stealthChop on an axis. (Requires at least one _DRIVER_TYPE to be TMC2130/2160/2208/2209/5130/5160) * M575 - Change the serial baud rate. (Requires BAUD_RATE_GCODE) + * M591 - Configure Filament Runout Detection. (Requires FILAMENT_RUNOUT_SENSOR) * M600 - Pause for filament change: "M600 X Y Z E L". (Requires ADVANCED_PAUSE_FEATURE) * M603 - Configure filament change: "M603 T U L". (Requires ADVANCED_PAUSE_FEATURE) * M605 - Set Dual X-Carriage movement mode: "M605 S [X] [R]". (Requires DUAL_X_CARRIAGE) @@ -979,7 +979,8 @@ private: #if HAS_FILAMENT_SENSOR static void M412(); - static void M412_report(const bool forReplay=true); + static void M591(); + static void M591_report(const bool forReplay=true); #endif #if HAS_MULTI_LANGUAGE diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index 36731c23da..50ff834d11 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -111,7 +111,7 @@ void GcodeSuite::M115() { // AUTOLEVEL (G29) cap_line(F("AUTOLEVEL"), ENABLED(HAS_AUTOLEVEL)); - // RUNOUT (M412, M600) + // RUNOUT (M591, M600) cap_line(F("RUNOUT"), ENABLED(FILAMENT_RUNOUT_SENSOR)); // Z_PROBE (G30) diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index d63395a719..f0999df41f 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -548,9 +548,6 @@ #if NUM_RUNOUT_SENSORS > 1 #define MULTI_FILAMENT_SENSOR 1 #endif - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - #define HAS_FILAMENT_RUNOUT_DISTANCE 1 - #endif #if ENABLED(MIXING_EXTRUDER) #define WATCH_ALL_RUNOUT_SENSORS #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index a94846275e..78117dc482 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1000,8 +1000,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "You can't enable FIL_RUNOUT7_PULLUP and FIL_RUNOUT7_PULLDOWN at the same time." #elif BOTH(FIL_RUNOUT8_PULLUP, FIL_RUNOUT8_PULLDOWN) #error "You can't enable FIL_RUNOUT8_PULLUP and FIL_RUNOUT8_PULLDOWN at the same time." - #elif FILAMENT_RUNOUT_DISTANCE_MM < 0 - #error "FILAMENT_RUNOUT_DISTANCE_MM must be greater than or equal to zero." #elif DISABLED(ADVANCED_PAUSE_FEATURE) static_assert(nullptr == strstr(FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with FILAMENT_RUNOUT_SENSOR."); #endif @@ -1238,8 +1236,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "MIXING_EXTRUDER is incompatible with SINGLENOZZLE." #elif ENABLED(DISABLE_INACTIVE_EXTRUDER) #error "MIXING_EXTRUDER is incompatible with DISABLE_INACTIVE_EXTRUDER." - #elif HAS_FILAMENT_RUNOUT_DISTANCE - #error "MIXING_EXTRUDER is incompatible with FILAMENT_RUNOUT_DISTANCE_MM." #endif #endif diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp index d384bae3e3..1e70a0656c 100644 --- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp @@ -2833,7 +2833,7 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/ #define ADVANCED_UNLOAD (ADVANCED_LOAD + ENABLED(ADVANCED_PAUSE_FEATURE)) #define ADVANCED_COLD_EXTRUDE (ADVANCED_UNLOAD + ENABLED(PREVENT_COLD_EXTRUSION)) #define ADVANCED_FILSENSORENABLED (ADVANCED_COLD_EXTRUDE + ENABLED(FILAMENT_RUNOUT_SENSOR)) - #define ADVANCED_FILSENSORDISTANCE (ADVANCED_FILSENSORENABLED + ENABLED(HAS_FILAMENT_RUNOUT_DISTANCE)) + #define ADVANCED_FILSENSORDISTANCE (ADVANCED_FILSENSORENABLED + 1) #define ADVANCED_POWER_LOSS (ADVANCED_FILSENSORDISTANCE + ENABLED(POWER_LOSS_RECOVERY)) #define ADVANCED_TOTAL ADVANCED_POWER_LOSS @@ -2923,24 +2923,22 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/ case ADVANCED_FILSENSORENABLED: if (draw) { Draw_Menu_Item(row, ICON_Extruder, F("Filament Sensor")); - Draw_Checkbox(row, runout.enabled); + Draw_Checkbox(row, runout.enabled[0]); } else { - runout.enabled = !runout.enabled; - Draw_Checkbox(row, runout.enabled); + runout.enabled = !runout.enabled[0]; + Draw_Checkbox(row, runout.enabled[0]); } break; - #if ENABLED(HAS_FILAMENT_RUNOUT_DISTANCE) - case ADVANCED_FILSENSORDISTANCE: - if (draw) { - Draw_Menu_Item(row, ICON_MaxAccE, F("Runout Distance")); - Draw_Float(runout.runout_distance(), row, false, 10); - } - else - Modify_Value(runout.runout_distance(), 0, 999, 10); - break; - #endif + case ADVANCED_FILSENSORDISTANCE: + if (draw) { + Draw_Menu_Item(row, ICON_MaxAccE, F("Runout Distance")); + Draw_Float(runout.runout_distance(), row, false, 10); + } + else + Modify_Value(runout.runout_distance(), 0, 999, 10); + break; #endif // FILAMENT_RUNOUT_SENSOR #if ENABLED(POWER_LOSS_RECOVERY) @@ -3829,11 +3827,11 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/ case TUNE_FILSENSORENABLED: if (draw) { Draw_Menu_Item(row, ICON_Extruder, F("Filament Sensor")); - Draw_Checkbox(row, runout.enabled); + Draw_Checkbox(row, runout.enabled[0]); } else { - runout.enabled = !runout.enabled; - Draw_Checkbox(row, runout.enabled); + runout.enabled = !runout.enabled[0]; + Draw_Checkbox(row, runout.enabled[0]); } break; #endif diff --git a/Marlin/src/lcd/e3v2/proui/dwin.cpp b/Marlin/src/lcd/e3v2/proui/dwin.cpp index 0a392cd563..93302406d4 100644 --- a/Marlin/src/lcd/e3v2/proui/dwin.cpp +++ b/Marlin/src/lcd/e3v2/proui/dwin.cpp @@ -2157,14 +2157,12 @@ void SetPID(celsius_t t, heater_id_t h) { #if HAS_FILAMENT_SENSOR void SetRunoutEnable() { runout.reset(); - runout.enabled = !runout.enabled; - Draw_Chkb_Line(CurrentMenu->line(), runout.enabled); + runout.enabled[0] = !runout.enabled[0]; + Draw_Chkb_Line(CurrentMenu->line(), runout.enabled[0]); DWIN_UpdateLCD(); } - #if HAS_FILAMENT_RUNOUT_DISTANCE - void ApplyRunoutDistance() { runout.set_runout_distance(MenuData.Value / MINUNITMULT); } - void SetRunoutDistance() { SetFloatOnClick(0, 999, UNITFDIGITS, runout.runout_distance(), ApplyRunoutDistance); } - #endif + void ApplyRunoutDistance() { runout.set_runout_distance(MenuData.Value / MINUNITMULT); } + void SetRunoutDistance() { SetFloatOnClick(0, 999, UNITFDIGITS, runout.runout_distance(), ApplyRunoutDistance); } #endif #if ENABLED(ADVANCED_PAUSE_FEATURE) @@ -2679,7 +2677,7 @@ void onDrawGetColorItem(MenuItemClass* menuitem, int8_t line) { } #if HAS_FILAMENT_SENSOR - void onDrawRunoutEnable(MenuItemClass* menuitem, int8_t line) { onDrawChkbMenu(menuitem, line, runout.enabled); } + void onDrawRunoutEnable(MenuItemClass* menuitem, int8_t line) { onDrawChkbMenu(menuitem, line, runout.enabled[0]); } #endif void onDrawPIDi(MenuItemClass* menuitem, int8_t line) { onDrawFloatMenu(menuitem, line, 2, unscalePID_i(*(float*)static_cast(menuitem)->value)); } @@ -3173,9 +3171,7 @@ void Draw_Move_Menu() { #if HAS_FILAMENT_SENSOR MENU_ITEM(ICON_Runout, GET_TEXT_F(MSG_RUNOUT_ENABLE), onDrawRunoutEnable, SetRunoutEnable); #endif - #if HAS_FILAMENT_RUNOUT_DISTANCE - EDIT_ITEM(ICON_Runout, F("Runout Distance"), onDrawPFloatMenu, SetRunoutDistance, &runout.runout_distance()); - #endif + EDIT_ITEM(ICON_Runout, F("Runout Distance"), onDrawPFloatMenu, SetRunoutDistance, &runout.runout_distance()); #if ENABLED(PREVENT_COLD_EXTRUSION) EDIT_ITEM(ICON_ExtrudeMinT, F("Extrude Min Temp."), onDrawPIntMenu, SetExtMinT, &HMI_data.ExtMinT); #endif diff --git a/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp b/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp index 74eb94e751..ab42b2f1d8 100644 --- a/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp +++ b/Marlin/src/lcd/e3v2/proui/endstop_diag.cpp @@ -100,7 +100,7 @@ void ESDiagClass::Update() { ES_REPORT(Z_MIN); #endif #if HAS_FILAMENT_SENSOR - draw_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE); + draw_es_state(READ(FIL_RUNOUT1_PIN) != (runout.mode[0]==2 ? HIGH, LOW); #endif DWIN_UpdateLCD(); } diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp index 68948b0c5e..a885d69cf5 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp @@ -34,14 +34,13 @@ void FilamentRunoutScreen::onRedraw(draw_mode_t what) { w.heading( GET_TEXT_F(MSG_FILAMENT)); w.toggle( 2, GET_TEXT_F(MSG_RUNOUT_SENSOR), getFilamentRunoutEnabled()); - #if HAS_FILAMENT_RUNOUT_DISTANCE - w.heading(GET_TEXT_F(MSG_RUNOUT_DISTANCE_MM)); - w.units(GET_TEXT_F(MSG_UNITS_MM)); - w.precision(0); - w.color(e_axis); - w.adjuster( 10, FPSTR(NUL_STR), getFilamentRunoutDistance_mm(), getFilamentRunoutEnabled()); - w.increments(); - #endif + w.heading(GET_TEXT_F(MSG_RUNOUT_DISTANCE_MM)); + w.units(GET_TEXT_F(MSG_UNITS_MM)); + w.precision(0); + w.color(e_axis); + w.adjuster( 10, FPSTR(NUL_STR), getFilamentRunoutDistance_mm(), getFilamentRunoutEnabled()); + w.increments(); + } bool FilamentRunoutScreen::onTouchHeld(uint8_t tag) { @@ -49,10 +48,8 @@ bool FilamentRunoutScreen::onTouchHeld(uint8_t tag) { const float increment = getIncrement(); switch (tag) { case 2: setFilamentRunoutEnabled(!getFilamentRunoutEnabled()); break; - #if HAS_FILAMENT_RUNOUT_DISTANCE - case 10: UI_DECREMENT(FilamentRunoutDistance_mm); break; - case 11: UI_INCREMENT(FilamentRunoutDistance_mm); break; - #endif + case 10: UI_DECREMENT(FilamentRunoutDistance_mm); break; + case 11: UI_INCREMENT(FilamentRunoutDistance_mm); break; default: return false; } diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp index bfcbc39d7b..9656e86f97 100644 --- a/Marlin/src/lcd/extui/ui_api.cpp +++ b/Marlin/src/lcd/extui/ui_api.cpp @@ -651,15 +651,12 @@ namespace ExtUI { } #if HAS_FILAMENT_SENSOR - bool getFilamentRunoutEnabled() { return runout.enabled; } - void setFilamentRunoutEnabled(const bool value) { runout.enabled = value; } + bool getFilamentRunoutEnabled(const extruder_t extruder/*=E0*/) { return runout.enabled[extruder]; } + void setFilamentRunoutEnabled(const bool value, const extruder_t extruder/*=E0*/) { runout.enabled[extruder] = value; } bool getFilamentRunoutState() { return runout.filament_ran_out; } void setFilamentRunoutState(const bool value) { runout.filament_ran_out = value; } - - #if HAS_FILAMENT_RUNOUT_DISTANCE - float getFilamentRunoutDistance_mm() { return runout.runout_distance(); } - void setFilamentRunoutDistance_mm(const_float_t value) { runout.set_runout_distance(constrain(value, 0, 999)); } - #endif + float getFilamentRunoutDistance_mm() { return runout.runout_distance(); } + void setFilamentRunoutDistance_mm(const_float_t value) { runout.set_runout_distance(constrain(value, 0, 999)); } #endif #if ENABLED(CASE_LIGHT_ENABLE) diff --git a/Marlin/src/lcd/extui/ui_api.h b/Marlin/src/lcd/extui/ui_api.h index 6753c53740..3d87d0208e 100644 --- a/Marlin/src/lcd/extui/ui_api.h +++ b/Marlin/src/lcd/extui/ui_api.h @@ -294,15 +294,13 @@ namespace ExtUI { #endif #if HAS_FILAMENT_SENSOR - bool getFilamentRunoutEnabled(); - void setFilamentRunoutEnabled(const bool); + bool getFilamentRunoutEnabled(const extruder_t extruder=E0); + void setFilamentRunoutEnabled(const bool, const extruder_t extruder=E0); bool getFilamentRunoutState(); void setFilamentRunoutState(const bool); + float getFilamentRunoutDistance_mm(); + void setFilamentRunoutDistance_mm(const_float_t); - #if HAS_FILAMENT_RUNOUT_DISTANCE - float getFilamentRunoutDistance_mm(); - void setFilamentRunoutDistance_mm(const_float_t); - #endif #endif #if ENABLED(CASE_LIGHT_ENABLE) diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp index 1bc9b9e88e..77728201c5 100644 --- a/Marlin/src/lcd/menu/menu_advanced.cpp +++ b/Marlin/src/lcd/menu/menu_advanced.cpp @@ -43,7 +43,7 @@ #include "../../module/temperature.h" #endif -#if HAS_FILAMENT_RUNOUT_DISTANCE +#if HAS_FILAMENT_SENSOR #include "../../feature/runout.h" #endif @@ -150,7 +150,7 @@ void menu_backlash(); #endif #endif - #if HAS_FILAMENT_RUNOUT_DISTANCE + #if HAS_FILAMENT_SENSOR editable.decimal = runout.runout_distance(); EDIT_ITEM_FAST(float3, MSG_RUNOUT_DISTANCE_MM, &editable.decimal, 1, 999, []{ runout.set_runout_distance(editable.decimal); }, true diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index b4e9287bd4..9c4164f7b6 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -550,7 +550,7 @@ void menu_configuration() { #endif #if HAS_FILAMENT_SENSOR - EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset); + EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled[active_extruder], runout.reset); #endif #if HAS_FANCHECK diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp index 9f432c405c..98278e7a6e 100644 --- a/Marlin/src/lcd/menu/menu_filament.cpp +++ b/Marlin/src/lcd/menu/menu_filament.cpp @@ -254,7 +254,7 @@ void menu_pause_option() { #if HAS_FILAMENT_SENSOR const bool still_out = runout.filament_ran_out; if (still_out) - EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled, runout.reset); + EDIT_ITEM(bool, MSG_RUNOUT_SENSOR, &runout.enabled[active_extruder], runout.reset); #else constexpr bool still_out = false; #endif diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 3dd6d8aeb6..57476d89f6 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -47,6 +47,10 @@ #include "../feature/joystick.h" #endif +#if HAS_FILAMENT_SENSOR + #include "../feature/runout.h" +#endif + #if HAS_BED_PROBE #include "probe.h" #endif @@ -570,8 +574,8 @@ void _O2 Endstops::report_states() { #if USES_Z_MIN_PROBE_PIN print_es_state(PROBE_TRIGGERED(), F(STR_Z_PROBE)); #endif - #if MULTI_FILAMENT_SENSOR - #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; state = FIL_RUNOUT##N##_STATE; break; + #if HAS_FILAMENT_SENSOR + #define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; break; LOOP_S_LE_N(i, 1, NUM_RUNOUT_SENSORS) { pin_t pin; uint8_t state; @@ -579,13 +583,23 @@ void _O2 Endstops::report_states() { default: continue; REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT) } + if(runout.mode[i]==1) + state = HIGH; + else + state = LOW; + SERIAL_ECHOPGM(STR_FILAMENT); if (i > 1) SERIAL_CHAR(' ', '0' + i); print_es_state(extDigitalRead(pin) != state); + SERIAL_ECHOPGM(": "); + if(runout.mode[i]==0) + SERIAL_ECHOLNF(F("Sensor Disabled")); + else if(extDigitalRead(pin) != state) + SERIAL_ECHOLNF(F("Fil Present")); + else + SERIAL_ECHOLNF(F("Fil Missing")); } #undef _CASE_RUNOUT - #elif HAS_FILAMENT_SENSOR - print_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE, F(STR_FILAMENT)); #endif TERN_(BLTOUCH, bltouch._reset_SW_mode()); diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index 6eb17d5d2e..1dccdb905e 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -235,8 +235,9 @@ typedef struct SettingsDataStruct { // // FILAMENT_RUNOUT_SENSOR // - bool runout_sensor_enabled; // M412 S - float runout_distance_mm; // M412 D + bool runout_sensor_enabled[HOTENDS]; // M591 S + float runout_distance_mm[HOTENDS]; // M591 D + uint8_t runout_mode[HOTENDS]; // M591 P // // ENABLE_LEVELING_FADE_HEIGHT @@ -793,19 +794,20 @@ void MarlinSettings::postprocess() { // { #if HAS_FILAMENT_SENSOR - const bool &runout_sensor_enabled = runout.enabled; + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_WRITE(runout.enabled[e]); + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_WRITE(runout.runout_distance(e)); + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_WRITE(runout.mode[e]); #else - constexpr int8_t runout_sensor_enabled = -1; + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_WRITE((int8_t)-1)); + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_WRITE((float)-0.0f)); + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_WRITE((uint8_t)0)); #endif - _FIELD_TEST(runout_sensor_enabled); - EEPROM_WRITE(runout_sensor_enabled); - - #if HAS_FILAMENT_RUNOUT_DISTANCE - const float &runout_distance_mm = runout.runout_distance(); - #else - constexpr float runout_distance_mm = 0; - #endif - EEPROM_WRITE(runout_distance_mm); } // @@ -1711,20 +1713,27 @@ void MarlinSettings::postprocess() { // Filament Runout Sensor // { - int8_t runout_sensor_enabled; + int8_t runout_sensor_enabled[HOTENDS]; _FIELD_TEST(runout_sensor_enabled); - EEPROM_READ(runout_sensor_enabled); + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_READ(runout_sensor_enabled); + float runout_distance_mm[HOTENDS]; + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_READ(runout_distance_mm[e]); + uint8_t runout_mode[HOTENDS]; + LOOP_S_L_N(e, 1, HOTENDS) + EEPROM_READ(runout_mode[e]); + #if HAS_FILAMENT_SENSOR - runout.enabled = runout_sensor_enabled < 0 ? FIL_RUNOUT_ENABLED_DEFAULT : runout_sensor_enabled; + LOOP_S_L_N(e, 1, HOTENDS) + runout.enabled[e] = runout_sensor_enabled[e] < 0 ? FIL_RUNOUT_ENABLED_DEFAULT : runout_sensor_enabled[e]; + LOOP_S_L_N(e, 1, HOTENDS) + if (!validating) runout.set_runout_distance(runout_distance_mm[e], e); + LOOP_S_L_N(e, 1, HOTENDS) + if (!validating) runout.mode[e] = runout_mode[e]; + runout.reset(); #endif - TERN_(HAS_FILAMENT_SENSOR, if (runout.enabled) runout.reset()); - - float runout_distance_mm; - EEPROM_READ(runout_distance_mm); - #if HAS_FILAMENT_RUNOUT_DISTANCE - if (!validating) runout.set_runout_distance(runout_distance_mm); - #endif } // @@ -2789,9 +2798,14 @@ void MarlinSettings::reset() { // #if HAS_FILAMENT_SENSOR - runout.enabled = FIL_RUNOUT_ENABLED_DEFAULT; + LOOP_S_L_N(e, 1, HOTENDS) + runout.enabled[e] = FIL_RUNOUT_ENABLED_DEFAULT; + LOOP_S_L_N(e, 1, HOTENDS) + runout.set_runout_distance(FILAMENT_RUNOUT_DISTANCE_MM, e); + LOOP_S_L_N(e, 1, HOTENDS) + runout.mode[e] = FILAMENT_RUNOUT_DEFAULT_MODE; + runout.reset(); - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, runout.set_runout_distance(FILAMENT_RUNOUT_DISTANCE_MM)); #endif // @@ -3481,7 +3495,7 @@ void MarlinSettings::reset() { // // Filament Runout Sensor // - TERN_(HAS_FILAMENT_SENSOR, gcode.M412_report(forReplay)); + TERN_(HAS_FILAMENT_SENSOR, gcode.M591_report(forReplay)); #if HAS_ETHERNET CONFIG_ECHO_HEADING("Ethernet"); diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index f83104fe9c..46a17b6591 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -113,7 +113,7 @@ Stepper stepper; // Singleton #include "../feature/mixing.h" #endif -#if HAS_FILAMENT_RUNOUT_DISTANCE +#if HAS_FILAMENT_SENSOR #include "../feature/runout.h" #endif @@ -1948,7 +1948,7 @@ uint32_t Stepper::block_phase_isr() { PAGE_SEGMENT_UPDATE_POS(E); } #endif - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, runout.block_completed(current_block)); + TERN_(HAS_FILAMENT_SENSOR, runout.block_completed(current_block)); discard_current_block(); } else {