mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-07-06 22:47:27 -06:00
✨ FILAMENT_MOTION_DISTANCE_MM (#27812)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
4e1e7fa1b0
commit
1f31027fd2
3 changed files with 71 additions and 22 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue