|
|
|
@ -43,7 +43,7 @@
|
|
|
|
|
#define FILAMENT_RUNOUT_THRESHOLD 5
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void event_filament_runout();
|
|
|
|
|
void event_filament_runout(const uint8_t extruder);
|
|
|
|
|
|
|
|
|
|
template<class RESPONSE_T, class SENSOR_T>
|
|
|
|
|
class TFilamentMonitor;
|
|
|
|
@ -119,11 +119,41 @@ class TFilamentMonitor : public FilamentMonitorBase {
|
|
|
|
|
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here
|
|
|
|
|
response.run();
|
|
|
|
|
sensor.run();
|
|
|
|
|
const bool ran_out = response.has_run_out();
|
|
|
|
|
const uint8_t runout_flags = response.has_run_out();
|
|
|
|
|
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei());
|
|
|
|
|
#if MULTI_FILAMENT_SENSOR
|
|
|
|
|
#if ENABLED(WATCH_ALL_RUNOUT_SENSORS)
|
|
|
|
|
const bool ran_out = !!runout_flags; // any sensor triggers
|
|
|
|
|
uint8_t extruder = 0;
|
|
|
|
|
if (ran_out) {
|
|
|
|
|
uint8_t bitmask = runout_flags;
|
|
|
|
|
while (!(bitmask & 1)) {
|
|
|
|
|
bitmask >>= 1;
|
|
|
|
|
extruder++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
const bool ran_out = TEST(runout_flags, active_extruder); // suppress non active extruders
|
|
|
|
|
uint8_t extruder = active_extruder;
|
|
|
|
|
#endif
|
|
|
|
|
#else
|
|
|
|
|
const bool ran_out = !!runout_flags;
|
|
|
|
|
uint8_t extruder = active_extruder;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
|
|
|
|
if (runout_flags) {
|
|
|
|
|
SERIAL_ECHOPGM("Runout Sensors: ");
|
|
|
|
|
LOOP_L_N(i, 8) SERIAL_ECHO('0' + TEST(runout_flags, i));
|
|
|
|
|
SERIAL_ECHOPAIR(" -> ", extruder);
|
|
|
|
|
if (ran_out) SERIAL_ECHOPGM(" RUN OUT");
|
|
|
|
|
SERIAL_EOL();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (ran_out) {
|
|
|
|
|
filament_ran_out = true;
|
|
|
|
|
event_filament_runout();
|
|
|
|
|
event_filament_runout(extruder);
|
|
|
|
|
planner.synchronize();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -280,16 +310,17 @@ class FilamentSensorBase {
|
|
|
|
|
static inline void block_completed(const block_t* const) {}
|
|
|
|
|
|
|
|
|
|
static inline void run() {
|
|
|
|
|
const bool out = poll_runout_state(active_extruder);
|
|
|
|
|
if (!out) filament_present(active_extruder);
|
|
|
|
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
|
|
|
|
static bool was_out = false;
|
|
|
|
|
if (out != was_out) {
|
|
|
|
|
was_out = out;
|
|
|
|
|
SERIAL_ECHOPGM("Filament ");
|
|
|
|
|
SERIAL_ECHOPGM_P(out ? PSTR("OUT\n") : PSTR("IN\n"));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
LOOP_L_N(s, NUM_RUNOUT_SENSORS) {
|
|
|
|
|
const bool out = poll_runout_state(s);
|
|
|
|
|
if (!out) filament_present(s);
|
|
|
|
|
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
|
|
|
|
static uint8_t was_out; // = 0
|
|
|
|
|
if (out != TEST(was_out, s)) {
|
|
|
|
|
TBI(was_out, s);
|
|
|
|
|
SERIAL_ECHOLNPAIR_P(PSTR("Filament Sensor "), '0' + s, out ? PSTR(" OUT") : PSTR(" IN"));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -305,13 +336,13 @@ class FilamentSensorBase {
|
|
|
|
|
// during a runout condition.
|
|
|
|
|
class RunoutResponseDelayed {
|
|
|
|
|
private:
|
|
|
|
|
static volatile float runout_mm_countdown[EXTRUDERS];
|
|
|
|
|
static volatile float runout_mm_countdown[NUM_RUNOUT_SENSORS];
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static float runout_distance_mm;
|
|
|
|
|
|
|
|
|
|
static inline void reset() {
|
|
|
|
|
LOOP_L_N(i, EXTRUDERS) filament_present(i);
|
|
|
|
|
LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void run() {
|
|
|
|
@ -320,15 +351,17 @@ class FilamentSensorBase {
|
|
|
|
|
const millis_t ms = millis();
|
|
|
|
|
if (ELAPSED(ms, t)) {
|
|
|
|
|
t = millis() + 1000UL;
|
|
|
|
|
LOOP_L_N(i, EXTRUDERS)
|
|
|
|
|
LOOP_L_N(i, NUM_RUNOUT_SENSORS)
|
|
|
|
|
SERIAL_ECHOPAIR_P(i ? PSTR(", ") : PSTR("Remaining mm: "), runout_mm_countdown[i]);
|
|
|
|
|
SERIAL_EOL();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool has_run_out() {
|
|
|
|
|
return runout_mm_countdown[active_extruder] < 0;
|
|
|
|
|
static inline uint8_t has_run_out() {
|
|
|
|
|
uint8_t runout_flags = 0;
|
|
|
|
|
LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_mm_countdown[i] < 0) SBI(runout_flags, i);
|
|
|
|
|
return runout_flags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void filament_present(const uint8_t extruder) {
|
|
|
|
@ -353,13 +386,28 @@ class FilamentSensorBase {
|
|
|
|
|
class RunoutResponseDebounced {
|
|
|
|
|
private:
|
|
|
|
|
static constexpr int8_t runout_threshold = FILAMENT_RUNOUT_THRESHOLD;
|
|
|
|
|
static int8_t runout_count;
|
|
|
|
|
static int8_t runout_count[NUM_RUNOUT_SENSORS];
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static inline void reset() { runout_count = runout_threshold; }
|
|
|
|
|
static inline void run() { if (runout_count >= 0) runout_count--; }
|
|
|
|
|
static inline bool has_run_out() { return runout_count < 0; }
|
|
|
|
|
static inline void block_completed(const block_t* const) { }
|
|
|
|
|
static inline void filament_present(const uint8_t) { runout_count = runout_threshold; }
|
|
|
|
|
static inline void reset() {
|
|
|
|
|
LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void run() {
|
|
|
|
|
LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_count[i] >= 0) runout_count[i]--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline uint8_t has_run_out() {
|
|
|
|
|
uint8_t runout_flags = 0;
|
|
|
|
|
LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_count[i] < 0) SBI(runout_flags, i);
|
|
|
|
|
return runout_flags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void block_completed(const block_t* const) { }
|
|
|
|
|
|
|
|
|
|
static inline void filament_present(const uint8_t extruder) {
|
|
|
|
|
runout_count[extruder] = runout_threshold;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif // !HAS_FILAMENT_RUNOUT_DISTANCE
|
|
|
|
|