From d3ca82d8c24b94a0073d5839ddca6569a6d013a1 Mon Sep 17 00:00:00 2001 From: Studiodyne Date: Sun, 18 Feb 2018 09:42:09 +0100 Subject: [PATCH] Support for multiple filament runout sensors --- Marlin/Configuration.h | 11 ++++--- Marlin/src/Marlin.cpp | 22 ++----------- Marlin/src/feature/pause.cpp | 2 +- Marlin/src/feature/runout.cpp | 38 ++++++++++++++++------ Marlin/src/feature/runout.h | 51 ++++++++++++++++++++++++++++-- Marlin/src/inc/Conditionals_post.h | 1 - Marlin/src/inc/SanityCheck.h | 14 ++++++-- 7 files changed, 98 insertions(+), 41 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index cf24356c63..d84508183f 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -852,15 +852,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 FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index a85e3a6fd5..671fd00702 100644 --- a/Marlin/src/Marlin.cpp +++ b/Marlin/src/Marlin.cpp @@ -216,20 +216,6 @@ void setup_killpin() { #endif } -#if ENABLED(FILAMENT_RUNOUT_SENSOR) - - void setup_filrunoutpin() { - #if ENABLED(FIL_RUNOUT_PULLUP) - SET_INPUT_PULLUP(FIL_RUNOUT_PIN); - #elif ENABLED(FIL_RUNOUT_PULLDOWN) - SET_INPUT_PULLDOWN(FIL_RUNOUT_PIN); - #else - SET_INPUT(FIL_RUNOUT_PIN); - #endif - } - -#endif - void setup_powerhold() { #if HAS_SUICIDE OUT_WRITE(SUICIDE_PIN, HIGH); @@ -336,11 +322,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(); + runout.run(); #endif if (commands_in_queue < BUFSIZE) get_available_commands(); @@ -661,7 +643,7 @@ void setup() { #endif #if ENABLED(FILAMENT_RUNOUT_SENSOR) - setup_filrunoutpin(); + runout.setup(); #endif setup_killpin(); diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 63c55fc914..846b370c98 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -500,7 +500,7 @@ void resume_print(const float &load_length/*=0*/, const float &purge_length/*=AD planner.set_e_position_mm(destination[E_AXIS] = current_position[E_AXIS] = resume_position[E_AXIS]); #if ENABLED(FILAMENT_RUNOUT_SENSOR) - filament_ran_out = false; + runout.reset(); #endif #if ENABLED(ULTIPANEL) diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index 8bc90947e3..18f0eadebd 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -24,21 +24,39 @@ * feature/runout.cpp - Runout sensor support */ -#include "../inc/MarlinConfig.h" +#include "../inc/MarlinConfigPre.h" #if ENABLED(FILAMENT_RUNOUT_SENSOR) -#include "../module/stepper.h" -#include "../gcode/queue.h" +#include "runout.h" -bool filament_ran_out = false; +FilamentRunoutSensor runout; -void handle_filament_runout() { - if (!filament_ran_out) { - filament_ran_out = true; - enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); - stepper.synchronize(); - } +bool FilamentRunoutSensor::filament_ran_out; // = false; + +void FilamentRunoutSensor::setup() { + + #if ENABLED(FIL_RUNOUT_PULLUP) + #define INIT_RUNOUT_PIN(P) SET_INPUT_PULLUP(P) + #elif ENABLED(FIL_RUNOUT_PULLDOWN) + #define INIT_RUNOUT_PIN(P) SET_INPUT_PULLDOWN(P) + #else + #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 // FILAMENT_RUNOUT_SENSOR diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index 36e5b086ce..3c9d312111 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -27,8 +27,55 @@ #ifndef _RUNOUT_H_ #define _RUNOUT_H_ -extern bool filament_ran_out; +#include "../sd/cardreader.h" +#include "../module/printcounter.h" +#include "../module/stepper.h" +#include "../gcode/queue.h" -void handle_filament_runout(); +#include "../inc/MarlinConfig.h" + +class FilamentRunoutSensor { + + FilamentRunoutSensor() {} + + static bool filament_ran_out; + static void setup(); + + FORCE_INLINE static reset() { filament_ran_out = false; } + + FORCE_INLINE static bool check() { + #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; + } + + FORCE_INLINE static void run() { + if ((IS_SD_PRINTING || print_job_timer.isRunning()) && check() && !filament_ran_out) { + filament_ran_out = true; + enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); + stepper.synchronize(); + } + } + +}; + +extern FilamentRunoutSensor runout; #endif // _RUNOUT_H_ diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 8ad079d3a6..6ea54dd427 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -792,7 +792,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/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index f5bd21ec21..ea78be3cec 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -429,11 +429,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)