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
#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)
#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 FIL_MOTION1_PIN -1
@ -2074,7 +2077,7 @@
//#define FIL_MOTION8_STATE LOW
//#define FIL_MOTION8_PULLUP
//#define FIL_MOTION8_PULLDOWN
#endif
#endif // FILAMENT_SWITCH_AND_MOTION
#endif // FILAMENT_MOTION_SENSOR
#endif // FILAMENT_RUNOUT_DISTANCE_MM
#endif // FILAMENT_RUNOUT_SENSOR

View file

@ -33,7 +33,7 @@
FilamentMonitor runout;
bool FilamentMonitorBase::enabled = true,
FilamentMonitorBase::filament_ran_out; // = false
FilamentMonitorBase::filament_ran_out; // = false
#if ENABLED(HOST_ACTION_COMMANDS)
bool FilamentMonitorBase::host_handling; // = false
@ -51,6 +51,11 @@ bool FilamentMonitorBase::enabled = true,
#if ENABLED(FILAMENT_MOTION_SENSOR)
uint8_t FilamentSensorEncoder::motion_detected;
#endif
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
bool RunoutResponseDelayed::ignore_motion = false;
constexpr float RunoutResponseDelayed::motion_distance_mm;
#endif
#else
int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0
#endif
@ -72,6 +77,8 @@ bool FilamentMonitorBase::enabled = true,
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 ENABLED(TOOLCHANGE_MIGRATION_FEATURE)

View file

@ -46,8 +46,10 @@
#if ENABLED(FILAMENT_MOTION_SENSOR)
#define HAS_FILAMENT_MOTION 1
#endif
#if DISABLED(FILAMENT_MOTION_SENSOR) || ENABLED(FILAMENT_SWITCH_AND_MOTION)
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
#define HAS_FILAMENT_SWITCH 1
#endif
#else
#define HAS_FILAMENT_SWITCH 1
#endif
@ -129,6 +131,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
// Handle a block completion. RunoutResponseDelayed uses this to
// 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) {
if (enabled) {
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 ***************************/
@ -267,6 +276,7 @@ class FilamentSensorBase {
}
public:
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const b) {
// If the sensor wheel has moved since the last call to
// this method reset the runout counter for the extruder.
@ -303,6 +313,7 @@ class FilamentSensorBase {
}
public:
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const) {}
static void run() {
@ -332,6 +343,7 @@ class FilamentSensorBase {
TERN_(HAS_FILAMENT_SWITCH, static FilamentSensorSwitch switch_sensor);
public:
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const b) {
TERN_(HAS_FILAMENT_MOTION, encoder_sensor.block_completed(b));
TERN_(HAS_FILAMENT_SWITCH, switch_sensor.block_completed(b));
@ -362,10 +374,17 @@ class FilamentSensorBase {
class RunoutResponseDelayed {
private:
static countdown_t mm_countdown;
static bool ignore_motion; // Flag to ignore the encoder
public:
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() {
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i);
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
@ -377,24 +396,27 @@ class FilamentSensorBase {
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
static millis_t t = 0;
const millis_t ms = millis();
if (ELAPSED(ms, t)) {
t = millis() + 1000UL;
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i)
SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]);
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i)
SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]);
#endif
SERIAL_EOL();
}
if (PENDING(ms, t)) return;
t = ms + 1000UL;
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i)
SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]);
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i)
SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]);
#endif
SERIAL_EOL();
#endif
}
// Get runout status for all presence sensors and motion sensors
static runout_flags_t has_run_out() {
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);
// Runout based on filament 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
return runout_flags;
}
@ -419,8 +441,8 @@ class FilamentSensorBase {
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
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;
if (mm_countdown.motion[extruder] < motion_distance_mm || did_pause_print) {
mm_countdown.motion[extruder] = motion_distance_mm;
mm_countdown.motion_reset.clear(extruder);
}
else
@ -428,29 +450,42 @@ class FilamentSensorBase {
}
#endif
// Called from ISR context to indicate a block was completed
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
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
const uint8_t e = b->extruder;
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) {
mm_countdown.runout[e] -= mm;
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 (e < NUM_MOTION_SENSORS) {
if (!ignore_motion && 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
}
// 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
@ -478,11 +513,15 @@ class FilamentSensorBase {
return runout_flags;
}
// Called from ISR context to indicate a block was completed
static void block_completed(const block_t * const) { }
static void filament_present(const uint8_t extruder) {
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