diff --git a/src/logic/feed_to_bondtech.cpp b/src/logic/feed_to_bondtech.cpp index dd7bc82..cf2067d 100644 --- a/src/logic/feed_to_bondtech.cpp +++ b/src/logic/feed_to_bondtech.cpp @@ -79,6 +79,8 @@ bool FeedToBondtech::Step() { //dbg_logic_P(PSTR("Feed to Bondtech --> Pushing")); if (mfs::fsensor.Pressed()) { mm::motion.AbortPlannedMoves(); // stop pushing filament + // remember the feed distance for later update of bowden length + feedEnd_mm = mpu::pulley.CurrentPosition_mm(); GoToPushToNozzle(); // } else if (mm::motion.StallGuard(mm::Pulley)) { // // StallGuard occurred during movement - the filament got stuck @@ -109,7 +111,7 @@ bool FeedToBondtech::Step() { dbg_logic_P(PSTR("Feed to Bondtech --> Idler disengaged")); dbg_logic_fP(PSTR("Pulley end steps %u"), mpu::pulley.CurrentPosition_mm()); state = OK; - UpdateBowdenLength(abs(mpu::pulley.CurrentPosition_mm() - feedStart_mm)); + UpdateBowdenLength(abs(feedEnd_mm - feedStart_mm)); ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::on); } return false; diff --git a/src/logic/feed_to_bondtech.h b/src/logic/feed_to_bondtech.h index 8297d1f..4adbcf8 100644 --- a/src/logic/feed_to_bondtech.h +++ b/src/logic/feed_to_bondtech.h @@ -56,7 +56,7 @@ private: uint8_t state; uint8_t maxRetries; - int32_t feedStart_mm; // intentionally trying to avoid using U_mm because it is a float (resp. long double) + int32_t feedStart_mm, feedEnd_mm; // intentionally trying to avoid using U_mm because it is a float (resp. long double) }; } // namespace logic diff --git a/src/modules/permanent_storage.cpp b/src/modules/permanent_storage.cpp index ab7182d..9d04032 100644 --- a/src/modules/permanent_storage.cpp +++ b/src/modules/permanent_storage.cpp @@ -79,12 +79,12 @@ static constexpr bool validBowdenLen(const uint16_t BowdenLength) { && BowdenLength <= eepromBowdenLenMaximum); } -uint16_t BowdenLength::Get(){ - uint16_t bl = ee::EEPROM::ReadByte(EEOFFSET(eepromBase->bowdenLengthMM)); +uint16_t BowdenLength::Get() { + uint16_t bl = ee::EEPROM::ReadWord(EEOFFSET(eepromBase->bowdenLengthMM)); return validBowdenLen(bl) ? bl : eepromBowdenLenDefault; } -void BowdenLength::Set(uint16_t mm){ +void BowdenLength::Set(uint16_t mm) { ee::EEPROM::UpdateWord(EEOFFSET(eepromBase->bowdenLengthMM), mm); } diff --git a/tests/unit/logic/feed_to_bondtech/test_feed_to_bondtech.cpp b/tests/unit/logic/feed_to_bondtech/test_feed_to_bondtech.cpp index 211ff40..2c9989e 100644 --- a/tests/unit/logic/feed_to_bondtech/test_feed_to_bondtech.cpp +++ b/tests/unit/logic/feed_to_bondtech/test_feed_to_bondtech.cpp @@ -28,11 +28,9 @@ TEST_CASE("feed_to_bondtech::feed_phase_unlimited", "[feed_to_bondtech]") { REQUIRE(EnsureActiveSlotIndex(slot, mg::FilamentLoadState::AtPulley)); // reset bowden lenghts in EEPROM - InitBowdenLengths(); + SetMinimalBowdenLength(); // check bowden lengths - for (uint8_t slot = 0; slot < config::toolCount; ++slot) { - REQUIRE(mps::BowdenLength::Get(mg::globals.ActiveSlot()) == config::minimumBowdenLength.v); - } + REQUIRE(mps::BowdenLength::Get() == config::minimumBowdenLength.v); FeedToBondtech fb; main_loop(); @@ -64,20 +62,23 @@ TEST_CASE("feed_to_bondtech::feed_phase_unlimited", "[feed_to_bondtech]") { REQUIRE(ml::leds.Mode(mg::globals.ActiveSlot(), ml::green) == ml::blink0); // fast load - no fsensor trigger + // performs fast load for config::minimumBowdenLength distance REQUIRE(WhileCondition( fb, [&](uint32_t) { return fb.State() == FeedToBondtech::PushingFilamentFast; }, mm::unitToSteps(config::minimumBowdenLength) + 2)); // slow load - expecting fsensor trigger + // This gets interesting with bowden length autotuning - we should trigger at the right step + constexpr uint32_t additionalBowdenLengthTrigger = mm::unitToSteps(config::defaultBowdenLength - config::minimumBowdenLength); REQUIRE(WhileCondition( fb, [&](uint32_t step) { - if( step == 100 ){ + if( step == additionalBowdenLengthTrigger ){ mfs::fsensor.ProcessMessage(true); } return fb.State() == FeedToBondtech::PushingFilamentToFSensor; }, - 1500)); + additionalBowdenLengthTrigger + 5)); REQUIRE(mfs::fsensor.Pressed()); @@ -114,5 +115,11 @@ TEST_CASE("feed_to_bondtech::feed_phase_unlimited", "[feed_to_bondtech]") { REQUIRE(fb.State() == FeedToBondtech::OK); REQUIRE(ml::leds.LedOn(mg::globals.ActiveSlot(), ml::green)); + // detected bowden length is expected to be 429 in our test scenario + uint16_t detectedBowdenLength = mps::BowdenLength::Get(); + CHECK(detectedBowdenLength == 429); + // must be within the specified tolerance of 10mm from the default bowden length + REQUIRE(abs(detectedBowdenLength - config::defaultBowdenLength.v) < 10); + REQUIRE(fb.Step() == true); // the automaton finished its work, any consecutive calls to Step must return true } diff --git a/tests/unit/logic/stubs/main_loop_stub.cpp b/tests/unit/logic/stubs/main_loop_stub.cpp index 05b3358..631c2c5 100644 --- a/tests/unit/logic/stubs/main_loop_stub.cpp +++ b/tests/unit/logic/stubs/main_loop_stub.cpp @@ -165,11 +165,9 @@ void ClearButtons(logic::CommandBase &cb) { } } -void InitBowdenLengths() { +void SetMinimalBowdenLength() { // reset bowdenLenght in EEPROM - for (uint8_t slot = 0; slot < config::toolCount; ++slot) { - mps::BowdenLength::Set(slot, config::minimumBowdenLength.v); - } + mps::BowdenLength::Set(config::minimumBowdenLength.v); } void SetFSensorStateAndDebounce(bool press) { diff --git a/tests/unit/logic/stubs/main_loop_stub.h b/tests/unit/logic/stubs/main_loop_stub.h index 6a769bb..0d5d492 100644 --- a/tests/unit/logic/stubs/main_loop_stub.h +++ b/tests/unit/logic/stubs/main_loop_stub.h @@ -32,7 +32,7 @@ bool SimulateRetractFromFINDA(uint32_t step, uint32_t findaOff); void PressButtonAndDebounce(logic::CommandBase &cb, uint8_t btnIndex, bool fromPrinter); void ClearButtons(logic::CommandBase &cb); -void InitBowdenLengths(); +void SetMinimalBowdenLength(); void SetFSensorStateAndDebounce(bool press); // these are recommended max steps for simulated movement of the idler and selector diff --git a/tests/unit/logic/tool_change/test_tool_change.cpp b/tests/unit/logic/tool_change/test_tool_change.cpp index 97a4695..046fbd2 100644 --- a/tests/unit/logic/tool_change/test_tool_change.cpp +++ b/tests/unit/logic/tool_change/test_tool_change.cpp @@ -79,7 +79,7 @@ bool SimulateUnloadFilament(uint32_t step, const logic::CommandBase *tc, uint32_ void ToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) { ForceReinitAllAutomata(); - InitBowdenLengths(); + SetMinimalBowdenLength(); REQUIRE(EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle)); SetFINDAStateAndDebounce(true); @@ -105,7 +105,7 @@ void ToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) { void NoToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) { ForceReinitAllAutomata(); - InitBowdenLengths(); + SetMinimalBowdenLength(); REQUIRE(EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle)); // the filament is LOADED @@ -125,7 +125,7 @@ void NoToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) { void JustLoadFilament(logic::ToolChange &tc, uint8_t slot) { for (uint8_t startSelectorSlot = 0; startSelectorSlot < config::toolCount; ++startSelectorSlot) { ForceReinitAllAutomata(); - InitBowdenLengths(); + SetMinimalBowdenLength(); // make sure all the modules are ready // MMU-196: Move selector to a "random" slot REQUIRE(EnsureActiveSlotIndex(startSelectorSlot, mg::FilamentLoadState::AtPulley)); @@ -191,7 +191,7 @@ TEST_CASE("tool_change::same_slot_just_unloaded_filament", "[tool_change]") { void ToolChangeFailLoadToFinda(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) { ForceReinitAllAutomata(); - InitBowdenLengths(); + SetMinimalBowdenLength(); REQUIRE(EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle)); SetFINDAStateAndDebounce(true); @@ -319,7 +319,7 @@ TEST_CASE("tool_change::load_fail_FINDA_resolve_btnM", "[tool_change]") { void ToolChangeFailFSensor(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) { using namespace std::placeholders; ForceReinitAllAutomata(); - InitBowdenLengths(); + SetMinimalBowdenLength(); REQUIRE(EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle)); SetFINDAStateAndDebounce(true); @@ -402,6 +402,7 @@ TEST_CASE("tool_change::load_fail_FSensor_resolve_btnM", "[tool_change]") { void ToolChangeWithFlickeringFINDA(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot, bool keepFindaPressed) { ForceReinitAllAutomata(); + SetMinimalBowdenLength(); REQUIRE(EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle)); SetFINDAStateAndDebounce(true); @@ -500,6 +501,7 @@ TEST_CASE("tool_change::test_flickering_FINDA_keepPressed", "[tool_change]") { void ToolChangeFSENSOR_TOO_EARLY(logic::ToolChange &tc, uint8_t slot) { ForceReinitAllAutomata(); + SetMinimalBowdenLength(); REQUIRE(EnsureActiveSlotIndex(slot, mg::FilamentLoadState::AtPulley)); // verify filament NOT loaded