From 257e45809995f8ef1613c681db0dc726c30a2ccd Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 28 Dec 2022 12:20:59 +0100 Subject: [PATCH] Finish EjectFilament operation --- src/logic/eject_filament.cpp | 51 +++++++++++++++++++++++++----------- src/logic/eject_filament.h | 4 +++ src/logic/error_codes.h | 2 ++ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/logic/eject_filament.cpp b/src/logic/eject_filament.cpp index 223eacb..8cdfa9b 100644 --- a/src/logic/eject_filament.cpp +++ b/src/logic/eject_filament.cpp @@ -9,6 +9,7 @@ #include "../modules/permanent_storage.h" #include "../modules/pulley.h" #include "../modules/selector.h" +#include "../modules/user_input.h" #include "../debug.h" namespace logic { @@ -23,10 +24,7 @@ bool EjectFilament::Reset(uint8_t param) { error = ErrorCode::RUNNING; slot = param; - if (mg::globals.FilamentLoaded() == mg::FilamentLoadState::NotLoaded) { - FinishedOK(); - dbg_logic_P(PSTR("Already ejected")); - } else if (mg::globals.FilamentLoaded() >= mg::FilamentLoadState::AtPulley) { + if (mg::globals.FilamentLoaded() >= mg::FilamentLoadState::AtPulley) { state = ProgressCode::UnloadingFilament; unl.Reset(param); //@@TODO probably act on active extruder only } else { @@ -38,8 +36,9 @@ bool EjectFilament::Reset(uint8_t param) { void EjectFilament::MoveSelectorAside() { state = ProgressCode::ParkingSelector; const uint8_t selectorParkedPos = (slot <= 2) ? 4 : 0; - mi::idler.Engage(slot); - ms::selector.MoveToSlot(selectorParkedPos); + if (ms::selector.MoveToSlot(selectorParkedPos) == ms::Selector::OperationResult::Refused) { + GoToErrDisengagingIdler(ErrorCode::FINDA_FLICKERS); + } } bool EjectFilament::StepInner() { @@ -54,26 +53,46 @@ bool EjectFilament::StepInner() { break; case ProgressCode::ParkingSelector: if (mm::motion.QueueEmpty()) { // selector parked aside + state = ProgressCode::EngagingIdler; + mi::idler.Engage(slot); + } + break; + case ProgressCode::EngagingIdler: + if (mi::idler.Engaged()) { state = ProgressCode::EjectingFilament; mpu::pulley.InitAxis(); - mpu::pulley.PlanMove(-config::filamentMinLoadedToMMU, config::pulleySlowFeedrate); + mpu::pulley.PlanMove(config::ejectFromCuttingEdge, config::pulleySlowFeedrate); } break; case ProgressCode::EjectingFilament: if (mm::motion.QueueEmpty()) { // filament ejected - state = ProgressCode::DisengagingIdler; - mi::idler.Disengage(); + GoToErrDisengagingIdler(ErrorCode::FILAMENT_EJECTED); } break; - case ProgressCode::DisengagingIdler: - if (mi::idler.Disengaged()) { // idler disengaged - mpu::pulley.Disable(); - mg::globals.SetFilamentLoaded(mg::globals.ActiveSlot(), mg::FilamentLoadState::NotLoaded); - FinishedOK(); + case ProgressCode::ERRDisengagingIdler: + ErrDisengagingIdler(); + return false; + case ProgressCode::ERRWaitingForUser: { + // waiting for user buttons and/or a command from the printer + mui::Event ev = mui::userInput.ConsumeEvent(); + switch (ev) { + case mui::Event::Middle: + switch (error) { + case ErrorCode::FILAMENT_EJECTED: // the user clicked "Done", we can finish the Eject operation + FinishedOK(); + break; + case ErrorCode::FINDA_FLICKERS: + MoveSelectorAside(); + break; + default: + break; + } + default: + break; } - break; + return false; + } case ProgressCode::OK: - dbg_logic_fP(PSTR("FilamentLoadState after Eject %d"), mg::globals.FilamentLoaded()); return true; default: // we got into an unhandled state, better report it state = ProgressCode::ERRInternal; diff --git a/src/logic/eject_filament.h b/src/logic/eject_filament.h index 998d966..fd43d9b 100644 --- a/src/logic/eject_filament.h +++ b/src/logic/eject_filament.h @@ -19,7 +19,11 @@ static constexpr modules::motion::P_speed_t ejectSpeed = 1000.0_P_mm_s; //@@TODO /// - If there is still some filament detected by PINDA unload it first. /// - If we want to eject fil 0-2, move selector to position 4 (right). /// - If we want to eject fil 3-4, move selector to position 0 (left) +/// - emit a message to the user: Filament ejected, press Continue to confirm removal and finish (or something like that) /// Optionally, we can also move the selector to its service position in the future. +/// +/// Technically, the hardest part is the UI - emitting a message. But, we have the MMU error screens. +/// The Eject message is not an error, but we'll leverage existing infrastructure of error screens + user input to model a nice UI dialog. class EjectFilament : public CommandBase { public: inline EjectFilament() diff --git a/src/logic/error_codes.h b/src/logic/error_codes.h index 651a302..fc686ca 100644 --- a/src/logic/error_codes.h +++ b/src/logic/error_codes.h @@ -49,6 +49,8 @@ enum class ErrorCode : uint_fast16_t { FINDA_FLICKERS = 0x800a, ///< FINDA flickers - seems to be badly calibrated and happens to be pressed at spots where it used to be not pressed before. ///< The user is obliged to inspect FINDA and tune its switching + FILAMENT_EJECTED = 0x800b, ///< Filament was ejected, waiting for user input - technically, this is not an error + QUEUE_FULL = 0x802b, ///< E32811 internal logic error - attempt to move with a full queue VERSION_MISMATCH = 0x802c, ///< E32812 internal error of the printer - incompatible version of the MMU FW