From c462c2d4114eabc83eb1bd2bf7c66715fac5c3e2 Mon Sep 17 00:00:00 2001 From: justvlade Date: Sun, 16 Jul 2023 13:40:12 +0300 Subject: [PATCH 1/2] Change runout computation algorithm This should be considered as a draft idea, as there are some ideological contradictions in changing fundamental idea of runout. And needs approving that it does not harm other runout algorithms. This needs proper discussion with its pros and cons. I guess there is a reason(was not able to learn it though), why initial code excludes retraction/unretraction movement (or at least tries to do so). Initial idea of fixing issue #26061 Unlike patch #26082 this idea have alternative to conservative view. Instead of trying to figure out which E move is retract and which not, we take into account any E move, as those are connected to physical filament movement. All in all forward and backward movement will compensate itself. Modern slicers often introduce new approach to retraction movement. For example Super Slicer allows to enable retraction wipe, which makes retraction during horizontal movement. Also there is an old idea of filament unretract compensation, when unretract is slightly larger then retract movement. Not all printer needed this fix, but if we ignore retract/unretract we will loose those compensation move as well. This idea was inspired LCD_SHOW_E_TOTAL function. I do not actually checked the code of filament summary feed calculation, but from user experience LCD_SHOW_E_TOTAL shows actual filament movement with retraction and unretraction, as it may become smaller while printing. And as I understand it is considered to be precise. --- Marlin/src/feature/runout.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index a001459e9d99..dd7445fab3b1 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -389,18 +389,26 @@ class FilamentSensorBase { } static void filament_present(const uint8_t extruder) { - mm_countdown.runout[extruder] = runout_distance_mm; + if (mm_countdown.runout[extruder]steps.x || b->steps.y || b->steps.z || did_pause_print) { // Allow pause purge move to re-trigger runout state - // Only trigger on extrusion with XYZ movement to allow filament change and retract/recover. + if (b->steps.e) { // execute calculation if there is any extruder movement + // there is no need to ignore retract/unretract movement as they compensate each other const uint8_t e = b->extruder; const int32_t steps = b->steps.e; const float mm = (b->direction_bits.e ? steps : -steps) * planner.mm_per_step[E_AXIS_N(e)]; From ec2f12db7ba75477a9522f7ef1b6b66623e716b6 Mon Sep 17 00:00:00 2001 From: justvlade Date: Thu, 20 Jul 2023 02:05:09 +0300 Subject: [PATCH 2/2] Change runout computation algorithm This patch propose idea to take into account retract and unretract motion while computing runout left distance. Initial idea of fixing issue #26061 Unlike patch #26082 this code works not only for firmware retract, or classic retract, but also for software wipe retracts, when retract done with horizontal motion. Modern slicers often introduce new approach to retraction movement. For example Super Slicer allows to enable retraction wipe, which makes retraction during horizontal movement. Also there is an old idea of filament unretract compensation, when unretract is slightly larger then retract movement. Not all printer needed this fix, but if we ignore retract/unretract we will loose those compensation move as well. --- Marlin/src/feature/runout.h | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index dd7445fab3b1..0c1b2d212448 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -340,8 +340,10 @@ class FilamentSensorBase { typedef struct { float runout[NUM_RUNOUT_SENSORS]; + bool runout_reset[NUM_RUNOUT_SENSORS]; // flag to reset runout later if it is not possible to reset now #if ENABLED(FILAMENT_SWITCH_AND_MOTION) float motion[NUM_MOTION_SENSORS]; + bool motion_reset[NUM_MOTION_SENSORS]; // flag to reset motion later if it is not possible to reset now #endif } countdown_t; @@ -389,32 +391,50 @@ class FilamentSensorBase { } static void filament_present(const uint8_t extruder) { - if (mm_countdown.runout[extruder]steps.e) { // execute calculation if there is any extruder movement + if (b->steps.e && (did_pause_print || printingIsActive())) { + // execute calculation if there is any extruder movement + // and if printer on pause or it is printing // there is no need to ignore retract/unretract movement as they compensate each other const uint8_t e = b->extruder; const int32_t steps = b->steps.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) { + mm_countdown.runout[e] -= mm; + if (mm_countdown.runout_reset[e]) filament_present(e); // if reset is pending, try to reset + } #if ENABLED(FILAMENT_SWITCH_AND_MOTION) - if (e < NUM_MOTION_SENSORS) mm_countdown.motion[e] -= mm; + if (e < NUM_MOTION_SENSORS) { + mm_countdown.motion[e] -= mm; + if (mm_countdown.motion_reset[e]) filament_motion_present(e); // if reset is pending, try to reset + } #endif } }