FILAMENT_MOTION_DISTANCE_MM (#27812)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
MrKuskov 2025-05-04 09:11:23 +07:00 committed by GitHub
parent 4e1e7fa1b0
commit 1f31027fd2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 71 additions and 22 deletions

View file

@ -2037,8 +2037,11 @@
//#define FILAMENT_MOTION_SENSOR //#define FILAMENT_MOTION_SENSOR
#if ENABLED(FILAMENT_MOTION_SENSOR) #if ENABLED(FILAMENT_MOTION_SENSOR)
//#define FILAMENT_SWITCH_AND_MOTION //#define FILAMENT_SWITCH_AND_MOTION // Define separate pins below to sense motion
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
#define FILAMENT_MOTION_DISTANCE_MM 3.0 // (mm) Missing distance required to trigger runout
#define NUM_MOTION_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_MOTION#_PIN for each. #define NUM_MOTION_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_MOTION#_PIN for each.
//#define FIL_MOTION1_PIN -1 //#define FIL_MOTION1_PIN -1
@ -2074,7 +2077,7 @@
//#define FIL_MOTION8_STATE LOW //#define FIL_MOTION8_STATE LOW
//#define FIL_MOTION8_PULLUP //#define FIL_MOTION8_PULLUP
//#define FIL_MOTION8_PULLDOWN //#define FIL_MOTION8_PULLDOWN
#endif #endif // FILAMENT_SWITCH_AND_MOTION
#endif // FILAMENT_MOTION_SENSOR #endif // FILAMENT_MOTION_SENSOR
#endif // FILAMENT_RUNOUT_DISTANCE_MM #endif // FILAMENT_RUNOUT_DISTANCE_MM
#endif // FILAMENT_RUNOUT_SENSOR #endif // FILAMENT_RUNOUT_SENSOR

View file

@ -33,7 +33,7 @@
FilamentMonitor runout; FilamentMonitor runout;
bool FilamentMonitorBase::enabled = true, bool FilamentMonitorBase::enabled = true,
FilamentMonitorBase::filament_ran_out; // = false FilamentMonitorBase::filament_ran_out; // = false
#if ENABLED(HOST_ACTION_COMMANDS) #if ENABLED(HOST_ACTION_COMMANDS)
bool FilamentMonitorBase::host_handling; // = false bool FilamentMonitorBase::host_handling; // = false
@ -51,6 +51,11 @@ bool FilamentMonitorBase::enabled = true,
#if ENABLED(FILAMENT_MOTION_SENSOR) #if ENABLED(FILAMENT_MOTION_SENSOR)
uint8_t FilamentSensorEncoder::motion_detected; uint8_t FilamentSensorEncoder::motion_detected;
#endif #endif
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
bool RunoutResponseDelayed::ignore_motion = false;
constexpr float RunoutResponseDelayed::motion_distance_mm;
#endif
#else #else
int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0 int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0
#endif #endif
@ -72,6 +77,8 @@ bool FilamentMonitorBase::enabled = true,
void event_filament_runout(const uint8_t extruder) { void event_filament_runout(const uint8_t extruder) {
runout.init_for_restart(false); // Reset and disable
if (did_pause_print) return; // Action already in progress. Purge triggered repeated runout. if (did_pause_print) return; // Action already in progress. Purge triggered repeated runout.
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)

View file

@ -46,8 +46,10 @@
#if ENABLED(FILAMENT_MOTION_SENSOR) #if ENABLED(FILAMENT_MOTION_SENSOR)
#define HAS_FILAMENT_MOTION 1 #define HAS_FILAMENT_MOTION 1
#endif #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
#if DISABLED(FILAMENT_MOTION_SENSOR) || ENABLED(FILAMENT_SWITCH_AND_MOTION) #define HAS_FILAMENT_SWITCH 1
#endif
#else
#define HAS_FILAMENT_SWITCH 1 #define HAS_FILAMENT_SWITCH 1
#endif #endif
@ -129,6 +131,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
// Handle a block completion. RunoutResponseDelayed uses this to // Handle a block completion. RunoutResponseDelayed uses this to
// add up the length of filament moved while the filament is out. // add up the length of filament moved while the filament is out.
// Called from ISR context!
static void block_completed(const block_t * const b) { static void block_completed(const block_t * const b) {
if (enabled) { if (enabled) {
response.block_completed(b); response.block_completed(b);
@ -171,6 +174,12 @@ class TFilamentMonitor : public FilamentMonitorBase {
} }
} }
} }
// Reset after a filament runout or upon resuming a job
static void init_for_restart(const bool onoff=true) {
response.init_for_restart(onoff);
}
}; };
/*************************** FILAMENT PRESENCE SENSORS ***************************/ /*************************** FILAMENT PRESENCE SENSORS ***************************/
@ -267,6 +276,7 @@ class FilamentSensorBase {
} }
public: public:
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const b) { static void block_completed(const block_t * const b) {
// If the sensor wheel has moved since the last call to // If the sensor wheel has moved since the last call to
// this method reset the runout counter for the extruder. // this method reset the runout counter for the extruder.
@ -303,6 +313,7 @@ class FilamentSensorBase {
} }
public: public:
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const) {} static void block_completed(const block_t * const) {}
static void run() { static void run() {
@ -332,6 +343,7 @@ class FilamentSensorBase {
TERN_(HAS_FILAMENT_SWITCH, static FilamentSensorSwitch switch_sensor); TERN_(HAS_FILAMENT_SWITCH, static FilamentSensorSwitch switch_sensor);
public: public:
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const b) { static void block_completed(const block_t * const b) {
TERN_(HAS_FILAMENT_MOTION, encoder_sensor.block_completed(b)); TERN_(HAS_FILAMENT_MOTION, encoder_sensor.block_completed(b));
TERN_(HAS_FILAMENT_SWITCH, switch_sensor.block_completed(b)); TERN_(HAS_FILAMENT_SWITCH, switch_sensor.block_completed(b));
@ -362,10 +374,17 @@ class FilamentSensorBase {
class RunoutResponseDelayed { class RunoutResponseDelayed {
private: private:
static countdown_t mm_countdown; static countdown_t mm_countdown;
static bool ignore_motion; // Flag to ignore the encoder
public: public:
static float runout_distance_mm; static float runout_distance_mm;
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
static constexpr float motion_distance_mm = FILAMENT_MOTION_DISTANCE_MM;
#endif
static void set_ignore_motion(const bool ignore=true) { ignore_motion = ignore; }
static void reset() { static void reset() {
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i); for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i);
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
@ -377,24 +396,27 @@ class FilamentSensorBase {
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
static millis_t t = 0; static millis_t t = 0;
const millis_t ms = millis(); const millis_t ms = millis();
if (ELAPSED(ms, t)) { if (PENDING(ms, t)) return;
t = millis() + 1000UL; t = ms + 1000UL;
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i)
SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]); SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]);
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i)
SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]); SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]);
#endif #endif
SERIAL_EOL(); SERIAL_EOL();
}
#endif #endif
} }
// Get runout status for all presence sensors and motion sensors
static runout_flags_t has_run_out() { static runout_flags_t has_run_out() {
runout_flags_t runout_flags{0}; runout_flags_t runout_flags{0};
// Runout based on filament presence
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (mm_countdown.runout[i] < 0) runout_flags.set(i); for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (mm_countdown.runout[i] < 0) runout_flags.set(i);
// Runout based on filament motion
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) if (mm_countdown.motion[i] < 0) runout_flags.set(i); if (!ignore_motion)
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) if (mm_countdown.motion[i] < 0) runout_flags.set(i);
#endif #endif
return runout_flags; return runout_flags;
} }
@ -419,8 +441,8 @@ class FilamentSensorBase {
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
static void filament_motion_present(const uint8_t extruder) { static void filament_motion_present(const uint8_t extruder) {
// Same logic as filament_present // Same logic as filament_present
if (mm_countdown.motion[extruder] < runout_distance_mm || did_pause_print) { if (mm_countdown.motion[extruder] < motion_distance_mm || did_pause_print) {
mm_countdown.motion[extruder] = runout_distance_mm; mm_countdown.motion[extruder] = motion_distance_mm;
mm_countdown.motion_reset.clear(extruder); mm_countdown.motion_reset.clear(extruder);
} }
else else
@ -428,29 +450,42 @@ class FilamentSensorBase {
} }
#endif #endif
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const b) { static void block_completed(const block_t * const b) {
const int32_t esteps = b->steps.e;
if (!esteps) return;
// No calculation unless paused or printing // No calculation unless paused or printing
if (!should_monitor_runout()) return; if (!should_monitor_runout()) return;
// Only extrusion moves are examined
const int32_t esteps = b->steps.e;
if (!esteps) return;
// No need to ignore retract/unretract movement since they complement each other // No need to ignore retract/unretract movement since they complement each other
const uint8_t e = b->extruder; const uint8_t e = b->extruder;
const float mm = (b->direction_bits.e ? esteps : -esteps) * planner.mm_per_step[E_AXIS_N(e)]; const float mm = (b->direction_bits.e ? esteps : -esteps) * planner.mm_per_step[E_AXIS_N(e)];
// Apply E distance to runout countdown, reset if flagged
if (e < NUM_RUNOUT_SENSORS) { if (e < NUM_RUNOUT_SENSORS) {
mm_countdown.runout[e] -= mm; mm_countdown.runout[e] -= mm;
if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset. if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset.
} }
// Apply E distance to motion countdown, reset if flagged
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
if (e < NUM_MOTION_SENSORS) { if (!ignore_motion && e < NUM_MOTION_SENSORS) {
mm_countdown.motion[e] -= mm; mm_countdown.motion[e] -= mm;
if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset. if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset.
} }
#endif #endif
} }
// Reset after a filament runout or upon resuming a job
static void init_for_restart(const bool onoff=true) {
UNUSED(onoff);
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
reset();
set_ignore_motion(!onoff);
#endif
}
}; };
#else // !HAS_FILAMENT_RUNOUT_DISTANCE #else // !HAS_FILAMENT_RUNOUT_DISTANCE
@ -478,11 +513,15 @@ class FilamentSensorBase {
return runout_flags; return runout_flags;
} }
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const) { } static void block_completed(const block_t * const) { }
static void filament_present(const uint8_t extruder) { static void filament_present(const uint8_t extruder) {
runout_count[extruder] = runout_threshold; runout_count[extruder] = runout_threshold;
} }
// Reset after a filament runout or upon resuming a job
static void init_for_restart(const bool=true) { reset(); }
}; };
#endif // !HAS_FILAMENT_RUNOUT_DISTANCE #endif // !HAS_FILAMENT_RUNOUT_DISTANCE