diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h index edeec7e08..d37a9eb2e 100644 --- a/Marlin/Conditionals_post.h +++ b/Marlin/Conditionals_post.h @@ -724,7 +724,6 @@ // Sensors #define HAS_FILAMENT_WIDTH_SENSOR (PIN_EXISTS(FILWIDTH)) - #define HAS_FIL_RUNOUT (PIN_EXISTS(FIL_RUNOUT)) // User Interface #define HAS_HOME (PIN_EXISTS(HOME)) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index d321fe128..ab86422aa 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -830,15 +830,16 @@ #endif /** - * Filament Runout Sensor - * A mechanical or opto endstop is used to check for the presence of filament. + * Filament Runout Sensors + * Mechanical or opto endstops are used to check for the presence of filament. * - * RAMPS-based boards use SERVO3_PIN. - * For other boards you may need to define FIL_RUNOUT_PIN. - * By default the firmware assumes HIGH = has filament, LOW = ran out + * 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. + * By default the firmware assumes HIGH=FILAMENT PRESENT. */ //#define FILAMENT_RUNOUT_SENSOR #if ENABLED(FILAMENT_RUNOUT_SENSOR) + #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. #define FIL_RUNOUT_INVERTING false // set to true to invert the logic of the sensor. #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. #define FILAMENT_RUNOUT_SCRIPT "M600" diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 251bdcb1d..fcf5e2f81 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -924,15 +924,30 @@ void setup_killpin() { #if ENABLED(FILAMENT_RUNOUT_SENSOR) - void setup_filrunoutpin() { - #if ENABLED(ENDSTOPPULLUP_FIL_RUNOUT) - SET_INPUT_PULLUP(FIL_RUNOUT_PIN); + void setup_filament_runout_pins() { + + #if ENABLED(FIL_RUNOUT_PULLUP) + #define INIT_RUNOUT_PIN(P) SET_INPUT_PULLUP(P) #else - SET_INPUT(FIL_RUNOUT_PIN); + #define INIT_RUNOUT_PIN(P) SET_INPUT(P) + #endif + + INIT_RUNOUT_PIN(FIL_RUNOUT_PIN); + #if NUM_RUNOUT_SENSORS > 1 + INIT_RUNOUT_PIN(FIL_RUNOUT2_PIN); + #if NUM_RUNOUT_SENSORS > 2 + INIT_RUNOUT_PIN(FIL_RUNOUT3_PIN); + #if NUM_RUNOUT_SENSORS > 3 + INIT_RUNOUT_PIN(FIL_RUNOUT4_PIN); + #if NUM_RUNOUT_SENSORS > 4 + INIT_RUNOUT_PIN(FIL_RUNOUT5_PIN); + #endif + #endif + #endif #endif } -#endif +#endif // FILAMENT_RUNOUT_SENSOR void setup_powerhold() { #if HAS_SUICIDE @@ -13289,6 +13304,38 @@ void disable_all_steppers() { disable_e_steppers(); } +#if ENABLED(FILAMENT_RUNOUT_SENSOR) + + FORCE_INLINE bool check_filament_runout() { + + if (IS_SD_PRINTING || print_job_timer.isRunning()) { + + #if NUM_RUNOUT_SENSORS < 2 + // A single sensor applying to all extruders + return READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; + #else + // Read the sensor for the active extruder + switch (active_extruder) { + case 0: return READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; + case 1: return READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; + #if NUM_RUNOUT_SENSORS > 2 + case 2: return READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; + #if NUM_RUNOUT_SENSORS > 3 + case 3: return READ(FIL_RUNOUT4_PIN) == FIL_RUNOUT_INVERTING; + #if NUM_RUNOUT_SENSORS > 4 + case 4: return READ(FIL_RUNOUT5_PIN) == FIL_RUNOUT_INVERTING; + #endif + #endif + #endif + } + #endif + + } + return false; + } + +#endif // FILAMENT_RUNOUT_SENSOR + /** * Manage several activities: * - Check for Filament Runout @@ -13304,11 +13351,7 @@ void disable_all_steppers() { void manage_inactivity(bool ignore_stepper_queue/*=false*/) { #if ENABLED(FILAMENT_RUNOUT_SENSOR) - if ((IS_SD_PRINTING || print_job_timer.isRunning()) - && READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING - && thermalManager.targetHotEnoughToExtrude(active_extruder) - ) - handle_filament_runout(); + if (check_filament_runout()) handle_filament_runout(); #endif if (commands_in_queue < BUFSIZE) get_available_commands(); @@ -13615,7 +13658,7 @@ void setup() { #endif #if ENABLED(FILAMENT_RUNOUT_SENSOR) - setup_filrunoutpin(); + setup_filament_runout_pins(); #endif setup_killpin(); diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h index 704a63318..ec6f42c40 100644 --- a/Marlin/SanityCheck.h +++ b/Marlin/SanityCheck.h @@ -400,11 +400,21 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, #endif /** - * Filament Runout needs a pin and either SD Support or Auto print start detection + * Filament Runout needs one or more pins and either SD Support or Auto print start detection */ #if ENABLED(FILAMENT_RUNOUT_SENSOR) - #if !HAS_FIL_RUNOUT + #if !PIN_EXISTS(FIL_RUNOUT) #error "FILAMENT_RUNOUT_SENSOR requires FIL_RUNOUT_PIN." + #elif NUM_RUNOUT_SENSORS > E_STEPPERS + #error "NUM_RUNOUT_SENSORS cannot exceed the number of E steppers." + #elif NUM_RUNOUT_SENSORS > 1 && !PIN_EXISTS(FIL_RUNOUT2) + #error "FILAMENT_RUNOUT_SENSOR with NUM_RUNOUT_SENSORS > 1 requires FIL_RUNOUT2_PIN." + #elif NUM_RUNOUT_SENSORS > 2 && !PIN_EXISTS(FIL_RUNOUT3) + #error "FILAMENT_RUNOUT_SENSOR with NUM_RUNOUT_SENSORS > 2 requires FIL_RUNOUT3_PIN." + #elif NUM_RUNOUT_SENSORS > 3 && !PIN_EXISTS(FIL_RUNOUT4) + #error "FILAMENT_RUNOUT_SENSOR with NUM_RUNOUT_SENSORS > 3 requires FIL_RUNOUT4_PIN." + #elif NUM_RUNOUT_SENSORS > 4 && !PIN_EXISTS(FIL_RUNOUT5) + #error "FILAMENT_RUNOUT_SENSOR with NUM_RUNOUT_SENSORS > 4 requires FIL_RUNOUT5_PIN." #elif DISABLED(SDSUPPORT) && DISABLED(PRINTJOB_TIMER_AUTOSTART) #error "FILAMENT_RUNOUT_SENSOR requires SDSUPPORT or PRINTJOB_TIMER_AUTOSTART." #elif DISABLED(ADVANCED_PAUSE_FEATURE)