Distinguish fast and slow feed stage
Originally, only FeedingToBondtech was reported to the printer. With PR#173 we have this operation separated into a fast and a slow stage (for MK3S with the chimney). It looks like the printer could benefit from knowing if the MMU is still pushing fast or when it entered the slow stage (to prevent ramming hard the Bondtech gears) Along with this new state being reported, we also introduce a new ErrorCode::FSENSOR_TOO_EARLY which basically means that the fsensor triggered in the fast feeding stage.pull/176/head
parent
d830a92fee
commit
fbb46e5951
|
|
@ -41,6 +41,11 @@ enum class ErrorCode : uint_fast16_t {
|
|||
|
||||
FINDA_VS_EEPROM_DISREPANCY = 0x8008, ///< E32776 FINDA is pressed but we have no such record in EEPROM - this can only happen at the start of the MMU and can be resolved by issuing an Unload command
|
||||
|
||||
FSENSOR_TOO_EARLY = 0x8009, ///< E32777 FSensor triggered while doing FastFeedToBondtech - that means either:
|
||||
///< - the PTFE is too short
|
||||
///< - a piece of filament was left inside - pushed in front of the loaded filament causing the fsensor trigger too early
|
||||
///< - fsensor is faulty producing bogus triggers
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ bool FeedToBondtech::Step() {
|
|||
if (mi::idler.Engaged()) {
|
||||
dbg_logic_P(PSTR("Feed to Bondtech --> Idler engaged"));
|
||||
dbg_logic_fP(PSTR("Pulley start steps %u"), mpu::pulley.CurrentPosition_mm());
|
||||
state = PushingFilamentToFSensor;
|
||||
state = PushingFilamentFast;
|
||||
mpu::pulley.InitAxis();
|
||||
// plan a fast move while in the safe minimal length
|
||||
mpu::pulley.PlanMove(config::minimumBowdenLength, config::pulleyLoadFeedrate, config::pulleySlowFeedrate);
|
||||
|
|
@ -42,14 +42,26 @@ bool FeedToBondtech::Step() {
|
|||
mpu::pulley.PlanMove(config::maximumBowdenLength - config::minimumBowdenLength, config::pulleySlowFeedrate, config::pulleySlowFeedrate);
|
||||
}
|
||||
return false;
|
||||
case PushingFilamentFast:
|
||||
if (mfs::fsensor.Pressed()) {
|
||||
// Safety precaution - if the fsensor triggers while pushing the filament fast, we must stop pushing immediately
|
||||
// With a correctly set-up MMU this shouldn't happen
|
||||
mm::motion.AbortPlannedMoves(); // stop pushing filament
|
||||
state = FSensorTooEarly;
|
||||
} else if (mm::motion.PlannedMoves(mm::Pulley) == 1) {
|
||||
// a bit of a hack - the fast (already planned) move has finished, doing the slow part
|
||||
// -> just switch to FeedingToFSensor
|
||||
state = PushingFilamentToFSensor;
|
||||
}
|
||||
return false;
|
||||
case PushingFilamentToFSensor:
|
||||
//dbg_logic_P(PSTR("Feed to Bondtech --> Pushing"));
|
||||
if (mfs::fsensor.Pressed()) {
|
||||
mm::motion.AbortPlannedMoves(); // stop pushing filament
|
||||
GoToPushToNozzle();
|
||||
} else if (mm::motion.StallGuard(mm::Pulley)) {
|
||||
// stall guard occurred during movement - the filament got stuck
|
||||
state = Failed; // @@TODO may be even report why it failed
|
||||
// } else if (mm::motion.StallGuard(mm::Pulley)) {
|
||||
// // stall guard occurred during movement - the filament got stuck
|
||||
// state = PulleyStalled;
|
||||
} else if (mm::motion.QueueEmpty()) { // all moves have been finished and the fsensor didn't switch on
|
||||
state = Failed;
|
||||
}
|
||||
|
|
@ -76,6 +88,8 @@ bool FeedToBondtech::Step() {
|
|||
dbg_logic_P(PSTR("Feed to Bondtech OK"));
|
||||
return true;
|
||||
case Failed:
|
||||
case FSensorTooEarly:
|
||||
// case PulleyStalled:
|
||||
dbg_logic_P(PSTR("Feed to Bondtech FAILED"));
|
||||
return true;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -14,11 +14,14 @@ struct FeedToBondtech {
|
|||
/// internal states of the state machine
|
||||
enum {
|
||||
EngagingIdler,
|
||||
PushingFilamentFast,
|
||||
PushingFilamentToFSensor,
|
||||
PushingFilamentIntoNozzle,
|
||||
DisengagingIdler,
|
||||
OK,
|
||||
Failed
|
||||
Failed,
|
||||
FSensorTooEarly,
|
||||
// PulleyStalled
|
||||
};
|
||||
|
||||
inline FeedToBondtech()
|
||||
|
|
|
|||
|
|
@ -39,5 +39,7 @@ enum class ProgressCode : uint_fast8_t {
|
|||
Homing, // P26
|
||||
MovingSelector, // P27
|
||||
|
||||
FeedingToFSensor, // P28
|
||||
|
||||
Empty = 0xff // dummy empty state
|
||||
};
|
||||
|
|
|
|||
|
|
@ -81,9 +81,14 @@ bool ToolChange::StepInner() {
|
|||
break;
|
||||
case ProgressCode::FeedingToBondtech:
|
||||
if (james.Step()) {
|
||||
if (james.State() == FeedToBondtech::Failed) {
|
||||
switch (james.State()) {
|
||||
case FeedToBondtech::Failed:
|
||||
GoToErrDisengagingIdler(ErrorCode::FSENSOR_DIDNT_SWITCH_ON); // signal loading error
|
||||
} else {
|
||||
break;
|
||||
case FeedToBondtech::FSensorTooEarly:
|
||||
GoToErrDisengagingIdler(ErrorCode::FSENSOR_TOO_EARLY); // signal loading error
|
||||
break;
|
||||
default:
|
||||
ToolChangeFinishedCorrectly();
|
||||
}
|
||||
}
|
||||
|
|
@ -163,6 +168,15 @@ ProgressCode ToolChange::State() const {
|
|||
switch (state) {
|
||||
case ProgressCode::UnloadingFilament:
|
||||
return unl.State(); // report sub-automaton states properly
|
||||
case ProgressCode::FeedingToBondtech:
|
||||
// only process the important states
|
||||
switch (james.State()) {
|
||||
case FeedToBondtech::PushingFilamentToFSensor:
|
||||
return ProgressCode::FeedingToFSensor;
|
||||
case FeedToBondtech::PushingFilamentIntoNozzle:
|
||||
return ProgressCode::FeedingToNozzle;
|
||||
}
|
||||
// [[fallthrough]] // everything else is reported as FeedingToBondtech
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,14 +52,21 @@ TEST_CASE("feed_to_bondtech::feed_phase_unlimited", "[feed_to_bondtech]") {
|
|||
CHECK(mm::axes[mm::Pulley].enabled);
|
||||
|
||||
// idler engaged, selector in position, we'll start pushing filament
|
||||
REQUIRE(fb.State() == FeedToBondtech::PushingFilamentToFSensor);
|
||||
REQUIRE(fb.State() == FeedToBondtech::PushingFilamentFast);
|
||||
// at least at the beginning the LED should shine green (it should be blinking, but this mode has been already verified in the LED's unit test)
|
||||
REQUIRE(ml::leds.Mode(mg::globals.ActiveSlot(), ml::green) == ml::blink0);
|
||||
|
||||
// fast load - no fsensor trigger
|
||||
REQUIRE(WhileCondition(
|
||||
fb,
|
||||
[&](uint32_t) { return fb.State() == FeedToBondtech::PushingFilamentFast; },
|
||||
mm::unitToSteps<mm::P_pos_t>(config::minimumBowdenLength) + 2));
|
||||
|
||||
// slow load - expecting fsensor trigger
|
||||
REQUIRE(WhileCondition(
|
||||
fb,
|
||||
[&](uint32_t step) {
|
||||
if( step == 1000 ){
|
||||
if( step == 100 ){
|
||||
mfs::fsensor.ProcessMessage(true);
|
||||
}
|
||||
return fb.State() == FeedToBondtech::PushingFilamentToFSensor; },
|
||||
|
|
|
|||
|
|
@ -42,15 +42,17 @@ void FeedingToFinda(logic::ToolChange &tc, uint8_t toSlot, uint32_t triggerAt =
|
|||
}
|
||||
|
||||
void FeedingToBondtech(logic::ToolChange &tc, uint8_t toSlot) {
|
||||
// james is feeding
|
||||
// james is feeding fast and then slowly
|
||||
// FSensor must not trigger too early
|
||||
REQUIRE_FALSE(mfs::fsensor.Pressed());
|
||||
REQUIRE(WhileCondition(
|
||||
tc,
|
||||
[&](uint32_t step) -> bool {
|
||||
if(step == 2000){ // on 2000th step make filament sensor trigger
|
||||
if(step == mm::unitToSteps<mm::P_pos_t>(config::minimumBowdenLength)+10){ // on the correct step make filament sensor trigger
|
||||
mfs::fsensor.ProcessMessage(true);
|
||||
}
|
||||
return tc.TopLevelState() == ProgressCode::FeedingToBondtech; },
|
||||
20000UL));
|
||||
mm::unitToSteps<mm::P_pos_t>(config::minimumBowdenLength) + 10000));
|
||||
REQUIRE(VerifyState(tc, mg::FilamentLoadState::InNozzle, mi::Idler::IdleSlotIndex(), toSlot, true, false, ml::on, ml::off, ErrorCode::OK, ProgressCode::OK));
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +75,9 @@ void ToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
|
|||
REQUIRE(WhileCondition(
|
||||
tc,
|
||||
[&](uint32_t step) -> bool {
|
||||
if(step == 2000){ // on 2000th step make FINDA trigger
|
||||
if(step == 20){ // on 20th step make FSensor switch off
|
||||
mfs::fsensor.ProcessMessage(false);
|
||||
} else if(step == mm::unitToSteps<mm::P_pos_t>(config::minimumBowdenLength)){ // on 2000th step make FINDA trigger
|
||||
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low);
|
||||
}
|
||||
return tc.TopLevelState() == ProgressCode::UnloadingFilament; },
|
||||
|
|
|
|||
Loading…
Reference in New Issue