Skip to content

Commit

Permalink
M600 in non-MMU mode now asks for confirmation before unloading
Browse files Browse the repository at this point in the history
  • Loading branch information
ekr committed Aug 27, 2019
1 parent 6aaa40b commit 802e182
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Firmware/Marlin.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ void proc_commands();

void M600_load_filament();
void M600_load_filament_movements();
void M600_wait_for_user(float HotendTempBckp);
bool M600_wait_for_user(float HotendTempBckp);
void M600_check_state(float nozzle_temp);
void load_filament_final_feed();
void marlin_wait_for_click();
Expand Down
91 changes: 63 additions & 28 deletions Firmware/Marlin_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3037,8 +3037,9 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
st_synchronize();

//Beep, manage nozzle heater and wait for user to start unload filament
if(!mmu_enabled) M600_wait_for_user(HotendTempBckp);

if (mmu_enabled || M600_wait_for_user(HotendTempBckp))
{

lcd_change_fil_state = 0;

// Unload filament
Expand Down Expand Up @@ -3085,6 +3086,8 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
M600_load_filament();

if (!automatic) M600_check_state(HotendTempBckp);

} // if (mmu_enabled || M600_wait_for_user(HotendTempBckp))

lcd_update_enable(true);

Expand Down Expand Up @@ -10320,44 +10323,76 @@ void M600_check_state(float nozzle_temp)
//! If times out, active extruder temperature is set to 0.
//!
//! @param HotendTempBckp Temperature to be restored for active extruder, after user resolves MMU problem.
void M600_wait_for_user(float HotendTempBckp) {
bool M600_wait_for_user(float HotendTempBckp) {

KEEPALIVE_STATE(PAUSED_FOR_USER);

int counterBeep = 0;
unsigned long waiting_start_time = _millis();
unsigned long beep_start_time = 0;
uint8_t wait_for_user_state = 0;
lcd_display_message_fullscreen_P(_T(MSG_PRESS_TO_UNLOAD));

// Ask the user if he actually wants to reload
// filament. They may have changed their mind; or they
// might want to use the M600 as a comfortable pause
// for whatever reason (works well with the layer
// change feature of PrusaSlicer).

// 0 = no (skip unload)
// 1 = yes (do unload)
// -1 = timeout (last selection was NO)
// -2 = timeout (last selection was YES)
int8_t yesno = -2;

bool bFirst=true;

while (!(wait_for_user_state == 0 && lcd_clicked())){
manage_heater();
manage_inactivity(true);
unsigned long mill;

while (wait_for_user_state != 0 || yesno < 0){

manage_heater();
manage_inactivity(true);

mill = _millis();

#if BEEPER > 0
if (counterBeep == 500) {
counterBeep = 0;
}
SET_OUTPUT(BEEPER);
if (counterBeep == 0) {
if((eSoundMode==e_SOUND_MODE_BLIND)|| (eSoundMode==e_SOUND_MODE_LOUD)||((eSoundMode==e_SOUND_MODE_ONCE)&&bFirst))
{
bFirst=false;
WRITE(BEEPER, HIGH);
}
if (beep_start_time == 0 &&
wait_for_user_state != 2 &&
((eSoundMode==e_SOUND_MODE_BLIND) ||
(eSoundMode==e_SOUND_MODE_LOUD) ||
((eSoundMode==e_SOUND_MODE_ONCE) && bFirst))) {
// Start a beep
bFirst=false;
WRITE(BEEPER, HIGH);
beep_start_time = mill;
}
if (counterBeep == 20) {
WRITE(BEEPER, LOW);
}

counterBeep++;
#endif //BEEPER > 0
#endif //BEEPER > 0

if (wait_for_user_state == 0) {
// this takes 1000ms
yesno = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Unload filament now?"), 1000, yesno);
if (yesno >= 0) {
break;
}
}

#if BEEPER > 0
if (mill - beep_start_time > 900) {
// Turn off beeper after 0.9s, which should be safely after the 1 second prompt timeout.
WRITE(BEEPER, LOW);
}
if (mill - beep_start_time > 5000) {
// Next beep after 5s
beep_start_time = 0;
}
#endif //BEEPER > 0


switch (wait_for_user_state) {
case 0: //nozzle is hot, waiting for user to press the knob to unload filament
delay_keep_alive(4);

if (_millis() > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) {
if (mill > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) {
lcd_display_message_fullscreen_P(_i("Press knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4
wait_for_user_state = 1;
setAllTargetHotends(0);
Expand All @@ -10378,14 +10413,11 @@ void M600_wait_for_user(float HotendTempBckp) {
}
break;
case 2: //waiting for nozzle to reach target temperature

if (abs(degTargetHotend(active_extruder) - degHotend(active_extruder)) < 1) {
lcd_display_message_fullscreen_P(_T(MSG_PRESS_TO_UNLOAD));
waiting_start_time = _millis();
waiting_start_time = mill;
wait_for_user_state = 0;
}
else {
counterBeep = 20; //beeper will be inactive during waiting for nozzle preheat
lcd_set_cursor(1, 4);
lcd_print(ftostr3(degHotend(active_extruder)));
}
Expand All @@ -10394,7 +10426,10 @@ void M600_wait_for_user(float HotendTempBckp) {
}

}

WRITE(BEEPER, LOW);

return (yesno == 1 ? true : false);
}

void M600_load_filament_movements()
Expand Down
43 changes: 21 additions & 22 deletions Firmware/ultralcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3725,40 +3725,39 @@ int8_t lcd_show_multiscreen_message_two_choices_and_wait_P(const char *msg, bool

//! @brief Show single screen message with yes and no possible choices and wait with possible timeout
//! @param msg Message to show
//! @param allow_timeouting if true, allows time outing of the screen
//! @param default_yes if true, yes choice is selected by default, otherwise no choice is preselected
//! @param allow_timeouting if true, allows time outing of the screen with a default timeout. If any other
//! number != 0, then allows timeout with that number of milliseconds
//! @param default_yes if true or -2, then yes choice is selected by default, otherwise no choice is preselected.
//! If return_immediately is true, then this should be the value of the previous call.
//! @retval 1 yes choice selected by user
//! @retval 0 no choice selected by user
//! @retval -1 screen timed out
int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting, bool default_yes)
//! @retval -1 screen timed out and the cursor was on NO
//! @retval -2 screen timed out and the cursor was on YES
int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, unsigned long allow_timeouting, int8_t default_yes)
{

lcd_display_message_fullscreen_P(msg);

if (default_yes) {
lcd_set_cursor(0, 2);
lcd_puts_P(PSTR(">"));
lcd_puts_P(_T(MSG_YES));
lcd_set_cursor(1, 3);
lcd_puts_P(_T(MSG_NO));
}
else {
lcd_set_cursor(1, 2);
lcd_puts_P(_T(MSG_YES));
lcd_set_cursor(0, 3);
lcd_puts_P(PSTR(">"));
lcd_puts_P(_T(MSG_NO));
}
bool yes = default_yes ? true : false;

bool yes = (default_yes == true) || (default_yes == -2);

lcd_set_cursor(1, 2);
lcd_puts_P(_T(MSG_YES));
lcd_set_cursor(1, 3);
lcd_puts_P(_T(MSG_NO));

lcd_set_cursor(0, yes ? 2 : 3);
lcd_puts_P(PSTR(">"));

// Wait for user confirmation or a timeout.
unsigned long previous_millis_cmd = _millis();
unsigned long timeout = allow_timeouting == true ? LCD_TIMEOUT_TO_STATUS : allow_timeouting;
int8_t enc_dif = lcd_encoder_diff;
lcd_consume_click();
KEEPALIVE_STATE(PAUSED_FOR_USER);
for (;;) {
if (allow_timeouting && _millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS)
return -1;
if (allow_timeouting && _millis() - previous_millis_cmd > timeout)
return yes ? -2 : -1;

manage_heater();
manage_inactivity(true);
if (abs(enc_dif - lcd_encoder_diff) > 4) {
Expand Down
4 changes: 2 additions & 2 deletions Firmware/ultralcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ extern void lcd_return_to_status();
extern void lcd_wait_for_click();
extern bool lcd_wait_for_click_delay(uint16_t nDelay);
extern void lcd_show_fullscreen_message_and_wait_P(const char *msg);
// 0: no, 1: yes, -1: timeouted
extern int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting = true, bool default_yes = false);
// 0: no, 1: yes, -1: timeouted (cursor on NO), -2: timeouted (cursor on YES)
extern int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, unsigned long allow_timeouting = true, int8_t default_yes = false);
extern int8_t lcd_show_multiscreen_message_two_choices_and_wait_P(const char *msg, bool allow_timeouting, bool default_yes,
const char *first_choice, const char *second_choice);
extern int8_t lcd_show_multiscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting = true, bool default_yes = false);
Expand Down

0 comments on commit 802e182

Please sign in to comment.