diff --git a/src/logic/feed_to_finda.cpp b/src/logic/feed_to_finda.cpp index e4b03e8..9b28ca6 100644 --- a/src/logic/feed_to_finda.cpp +++ b/src/logic/feed_to_finda.cpp @@ -12,7 +12,7 @@ #include "../debug.h" namespace logic { -void FeedToFinda::Reset(bool feedPhaseLimited, bool haltAtEnd) { +bool FeedToFinda::Reset(bool feedPhaseLimited, bool haltAtEnd) { dbg_logic_P(PSTR("\nFeed to FINDA\n\n")); state = EngagingIdler; this->feedPhaseLimited = feedPhaseLimited; @@ -20,12 +20,15 @@ void FeedToFinda::Reset(bool feedPhaseLimited, bool haltAtEnd) { ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off); mi::idler.Engage(mg::globals.ActiveSlot()); // We can't get any FINDA readings if the selector is at the wrong spot - move it accordingly if necessary - ms::selector.MoveToSlot(mg::globals.ActiveSlot()); + return ms::selector.MoveToSlot(mg::globals.ActiveSlot()) == ms::Selector::OperationResult::Accepted; } bool FeedToFinda::Step() { switch (state) { case EngagingIdler: + // A serious deadlock may occur at this spot in case of flickering FINDA. + // Therefore FeedToFinda::Reset returns false in case of Selector refusing to move. + // We don't have to check the FINDA state while the move is in progress. if (mi::idler.Engaged() && ms::selector.Slot() == mg::globals.ActiveSlot()) { dbg_logic_P(PSTR("Feed to Finda --> Idler engaged")); dbg_logic_fP(PSTR("Pulley start steps %u"), mpu::pulley.CurrentPosition_mm()); diff --git a/src/logic/feed_to_finda.h b/src/logic/feed_to_finda.h index cd25857..72ca682 100644 --- a/src/logic/feed_to_finda.h +++ b/src/logic/feed_to_finda.h @@ -33,7 +33,10 @@ struct FeedToFinda { /// * false feed phase is unlimited, can be interrupted by any button press after blanking time /// Beware: the function returns immediately without actually doing anything if the FINDA is "pressed", i.e. the filament is already at the FINDA /// @param haltAtEnd true if the Pulley's motion shall be brought into a halt (which is what LoadFilament wants, but not ToolChange) - void Reset(bool feedPhaseLimited, bool haltAtEnd); + /// @returns + /// * true if the operation has been successfully started. + /// * false if the selector refused to move to the desired spot (which can be caused by pressed FINDA) + bool Reset(bool feedPhaseLimited, bool haltAtEnd); /// @returns true if the state machine finished its job, false otherwise bool Step(); diff --git a/src/logic/tool_change.cpp b/src/logic/tool_change.cpp index 079117f..2330666 100644 --- a/src/logic/tool_change.cpp +++ b/src/logic/tool_change.cpp @@ -41,11 +41,15 @@ bool ToolChange::Reset(uint8_t param) { state = ProgressCode::UnloadingFilament; unl.Reset(mg::globals.ActiveSlot()); } else { - state = ProgressCode::FeedingToFinda; - error = ErrorCode::RUNNING; - dbg_logic_P(PSTR("Filament is not loaded --> load")); - mg::globals.SetFilamentLoaded(plannedSlot, mg::FilamentLoadState::InSelector); - feed.Reset(true, false); + if (feed.Reset(true, false)) { + state = ProgressCode::FeedingToFinda; + error = ErrorCode::RUNNING; + // mg::globals.SetFilamentLoaded(plannedSlot, mg::FilamentLoadState::InSelector); // this is set in feed @@TODO + dbg_logic_P(PSTR("Filament is not loaded --> load")); + } else { + // selector refused to move - FINDA problem suspected + GoToErrDisengagingIdler(ErrorCode::FINDA_DIDNT_SWITCH_OFF); + } } return true; } diff --git a/src/logic/unload_filament.cpp b/src/logic/unload_filament.cpp index 086fe9d..9d7ada9 100644 --- a/src/logic/unload_filament.cpp +++ b/src/logic/unload_filament.cpp @@ -46,9 +46,12 @@ void UnloadFilament::GoToRetractingFromFinda() { } void UnloadFilament::GoToRecheckFilamentAgainstFINDA() { - state = ProgressCode::FeedingToFinda; - error = ErrorCode::RUNNING; - feed.Reset(true, true); + if (feed.Reset(true, true)) { + state = ProgressCode::FeedingToFinda; + error = ErrorCode::RUNNING; + } else { + GoToErrDisengagingIdler(ErrorCode::FINDA_DIDNT_SWITCH_OFF); + } } bool UnloadFilament::StepInner() {