Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚧 WIP MMU Jam detection, the Redux #3692

Draft
wants to merge 1 commit into
base: MK3
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions Firmware/Filament_sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ FSensorBlockRunout::~FSensorBlockRunout() {
// SERIAL_ECHOLNPGM("FSUnBlockRunout");
}

enum class RunoutTypeSetting : uint8_t {
_Disabled = 0,
_Enabled = 1,
_Enabled_with_MMU_jam = 2,
_Undef = EEPROM_EMPTY_VALUE
};

# if FILAMENT_SENSOR_TYPE == FSENSOR_IR
IR_sensor fsensor;
# elif FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG
Expand Down Expand Up @@ -55,10 +62,23 @@ void Filament_sensor::setAutoLoadEnabled(bool state, bool updateEEPROM) {
}
}

void Filament_sensor::setMMUJamEnabled(bool state) {
mmuJamEnabled = state & MMU2::mmu2.Enabled() && sensorSupportsMMUJam;
eeprom_update_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED, (uint8_t)(mmuJamEnabled ? RunoutTypeSetting::_Enabled_with_MMU_jam : RunoutTypeSetting::_Enabled));
}

void Filament_sensor::setRunoutEnabled(bool state, bool updateEEPROM) {
runoutEnabled = state;
if (updateEEPROM) {
eeprom_update_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED, state);
if (state)
{
// If on, forward to handle jam setting properly.
setMMUJamEnabled(mmuJamEnabled);
}
else
{
eeprom_update_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED, state);
}
}
}

Expand All @@ -76,7 +96,9 @@ void Filament_sensor::settings_init_common() {
}

autoLoadEnabled = eeprom_read_byte((uint8_t *)EEPROM_FSENS_AUTOLOAD_ENABLED);
runoutEnabled = eeprom_read_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED);
RunoutTypeSetting runout = (RunoutTypeSetting)eeprom_read_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED);
runoutEnabled = runout >= RunoutTypeSetting::_Enabled;
mmuJamEnabled = runout == RunoutTypeSetting::_Enabled_with_MMU_jam;
sensorActionOnError = (SensorActionOnError)eeprom_read_byte((uint8_t *)EEPROM_FSENSOR_ACTION_NA);
if (sensorActionOnError == SensorActionOnError::_Undef) {
sensorActionOnError = SensorActionOnError::_Continue;
Expand Down Expand Up @@ -181,6 +203,7 @@ void IR_sensor::init() {
// puts_P(PSTR("fsensor::init()"));
SET_INPUT(IR_SENSOR_PIN); // input mode
WRITE(IR_SENSOR_PIN, 1); // pullup
sensorSupportsMMUJam = true;
settings_init(); // also sets the state to State::initializing
}

Expand Down
8 changes: 8 additions & 0 deletions Firmware/Filament_sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ class Filament_sensor {
void setRunoutEnabled(bool state, bool updateEEPROM = false);
bool getRunoutEnabled() const { return runoutEnabled; }

void setMMUJamEnabled(bool state);
bool getMMUJamEnabled() const { return runoutEnabled; }

// This should be overloaded on a per-sensor basis whether it can support jams or not.
bool supportsMMUJam() const { return sensorSupportsMMUJam; }

void setActionOnError(SensorActionOnError state, bool updateEEPROM = false);
SensorActionOnError getActionOnError() const { return sensorActionOnError; }

Expand Down Expand Up @@ -79,6 +85,8 @@ class Filament_sensor {
State state;
bool autoLoadEnabled;
bool runoutEnabled;
bool mmuJamEnabled;
bool sensorSupportsMMUJam = false;
bool oldFilamentPresent; //for creating filament presence switching events.
bool postponedLoadEvent; //this event lasts exactly one update cycle. It is long enough to be able to do polling for load event.
ShortTimer eventBlankingTimer;
Expand Down
7 changes: 6 additions & 1 deletion Firmware/Marlin_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3459,7 +3459,12 @@ static void mmu_M600_wait_and_beep() {
KEEPALIVE_STATE(PAUSED_FOR_USER);

int counterBeep = 0;
lcd_display_message_fullscreen_P(_i("Remove old filament and press the knob to start loading new filament.")); ////MSG_REMOVE_OLD_FILAMENT c=20 r=5
if (MMU2::mmu2.IsExtruderJamDetected()) {
lcd_display_message_fullscreen_P(_i("Possible extruder jam/grinding (FS=0). Fix problem and press the knob.")); ////MSG_FIX_MMU_JAM c=20 r=5
MMU2::mmu2.ClearExtruderJam();
} else {
lcd_display_message_fullscreen_P(_i("Remove old filament and press the knob to start loading new filament.")); ////MSG_REMOVE_OLD_FILAMENT c=20 r=5
}
bool bFirst = true;

while (!lcd_clicked()) {
Expand Down
1 change: 1 addition & 0 deletions Firmware/messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const char MSG_FOLLOW_Z_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("There is still a n
const char MSG_FSENSOR_RUNOUT[] PROGMEM_I1 = ISTR("F. runout"); ////MSG_FSENSOR_RUNOUT c=13
const char MSG_FSENSOR_AUTOLOAD[] PROGMEM_I1 = ISTR("F. autoload"); ////MSG_FSENSOR_AUTOLOAD c=13
const char MSG_FSENSOR_JAM_DETECTION[] PROGMEM_I1 = ISTR("F. jam detect"); ////MSG_FSENSOR_JAM_DETECTION c=13
const char MSG_FSENSOR_MMU_JAM_DETECTION[] PROGMEM_I1 = ISTR("MMU jam det."); ////MSG_FSENSOR_MMU_JAM_DETECTION c=13
const char MSG_FSENSOR[] PROGMEM_I1 = ISTR("Fil. sensor"); ////MSG_FSENSOR c=12
const char MSG_HEATING[] PROGMEM_I1 = ISTR("Heating"); ////MSG_HEATING c=20
const char MSG_HEATING_COMPLETE[] PROGMEM_I1 = ISTR("Heating done."); ////MSG_HEATING_COMPLETE c=20
Expand Down
1 change: 1 addition & 0 deletions Firmware/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern const char MSG_FOLLOW_Z_CALIBRATION_FLOW[];
extern const char MSG_FSENSOR_RUNOUT[];
extern const char MSG_FSENSOR_AUTOLOAD[];
extern const char MSG_FSENSOR_JAM_DETECTION[];
extern const char MSG_FSENSOR_MMU_JAM_DETECTION[];
extern const char MSG_FSENSOR[];
extern const char MSG_HEATING[];
extern const char MSG_HEATING_COMPLETE[];
Expand Down
10 changes: 10 additions & 0 deletions Firmware/mmu2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ MMU2::MMU2()
, loadingToNozzle(false)
, inAutoRetry(false)
, retryAttempts(MAX_RETRIES)
, isPossibleEJam(false)
{
}

Expand Down Expand Up @@ -246,6 +247,15 @@ void MMU2::CheckFINDARunout()
{
enquecommand_front_P(PSTR("M600")); //save print and run M600 command
}
} else if (FindaDetectsFilament() && CHECK_FSENSOR && fsensor.getMMUJamEnabled() && !fsensor.getFilamentPresent()) {
// This is a case where the IR sensor reports false while the FINDA is true. This is called only from state machines where it
// is safe to check (Finished) and won't cause spurious runouts on the FINDA, so I am assuming that is safe to check the fsensor too
// since the MMU won't be e.g. in the middle of a toolchange.
isPossibleEJam = true;
stop_and_save_print_to_ram(0, 0);
restore_print_from_ram_and_continue(0);
enquecommand_front_P(PSTR("M600")); //save print and run M600 command. This will come back to us via eject_filament and then M600_wait_and_beep
printf_P(PSTR("Jam detected, no filament @ IR! \n"));
}
}

Expand Down
9 changes: 9 additions & 0 deletions Firmware/mmu2.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ class MMU2 {
// Called by the MMU protocol when a sent button is acknowledged.
void DecrementRetryAttempts();

/// @brief Returns whether this is possibly an extruder grinding trip due to FS=0
/// @return True if yes
inline bool IsExtruderJamDetected() { return Enabled() && isPossibleEJam; }

/// @brief Clears the extruder jam flag once the message has been serviced.
inline void ClearExtruderJam() { isPossibleEJam = false; }

private:
/// Reset the retryAttempts back to the default value
void ResetRetryAttempts();
Expand Down Expand Up @@ -283,6 +290,8 @@ class MMU2 {
/// true in case we are doing the LoadToNozzle operation - that means the filament shall be loaded all the way down to the nozzle
/// unlike the mid-print ToolChange commands, which only load the first ~30mm and then the G-code takes over.
bool loadingToNozzle;

bool isPossibleEJam;

bool inAutoRetry;
uint8_t retryAttempts;
Expand Down
11 changes: 10 additions & 1 deletion Firmware/ultralcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4162,6 +4162,10 @@ static void lcd_fsensor_runout_set() {
fsensor.setRunoutEnabled(!fsensor.getRunoutEnabled(), true);
}

static void lcd_fsensor_mmujam_set() {
fsensor.setMMUJamEnabled(!fsensor.getMMUJamEnabled());
}

static void lcd_fsensor_autoload_set() {
fsensor.setAutoLoadEnabled(!fsensor.getAutoLoadEnabled(), true);
}
Expand Down Expand Up @@ -4206,8 +4210,13 @@ static void lcd_fsensor_settings_menu() {
MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_RUNOUT), fsensor.getRunoutEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_runout_set);
MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), fsensor.getAutoLoadEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_autoload_set);
#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_JAM_DETECTION), fsensor.getJamDetectionEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_jam_detection_set);
MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_JAM_DETECTION), fsensor.getJamDetectionEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_jam_detection_set);
#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
// For consideration... Should we have an MMU submenu?
if (MMU2::mmu2.Enabled() && fsensor.supportsMMUJam())
{
MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_MMU_JAM_DETECTION), fsensor.getMMUJamEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_mmujam_set);
}
}

switch(fsensor.getActionOnError()) {
Expand Down