diff --git a/src/logic/CMakeLists.txt b/src/logic/CMakeLists.txt index 2b2122d..36bfad8 100644 --- a/src/logic/CMakeLists.txt +++ b/src/logic/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources( feed_to_finda.cpp load_filament.cpp no_command.cpp + retract_from_finda.cpp set_mode.cpp tool_change.cpp unload_filament.cpp diff --git a/src/logic/feed_to_finda.cpp b/src/logic/feed_to_finda.cpp index fd363c5..294f13e 100644 --- a/src/logic/feed_to_finda.cpp +++ b/src/logic/feed_to_finda.cpp @@ -32,29 +32,14 @@ bool FeedToFinda::Step() { if (mf::finda.Pressed() || (feedPhaseLimited && mui::userInput.AnyEvent())) { // @@TODO probably also a command from the printer mm::motion.AbortPlannedMoves(); // stop pushing filament // FINDA triggered - that means it works and detected the filament tip - state = UnloadBackToPTFE; - mm::motion.PlanMove(-config::cuttingEdgeToFindaMidpoint, config::pulleyFeedrate); + state = OK; } else if (mm::motion.QueueEmpty()) { // all moves have been finished and FINDA didn't switch on state = Failed; - // @@TODO - shall we disengage the idler? ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off); ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0); } } return false; - case UnloadBackToPTFE: - if (mm::motion.QueueEmpty()) { // all moves have been finished - state = DisengagingIdler; - mi::idler.Disengage(); - } - return false; - case DisengagingIdler: - if (!mi::idler.Engaged()) { - state = OK; - ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off); - } - // @@TODO FINDA must be reported as OFF again as we are pulling the filament from it - is this correct? - return false; case OK: case Failed: default: diff --git a/src/logic/load_filament.cpp b/src/logic/load_filament.cpp index 57fb877..5f6fbe4 100644 --- a/src/logic/load_filament.cpp +++ b/src/logic/load_filament.cpp @@ -51,20 +51,22 @@ bool LoadFilament::StepInner() { ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off); ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0); // signal loading error } else { - state = ProgressCode::FeedingToBondtech; - james.Reset(config::feedToBondtechMaxRetries); + state = ProgressCode::RetractingFromFinda; + retract.Reset(); } } break; - case ProgressCode::FeedingToBondtech: - if (james.Step()) { // No, Mr. Bond, I expect you to FEED - switch (james.State()) { - case FeedToBondtech::Failed: - - case FeedToBondtech::OK: - mm::motion.Disable(mm::Pulley); + case ProgressCode::RetractingFromFinda: + if (retract.Step()) { + if (retract.State() == RetractFromFinda::Failed) { + state = ProgressCode::ERRDisengagingIdler; + error = ErrorCode::FINDA_DIDNT_SWITCH_OFF; mi::idler.Disengage(); + ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off); + ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0); // signal loading error + } else { state = ProgressCode::DisengagingIdler; + mi::idler.Disengage(); } } break; diff --git a/src/logic/load_filament.h b/src/logic/load_filament.h index f469a7d..e3975ca 100644 --- a/src/logic/load_filament.h +++ b/src/logic/load_filament.h @@ -2,7 +2,7 @@ #include #include "command_base.h" #include "feed_to_finda.h" -#include "feed_to_bondtech.h" +#include "retract_from_finda.h" namespace logic { @@ -21,7 +21,7 @@ public: private: FeedToFinda feed; - FeedToBondtech james; // bond ;) + RetractFromFinda retract; }; /// The one and only instance of LoadFilament state machine in the FW diff --git a/src/logic/progress_codes.h b/src/logic/progress_codes.h index f9f9170..d7f9357 100644 --- a/src/logic/progress_codes.h +++ b/src/logic/progress_codes.h @@ -33,4 +33,5 @@ enum class ProgressCode : uint_fast8_t { ReturningSelector, // P21 ParkingSelector, // P22 EjectingFilament, // P23 + RetractingFromFinda, // P24 }; diff --git a/src/logic/retract_from_finda.cpp b/src/logic/retract_from_finda.cpp new file mode 100644 index 0000000..5fc6894 --- /dev/null +++ b/src/logic/retract_from_finda.cpp @@ -0,0 +1,42 @@ +#include "retract_from_finda.h" +#include "../modules/finda.h" +#include "../modules/globals.h" +#include "../modules/idler.h" +#include "../modules/leds.h" +#include "../modules/motion.h" + +namespace logic { + +void RetractFromFinda::Reset() { + state = EngagingIdler; + ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::blink0); + mi::idler.Engage(mg::globals.ActiveSlot()); +} + +bool RetractFromFinda::Step() { + switch (state) { + case EngagingIdler: + if (mi::idler.Engaged()) { + state = UnloadBackToPTFE; + mm::motion.PlanMove(-config::cuttingEdgeToFindaMidpoint, config::pulleyFeedrate); + } + return false; + case UnloadBackToPTFE: + if (mm::motion.QueueEmpty()) { // all moves have been finished + if (!mf::finda.Pressed()) { // FINDA switched off correctly + state = OK; + } else { // FINDA didn't switch off + state = Failed; + ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off); + ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0); + } + } + return false; + case OK: + case Failed: + default: + return true; + } +} + +} // namespace logic diff --git a/src/logic/retract_from_finda.h b/src/logic/retract_from_finda.h new file mode 100644 index 0000000..a577946 --- /dev/null +++ b/src/logic/retract_from_finda.h @@ -0,0 +1,36 @@ +#pragma once +#include + +namespace logic { + +/// @brief Retract filament from FINDA to PTFE +/// +/// Continuously pull filament by a fixed length (originally 600 steps) + verify FINDA is switched OFF +struct RetractFromFinda { + /// internal states of the state machine + enum { + EngagingIdler, + UnloadBackToPTFE, + OK, + Failed + }; + + inline RetractFromFinda() + : state(OK) {} + + /// Restart the automaton + void Reset(); + + /// @returns true if the state machine finished its job, false otherwise + bool Step(); + + /// This method may be used to check the result of the automaton + /// @returns OK if everything went OK and FINDA triggered + /// @returns Failed if the FINDA didn't trigger + inline uint8_t State() const { return state; } + +private: + uint8_t state; +}; + +} // namespace logic diff --git a/tests/unit/logic/feed_to_finda/test_feed_to_finda.cpp b/tests/unit/logic/feed_to_finda/test_feed_to_finda.cpp index 83f4a3f..acdd5c2 100644 --- a/tests/unit/logic/feed_to_finda/test_feed_to_finda.cpp +++ b/tests/unit/logic/feed_to_finda/test_feed_to_finda.cpp @@ -63,26 +63,26 @@ TEST_CASE("feed_to_finda::feed_phase_unlimited", "[feed_to_finda]") { 1500)); // From now on the FINDA is reported as ON - // unloading back to PTFE - REQUIRE(ff.State() == FeedToFinda::UnloadBackToPTFE); - REQUIRE(WhileCondition( - ff, - [&](int) { return ff.State() == FeedToFinda::UnloadBackToPTFE; }, - 5000)); + // // unloading back to PTFE + // REQUIRE(ff.State() == FeedToFinda::UnloadBackToPTFE); + // REQUIRE(WhileCondition( + // ff, + // [&](int) { return ff.State() == FeedToFinda::UnloadBackToPTFE; }, + // 5000)); - // disengaging idler - REQUIRE(ff.State() == FeedToFinda::DisengagingIdler); - REQUIRE(WhileCondition( - ff, - [&](int) { return mi::idler.Engaged(); }, - 5000)); + // // disengaging idler + // REQUIRE(ff.State() == FeedToFinda::DisengagingIdler); + // REQUIRE(WhileCondition( + // ff, + // [&](int) { return mi::idler.Engaged(); }, + // 5000)); - CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5).v); // @@TODO constants + // CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5).v); // @@TODO constants CHECK(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(0).v); - // state machine finished ok, the green LED should be on + // state machine finished ok, the green LED should be blinking REQUIRE(ff.State() == FeedToFinda::OK); - REQUIRE(ml::leds.Mode(mg::globals.ActiveSlot(), ml::green) == ml::off); + REQUIRE(ml::leds.Mode(mg::globals.ActiveSlot(), ml::green) == ml::blink0); REQUIRE(ff.Step() == true); // the automaton finished its work, any consecutive calls to Step must return true } diff --git a/tests/unit/logic/load_filament/CMakeLists.txt b/tests/unit/logic/load_filament/CMakeLists.txt index c435fa9..bb8199a 100644 --- a/tests/unit/logic/load_filament/CMakeLists.txt +++ b/tests/unit/logic/load_filament/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable( ${CMAKE_SOURCE_DIR}/src/logic/feed_to_bondtech.cpp ${CMAKE_SOURCE_DIR}/src/logic/feed_to_finda.cpp ${CMAKE_SOURCE_DIR}/src/logic/load_filament.cpp + ${CMAKE_SOURCE_DIR}/src/logic/retract_from_finda.cpp ${CMAKE_SOURCE_DIR}/src/modules/buttons.cpp ${CMAKE_SOURCE_DIR}/src/modules/debouncer.cpp ${CMAKE_SOURCE_DIR}/src/modules/finda.cpp diff --git a/tests/unit/logic/load_filament/test_load_filament.cpp b/tests/unit/logic/load_filament/test_load_filament.cpp index 7b130ca..bca3132 100644 --- a/tests/unit/logic/load_filament/test_load_filament.cpp +++ b/tests/unit/logic/load_filament/test_load_filament.cpp @@ -57,23 +57,23 @@ void LoadFilamentSuccessful(uint8_t slot, logic::LoadFilament &lf) { } return lf.TopLevelState() == ProgressCode::FeedingToFinda; }, 5000)); - REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::FeedingToBondtech)); + REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::RetractingFromFinda)); - // Stage 3 - feeding to bondtech - // we'll make a fsensor switch during the process + // Stage 3 - retracting from finda + // we'll assume the finda is working correctly here REQUIRE(WhileCondition( lf, [&](int step) -> bool { - if(step == 100){ // on 100th step make fsensor trigger - mfs::fsensor.ProcessMessage(true); + if(step == 50){ // on 50th step make FINDA trigger + hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low); } - return lf.TopLevelState() == ProgressCode::FeedingToBondtech; }, + return lf.TopLevelState() == ProgressCode::RetractingFromFinda; }, 5000)); - REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::DisengagingIdler)); + REQUIRE(VerifyState(lf, false, slot, slot, false, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::DisengagingIdler)); // Stage 4 - disengaging idler REQUIRE(WhileTopState(lf, ProgressCode::DisengagingIdler, idlerEngageDisengageMaxSteps)); - REQUIRE(VerifyState(lf, true, mi::Idler::IdleSlotIndex(), slot, true, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK)); + REQUIRE(VerifyState(lf, true, mi::Idler::IdleSlotIndex(), slot, false, ml::on, ml::off, ErrorCode::OK, ProgressCode::OK)); } TEST_CASE("load_filament::regular_load_to_slot_0-4", "[load_filament]") { diff --git a/tests/unit/logic/tool_change/CMakeLists.txt b/tests/unit/logic/tool_change/CMakeLists.txt index d965ec7..13cb494 100644 --- a/tests/unit/logic/tool_change/CMakeLists.txt +++ b/tests/unit/logic/tool_change/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable( ${CMAKE_SOURCE_DIR}/src/logic/feed_to_bondtech.cpp ${CMAKE_SOURCE_DIR}/src/logic/feed_to_finda.cpp ${CMAKE_SOURCE_DIR}/src/logic/load_filament.cpp + ${CMAKE_SOURCE_DIR}/src/logic/retract_from_finda.cpp ${CMAKE_SOURCE_DIR}/src/logic/tool_change.cpp ${CMAKE_SOURCE_DIR}/src/logic/unload_filament.cpp ${CMAKE_SOURCE_DIR}/src/logic/unload_to_finda.cpp