🐛 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:
parent
79be07f9a4
commit
fdad658e5f
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue