From eb867817b5f4f74070137bad36c68c4be22b6fe7 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <thinkyhead@users.noreply.github.com>
Date: Mon, 5 Mar 2018 01:49:30 -0600
Subject: [PATCH] Prevent filament runout false positives (#9946)

---
 .travis.yml                   |  4 ++--
 Marlin/src/feature/runout.cpp |  3 ++-
 Marlin/src/feature/runout.h   | 20 ++++++++++++--------
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index a6348d9e4f..cab3e42d95 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -65,9 +65,9 @@ script:
   - opt_set POWER_SUPPLY 1
   - opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING ARC_P_CIRCLES CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS
   - opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS
-  - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_LED AUTO_POWER_CONTROL
+  - opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_LED AUTO_POWER_CONTROL NOZZLE_PARK_FEATURE FILAMENT_RUNOUT_SENSOR
   - opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE
-  - opt_enable_adv FWRETRACT MAX7219_DEBUG LED_CONTROL_MENU CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CODEPENDENT_XY_HOMING
+  - opt_enable_adv FWRETRACT MAX7219_DEBUG LED_CONTROL_MENU CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CODEPENDENT_XY_HOMING ADVANCED_PAUSE_FEATURE
   - opt_set ABL_GRID_POINTS_X 16
   - opt_set ABL_GRID_POINTS_Y 16
   - opt_set_adv FANMUX0_PIN 53
diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp
index 18f0eadebd..fde93e7f7a 100644
--- a/Marlin/src/feature/runout.cpp
+++ b/Marlin/src/feature/runout.cpp
@@ -32,7 +32,8 @@
 
 FilamentRunoutSensor runout;
 
-bool FilamentRunoutSensor::filament_ran_out; // = false;
+bool FilamentRunoutSensor::filament_ran_out; // = false
+uint8_t FilamentRunoutSensor::runout_count; // = 0
 
 void FilamentRunoutSensor::setup() {
 
diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h
index 692a36210f..37b4dbfba5 100644
--- a/Marlin/src/feature/runout.h
+++ b/Marlin/src/feature/runout.h
@@ -34,13 +34,15 @@
 
 #include "../inc/MarlinConfig.h"
 
+#define FIL_RUNOUT_THRESHOLD 5
+
 class FilamentRunoutSensor {
   public:
     FilamentRunoutSensor() {}
 
     static void setup();
 
-    FORCE_INLINE static void reset() { filament_ran_out = false; }
+    FORCE_INLINE static void reset() { runout_count = 0; filament_ran_out = false; }
 
     FORCE_INLINE static void run() {
       if ((IS_SD_PRINTING || print_job_timer.isRunning()) && check() && !filament_ran_out) {
@@ -51,28 +53,30 @@ class FilamentRunoutSensor {
     }
   private:
     static bool filament_ran_out;
+    static uint8_t runout_count;
 
     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;
+        const bool is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING;
       #else
         // Read the sensor for the active extruder
+        bool is_out;
         switch (active_extruder) {
-          case 0: return READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING;
-          case 1: return READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING;
+          case 0: is_out = READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING; break;
+          case 1: is_out = READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT_INVERTING; break;
           #if NUM_RUNOUT_SENSORS > 2
-            case 2: return READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING;
+            case 2: is_out = READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; break;
             #if NUM_RUNOUT_SENSORS > 3
-              case 3: return READ(FIL_RUNOUT4_PIN) == FIL_RUNOUT_INVERTING;
+              case 3: is_out = READ(FIL_RUNOUT4_PIN) == FIL_RUNOUT_INVERTING; break;
               #if NUM_RUNOUT_SENSORS > 4
-                case 4: return READ(FIL_RUNOUT5_PIN) == FIL_RUNOUT_INVERTING;
+                case 4: is_out = READ(FIL_RUNOUT5_PIN) == FIL_RUNOUT_INVERTING; break;
               #endif
             #endif
           #endif
         }
       #endif
-      return false;
+      return (is_out ? ++runout_count : (runout_count = 0)) > FIL_RUNOUT_THRESHOLD;
     }
 };
 
-- 
GitLab