🐛 Fix runout extra length (#26082)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
Co-authored-by: justvlade <7622616+justvlade@users.noreply.github.com>
This commit is contained in:
Giuliano Zaro 2023-07-27 01:38:59 +02:00 committed by GitHub
parent 79be07f9a4
commit fdad658e5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 16 deletions

View file

@ -47,7 +47,7 @@ bool FilamentMonitorBase::enabled = true,
#if HAS_FILAMENT_RUNOUT_DISTANCE #if HAS_FILAMENT_RUNOUT_DISTANCE
float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM; float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM;
volatile countdown_t RunoutResponseDelayed::mm_countdown; countdown_t RunoutResponseDelayed::mm_countdown;
#if ENABLED(FILAMENT_MOTION_SENSOR) #if ENABLED(FILAMENT_MOTION_SENSOR)
uint8_t FilamentSensorEncoder::motion_detected; uint8_t FilamentSensorEncoder::motion_detected;
#endif #endif

View file

@ -30,7 +30,8 @@
#include "../module/planner.h" #include "../module/planner.h"
#include "../module/stepper.h" // for block_t #include "../module/stepper.h" // for block_t
#include "../gcode/queue.h" #include "../gcode/queue.h"
#include "../feature/pause.h" #include "../feature/pause.h" // for did_pause_print
#include "../MarlinCore.h" // for printingIsActive()
#include "../inc/MarlinConfig.h" #include "../inc/MarlinConfig.h"
@ -50,9 +51,16 @@
#define HAS_FILAMENT_SWITCH 1 #define HAS_FILAMENT_SWITCH 1
#endif #endif
typedef Flags<8> runout_flags_t; typedef Flags<
#if NUM_MOTION_SENSORS > NUM_RUNOUT_SENSORS
NUM_MOTION_SENSORS
#else
NUM_RUNOUT_SENSORS
#endif
> runout_flags_t;
void event_filament_runout(const uint8_t extruder); void event_filament_runout(const uint8_t extruder);
inline bool should_monitor_runout() { return did_pause_print || printingIsActive(); }
template<class RESPONSE_T, class SENSOR_T> template<class RESPONSE_T, class SENSOR_T>
class TFilamentMonitor; class TFilamentMonitor;
@ -128,7 +136,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
// Give the response a chance to update its counter. // Give the response a chance to update its counter.
static void run() { static void run() {
if (enabled && !filament_ran_out && (printingIsActive() || did_pause_print)) { if (enabled && !filament_ran_out && should_monitor_runout()) {
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here
response.run(); response.run();
sensor.run(); sensor.run();
@ -340,8 +348,10 @@ class FilamentSensorBase {
typedef struct { typedef struct {
float runout[NUM_RUNOUT_SENSORS]; float runout[NUM_RUNOUT_SENSORS];
Flags<NUM_RUNOUT_SENSORS> runout_reset; // Reset runout later
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) #if ENABLED(FILAMENT_SWITCH_AND_MOTION)
float motion[NUM_MOTION_SENSORS]; float motion[NUM_MOTION_SENSORS];
Flags<NUM_MOTION_SENSORS> motion_reset; // Reset motion later
#endif #endif
} countdown_t; } countdown_t;
@ -350,7 +360,7 @@ class FilamentSensorBase {
// during a runout condition. // during a runout condition.
class RunoutResponseDelayed { class RunoutResponseDelayed {
private: private:
static volatile countdown_t mm_countdown; static countdown_t mm_countdown;
public: public:
static float runout_distance_mm; static float runout_distance_mm;
@ -389,26 +399,56 @@ class FilamentSensorBase {
} }
static void filament_present(const uint8_t extruder) { static void filament_present(const uint8_t extruder) {
if (mm_countdown.runout[extruder] < runout_distance_mm || did_pause_print) {
// Reset runout only if it is smaller than runout_distance or printing is paused.
// On Bowden systems retract may be larger than runout_distance_mm, so if retract
// was added leave it in place, or the following unretract will cause runout event.
mm_countdown.runout[extruder] = runout_distance_mm; mm_countdown.runout[extruder] = runout_distance_mm;
mm_countdown.runout_reset.clear(extruder);
}
else {
// If runout is larger than runout distance, we cannot reset right now, as Bowden and retract
// distance larger than runout_distance_mm leads to negative runout right after unretract.
// But we cannot ignore filament_present event. After unretract, runout will become smaller
// than runout_distance_mm and should be reset after that. So activate delayed reset.
mm_countdown.runout_reset.set(extruder);
}
} }
#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
if (mm_countdown.motion[extruder] < runout_distance_mm || did_pause_print) {
mm_countdown.motion[extruder] = runout_distance_mm; mm_countdown.motion[extruder] = runout_distance_mm;
mm_countdown.motion_reset.clear(extruder);
}
else
mm_countdown.motion_reset.set(extruder);
} }
#endif #endif
static void block_completed(const block_t * const b) { static void block_completed(const block_t * const b) {
if (b->steps.x || b->steps.y || b->steps.z || did_pause_print) { // Allow pause purge move to re-trigger runout state const int32_t esteps = b->steps.e;
// Only trigger on extrusion with XYZ movement to allow filament change and retract/recover. if (!esteps) return;
// No calculation unless paused or printing
if (!should_monitor_runout()) return;
// 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 int32_t steps = b->steps.e; const float mm = (b->direction_bits.e ? esteps : -esteps) * planner.mm_per_step[E_AXIS_N(e)];
const float mm = (b->direction_bits.e ? steps : -steps) * planner.mm_per_step[E_AXIS_N(e)];
if (e < NUM_RUNOUT_SENSORS) mm_countdown.runout[e] -= mm; if (e < NUM_RUNOUT_SENSORS) {
#if ENABLED(FILAMENT_SWITCH_AND_MOTION) mm_countdown.runout[e] -= mm;
if (e < NUM_MOTION_SENSORS) mm_countdown.motion[e] -= mm; if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset.
#endif
} }
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
if (e < NUM_MOTION_SENSORS) {
mm_countdown.motion[e] -= mm;
if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset.
}
#endif
} }
}; };