Prusa-Firmware-MMU/src/logic/unload_filament.cpp

98 lines
3.9 KiB
C++

#include "unload_filament.h"
#include "../modules/buttons.h"
#include "../modules/finda.h"
#include "../modules/leds.h"
#include "../modules/motion.h"
#include "../modules/idler.h"
#include "../modules/permanent_storage.h"
namespace logic {
UnloadFilament unloadFilament;
namespace mm = modules::motion;
namespace mi = modules::idler;
void UnloadFilament::Reset(uint8_t param) {
// unloads filament from extruder - filament is above Bondtech gears
mm::motion.InitAxis(mm::Pulley);
state = ProgressCode::EngagingIdler;
error = ErrorCode::OK;
modules::idler::idler.Engage(0); //@@TODO
}
bool UnloadFilament::Step() {
switch (state) {
case ProgressCode::EngagingIdler: // state 1 engage idler
if (mi::idler.Engaged()) { // if idler is in parked position un-park it get in contact with filament
state = ProgressCode::UnloadingToFinda;
unl.Reset();
}
return false;
case ProgressCode::UnloadingToFinda: // state 2 rotate pulley as long as the FINDA is on
if (unl.Step()) {
if (unl.state == UnloadToFinda::Failed) {
// couldn't unload to FINDA, report error and wait for user to resolve it
state = ProgressCode::ERR1DisengagingIdler;
// modules::leds::leds.SetMode(active_extruder, modules::leds::red, modules::leds::blink0);
} else {
state = ProgressCode::DisengagingIdler;
}
// in all cases disengage the idler
mi::idler.Disengage();
}
return false;
case ProgressCode::DisengagingIdler:
if (!mi::idler.Engaged()) {
state = ProgressCode::AvoidingGrind;
// mm::motion.PlanMove(mm::Pulley, -100, 10); // @@TODO constants
}
return false;
case ProgressCode::AvoidingGrind: // state 3 move a little bit so it is not a grinded hole in filament
if (mm::motion.QueueEmpty()) {
state = ProgressCode::FinishingMoves;
mi::idler.Disengage();
return true;
}
return false;
case ProgressCode::FinishingMoves:
if (mm::motion.QueueEmpty()) {
state = ProgressCode::OK;
mm::motion.DisableAxis(mm::Pulley);
}
return false;
case ProgressCode::ERR1DisengagingIdler: // couldn't unload to FINDA
error = ErrorCode::UNLOAD_FINDA_DIDNT_TRIGGER;
if (!mi::idler.Engaged()) {
state = ProgressCode::ERR1WaitingForUser;
}
return false;
case ProgressCode::ERR1WaitingForUser: {
// waiting for user buttons and/or a command from the printer
bool help = modules::buttons::buttons.ButtonPressed(modules::buttons::Left) /*|| command_help()*/;
bool tryAgain = modules::buttons::buttons.ButtonPressed(modules::buttons::Middle) /*|| command_tryAgain()*/;
bool userResolved = modules::buttons::buttons.ButtonPressed(modules::buttons::Right) /*|| command_userResolved()*/;
if (help) {
// try to manually unload just a tiny bit - help the filament with the pulley
//@@TODO
} else if (tryAgain) {
// try again the whole sequence
Reset(0); // @@TODO param
} else if (userResolved) {
// problem resolved - the user pulled the fillament by hand
// modules::leds::leds.SetMode(active_extruder, modules::leds::red, modules::leds::off);
// modules::leds::leds.SetMode(active_extruder, modules::leds::green, modules::leds::on);
// mm::motion.PlanMove(mm::Pulley, 450, 5000); // @@TODO constants
state = ProgressCode::AvoidingGrind;
}
return false;
}
case ProgressCode::OK:
// isFilamentLoaded = false; // filament unloaded
return true; // successfully finished
}
return false;
}
} // namespace logic