diff --git a/.travis.yml b/.travis.yml
index 439735e4e1..629d6a311f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -93,9 +93,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/Marlin.h b/Marlin/Marlin.h
index b1ea99285b..70ed6342aa 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -191,10 +191,6 @@ void kill(const char*);
void quickstop_stepper();
-#if ENABLED(FILAMENT_RUNOUT_SENSOR)
- void handle_filament_runout();
-#endif
-
extern uint8_t marlin_debug_flags;
#define DEBUGGING(F) (marlin_debug_flags & (DEBUG_## F))
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 9b564ab7df..bce26cb803 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -286,6 +286,10 @@
#include "fwretract.h"
#endif
+#if ENABLED(FILAMENT_RUNOUT_SENSOR)
+ #include "runout.h"
+#endif
+
#if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER)
#include "buzzer.h"
#endif
@@ -660,10 +664,6 @@ float cartes[XYZ] = { 0 };
filwidth_delay_index[2] = { 0, -1 }; // Indexes into ring buffer
#endif
-#if ENABLED(FILAMENT_RUNOUT_SENSOR)
- static bool filament_ran_out = false;
-#endif
-
#if ENABLED(ADVANCED_PAUSE_FEATURE)
AdvancedPauseMenuResponse advanced_pause_menu_response;
float filament_change_unload_length[EXTRUDERS],
@@ -916,33 +916,6 @@ void setup_killpin() {
#endif
}
-#if ENABLED(FILAMENT_RUNOUT_SENSOR)
-
- void setup_filament_runout_pins() {
-
- #if ENABLED(FIL_RUNOUT_PULLUP)
- #define INIT_RUNOUT_PIN(P) SET_INPUT_PULLUP(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
-
void setup_powerhold() {
#if HAS_SUICIDE
OUT_WRITE(SUICIDE_PIN, HIGH);
@@ -6826,7 +6799,7 @@ inline void gcode_M17() {
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)
@@ -13224,18 +13197,6 @@ void prepare_move_to_destination() {
#endif
-#if ENABLED(FILAMENT_RUNOUT_SENSOR)
-
- void handle_filament_runout() {
- if (!filament_ran_out) {
- filament_ran_out = true;
- enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
- stepper.synchronize();
- }
- }
-
-#endif // FILAMENT_RUNOUT_SENSOR
-
void enable_all_steppers() {
#if ENABLED(AUTO_POWER_CONTROL)
powerManager.power_on();
@@ -13275,38 +13236,6 @@ 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
@@ -13322,7 +13251,7 @@ void disable_all_steppers() {
void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
- if (check_filament_runout()) handle_filament_runout();
+ runout.run();
#endif
if (commands_in_queue < BUFSIZE) get_available_commands();
@@ -13629,7 +13558,7 @@ void setup() {
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
- setup_filament_runout_pins();
+ runout.setup();
#endif
setup_killpin();
diff --git a/Marlin/runout.cpp b/Marlin/runout.cpp
new file mode 100644
index 0000000000..44ca694df1
--- /dev/null
+++ b/Marlin/runout.cpp
@@ -0,0 +1,61 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * runout.cpp - Runout sensor support
+ */
+
+#include "MarlinConfig.h"
+
+#if ENABLED(FILAMENT_RUNOUT_SENSOR)
+
+#include "runout.h"
+
+FilamentRunoutSensor runout;
+
+bool FilamentRunoutSensor::filament_ran_out; // = false
+uint8_t FilamentRunoutSensor::runout_count; // = 0
+
+void FilamentRunoutSensor::setup() {
+
+ #if ENABLED(FIL_RUNOUT_PULLUP)
+ #define INIT_RUNOUT_PIN(P) SET_INPUT_PULLUP(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/runout.h b/Marlin/runout.h
new file mode 100644
index 0000000000..d94c21ef64
--- /dev/null
+++ b/Marlin/runout.h
@@ -0,0 +1,85 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * runout.h - Runout sensor support
+ */
+
+#ifndef _RUNOUT_H_
+#define _RUNOUT_H_
+
+#include "cardreader.h"
+#include "printcounter.h"
+#include "stepper.h"
+#include "Marlin.h"
+
+#include "MarlinConfig.h"
+
+#define FIL_RUNOUT_THRESHOLD 5
+
+class FilamentRunoutSensor {
+ public:
+ FilamentRunoutSensor() {}
+
+ static void setup();
+
+ 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) {
+ filament_ran_out = true;
+ enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
+ stepper.synchronize();
+ }
+ }
+ 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
+ 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: 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: is_out = READ(FIL_RUNOUT3_PIN) == FIL_RUNOUT_INVERTING; break;
+ #if NUM_RUNOUT_SENSORS > 3
+ case 3: is_out = READ(FIL_RUNOUT4_PIN) == FIL_RUNOUT_INVERTING; break;
+ #if NUM_RUNOUT_SENSORS > 4
+ case 4: is_out = READ(FIL_RUNOUT5_PIN) == FIL_RUNOUT_INVERTING; break;
+ #endif
+ #endif
+ #endif
+ }
+ #endif
+ return (is_out ? ++runout_count : (runout_count = 0)) > FIL_RUNOUT_THRESHOLD;
+ }
+};
+
+extern FilamentRunoutSensor runout;
+
+#endif // _RUNOUT_H_