Allow G26 to use the active extruder (#12387)

* Make lcd_quick_feedback argument optional
* Add click_to_cancel option to wait_for_hotend/bed
* Have G26 use the active nozzle and wait_for_hotend/bed
* Use wait_for_release in UBL G29
* Add 'T' parameter to G26 for an initial tool-change
This commit is contained in:
Scott Lahteine 2018-11-10 18:07:38 -06:00 committed by GitHub
parent 4260282df7
commit 6093df11dc
Signed by: GitHub
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 107 additions and 82 deletions

View file

@ -630,7 +630,7 @@
#if HAS_LCD_MENU #if HAS_LCD_MENU
lcd_reset_alert_level(); lcd_reset_alert_level();
lcd_quick_feedback(true); lcd_quick_feedback();
lcd_reset_status(); lcd_reset_status();
lcd_external_control = false; lcd_external_control = false;
#endif #endif
@ -689,16 +689,14 @@
bool click_and_hold(const clickFunc_t func=NULL) { bool click_and_hold(const clickFunc_t func=NULL) {
if (is_lcd_clicked()) { if (is_lcd_clicked()) {
lcd_quick_feedback(false); // Do NOT clear button status! If cleared, the code lcd_quick_feedback(false); // Preserve button state for click-and-hold
// code can not look for a 'click and hold'
const millis_t nxt = millis() + 1500UL; const millis_t nxt = millis() + 1500UL;
while (is_lcd_clicked()) { // Loop while the encoder is pressed. Uses hardware flag! while (is_lcd_clicked()) { // Loop while the encoder is pressed. Uses hardware flag!
idle(); // idle, of course idle(); // idle, of course
if (ELAPSED(millis(), nxt)) { // After 1.5 seconds if (ELAPSED(millis(), nxt)) { // After 1.5 seconds
lcd_quick_feedback(true); lcd_quick_feedback();
if (func) (*func)(); if (func) (*func)();
wait_for_release(); wait_for_release();
safe_delay(50); // Debounce the Encoder wheel
return true; return true;
} }
} }
@ -721,7 +719,7 @@
lcd_external_control = true; lcd_external_control = true;
#endif #endif
save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained
DEPLOY_PROBE(); DEPLOY_PROBE();
uint16_t count = GRID_MAX_POINTS; uint16_t count = GRID_MAX_POINTS;
@ -731,14 +729,13 @@
#if HAS_LCD_MENU #if HAS_LCD_MENU
if (is_lcd_clicked()) { if (is_lcd_clicked()) {
lcd_quick_feedback(false); // Preserve button state for click-and-hold
SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n"); SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n");
lcd_quick_feedback(false);
STOW_PROBE(); STOW_PROBE();
while (is_lcd_clicked()) idle(); wait_for_release();
lcd_quick_feedback();
lcd_external_control = false; lcd_external_control = false;
restore_ubl_active_state_and_leave(); restore_ubl_active_state_and_leave();
lcd_quick_feedback(true);
safe_delay(50); // Debounce the Encoder wheel
return; return;
} }
#endif #endif
@ -843,7 +840,7 @@
do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
lcd_external_control = false; lcd_external_control = false;
KEEPALIVE_STATE(IN_HANDLER); KEEPALIVE_STATE(IN_HANDLER);
lcd_quick_feedback(true); lcd_quick_feedback();
ubl.restore_ubl_active_state_and_leave(); ubl.restore_ubl_active_state_and_leave();
} }
@ -910,12 +907,16 @@
} }
#endif // HAS_LCD_MENU #endif // HAS_LCD_MENU
inline void set_message_with_feedback(PGM_P const msg_P) {
lcd_setstatusPGM(msg_P);
lcd_quick_feedback();
}
bool unified_bed_leveling::g29_parameter_parsing() { bool unified_bed_leveling::g29_parameter_parsing() {
bool err_flag = false; bool err_flag = false;
#if HAS_LCD_MENU #if HAS_LCD_MENU
LCD_MESSAGEPGM(MSG_UBL_DOING_G29); set_message_with_feedback(PSTR(MSG_UBL_DOING_G29));
lcd_quick_feedback(true);
#endif #endif
g29_constant = 0; g29_constant = 0;
@ -1037,8 +1038,7 @@
if (ubl_state_recursion_chk != 1) { if (ubl_state_recursion_chk != 1) {
SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
#if HAS_LCD_MENU #if HAS_LCD_MENU
LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); set_message_with_feedback(PSTR(MSG_UBL_SAVE_ERROR));
lcd_quick_feedback(true);
#endif #endif
return; return;
} }
@ -1052,8 +1052,7 @@
if (--ubl_state_recursion_chk) { if (--ubl_state_recursion_chk) {
SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
#if HAS_LCD_MENU #if HAS_LCD_MENU
LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); set_message_with_feedback(PSTR(MSG_UBL_RESTORE_ERROR));
lcd_quick_feedback(true);
#endif #endif
return; return;
} }
@ -1344,8 +1343,7 @@
void abort_fine_tune() { void abort_fine_tune() {
lcd_return_to_status(); lcd_return_to_status();
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
LCD_MESSAGEPGM(MSG_EDITING_STOPPED); set_message_with_feedback(PSTR(MSG_EDITING_STOPPED));
lcd_quick_feedback(true);
} }
void unified_bed_leveling::fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) { void unified_bed_leveling::fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) {

View file

@ -38,6 +38,7 @@
#include "../../module/planner.h" #include "../../module/planner.h"
#include "../../module/stepper.h" #include "../../module/stepper.h"
#include "../../module/motion.h" #include "../../module/motion.h"
#include "../../module/tool_change.h"
#include "../../module/temperature.h" #include "../../module/temperature.h"
#include "../../lcd/ultralcd.h" #include "../../lcd/ultralcd.h"
@ -165,18 +166,12 @@ int8_t g26_prime_flag;
if (!is_lcd_clicked()) return false; // Return if the button isn't pressed if (!is_lcd_clicked()) return false; // Return if the button isn't pressed
lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99); lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99);
#if HAS_LCD_MENU #if HAS_LCD_MENU
lcd_quick_feedback(true); lcd_quick_feedback();
#endif #endif
wait_for_release(); wait_for_release();
return true; return true;
} }
bool exit_from_g26() {
lcd_setstatusPGM(PSTR("Leaving G26"), -1);
wait_for_release();
return G26_ERR;
}
#endif #endif
mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) { mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
@ -412,58 +407,50 @@ inline bool look_for_lines_to_connect() {
* wait for them to get up to temperature. * wait for them to get up to temperature.
*/ */
inline bool turn_on_heaters() { inline bool turn_on_heaters() {
millis_t next = millis() + 5000UL;
SERIAL_ECHOLNPGM("Waiting for heatup.");
#if HAS_HEATED_BED #if HAS_HEATED_BED
#if ENABLED(ULTRA_LCD)
if (g26_bed_temp > 25) { if (g26_bed_temp > 25) {
#if ENABLED(ULTRA_LCD)
lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99); lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99);
lcd_quick_feedback(true); lcd_quick_feedback();
#if HAS_LCD_MENU #if HAS_LCD_MENU
lcd_external_control = true; lcd_external_control = true;
#endif #endif
#endif #endif
thermalManager.setTargetBed(g26_bed_temp); thermalManager.setTargetBed(g26_bed_temp);
while (ABS(thermalManager.degBed() - g26_bed_temp) > 3) {
#if HAS_LCD_MENU // Wait for the temperature to stabilize
if (is_lcd_clicked()) return exit_from_g26(); if (!thermalManager.wait_for_bed(true
#if G26_CLICK_CAN_CANCEL
, true
#endif #endif
)
if (ELAPSED(millis(), next)) { ) return G26_ERR;
next = millis() + 5000UL;
thermalManager.print_heaterstates();
SERIAL_EOL();
}
idle();
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
}
#if ENABLED(ULTRA_LCD)
}
lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99);
lcd_quick_feedback(true);
#endif
#endif
// Start heating the nozzle and wait for it to reach temperature.
thermalManager.setTargetHotend(g26_hotend_temp, 0);
while (ABS(thermalManager.degHotend(0) - g26_hotend_temp) > 3) {
#if HAS_LCD_MENU
if (is_lcd_clicked()) return exit_from_g26();
#endif
if (ELAPSED(millis(), next)) {
next = millis() + 5000UL;
thermalManager.print_heaterstates();
SERIAL_EOL();
} }
idle();
SERIAL_FLUSH(); // Prevent host M105 buffer overrun. #endif // HAS_HEATED_BED
}
// Start heating the active nozzle
#if ENABLED(ULTRA_LCD)
lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99);
lcd_quick_feedback();
#endif
thermalManager.setTargetHotend(g26_hotend_temp, active_extruder);
// Wait for the temperature to stabilize
if (!thermalManager.wait_for_hotend(active_extruder, true
#if G26_CLICK_CAN_CANCEL
, true
#endif
)
) return G26_ERR;
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
lcd_reset_status(); lcd_reset_status();
lcd_quick_feedback(true); lcd_quick_feedback();
#endif #endif
return G26_OK; return G26_OK;
@ -507,7 +494,7 @@ inline bool prime_nozzle() {
wait_for_release(); wait_for_release();
lcd_setstatusPGM(PSTR("Done Priming"), 99); lcd_setstatusPGM(PSTR("Done Priming"), 99);
lcd_quick_feedback(true); lcd_quick_feedback();
lcd_external_control = false; lcd_external_control = false;
} }
else else
@ -515,7 +502,7 @@ inline bool prime_nozzle() {
{ {
#if ENABLED(ULTRA_LCD) #if ENABLED(ULTRA_LCD)
lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99); lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99);
lcd_quick_feedback(true); lcd_quick_feedback();
#endif #endif
set_destination_from_current(); set_destination_from_current();
destination[E_AXIS] += g26_prime_length; destination[E_AXIS] += g26_prime_length;
@ -553,17 +540,21 @@ float valid_trig_angle(float d) {
* Q Retraction multiplier * Q Retraction multiplier
* R Repetitions (number of grid points) * R Repetitions (number of grid points)
* S Nozzle Size (diameter) in mm * S Nozzle Size (diameter) in mm
* T Tool index to change to, if included
* U Random deviation (50 if no value given) * U Random deviation (50 if no value given)
* X X position * X X position
* Y Y position * Y Y position
*/ */
void GcodeSuite::G26() { void GcodeSuite::G26() {
SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s)."); SERIAL_ECHOLNPGM("G26 starting...");
// Don't allow Mesh Validation without homing first, // Don't allow Mesh Validation without homing first,
// or if the parameter parsing did not go OK, abort // or if the parameter parsing did not go OK, abort
if (axis_unhomed_error()) return; if (axis_unhomed_error()) return;
// Change the tool first, if specified
if (parser.seenval('T')) tool_change(parser.value_int());
g26_extrusion_multiplier = EXTRUSION_MULTIPLIER; g26_extrusion_multiplier = EXTRUSION_MULTIPLIER;
g26_retraction_multiplier = RETRACTION_MULTIPLIER; g26_retraction_multiplier = RETRACTION_MULTIPLIER;
g26_layer_height = MESH_TEST_LAYER_HEIGHT; g26_layer_height = MESH_TEST_LAYER_HEIGHT;
@ -891,6 +882,7 @@ void GcodeSuite::G26() {
LEAVE: LEAVE:
lcd_setstatusPGM(PSTR("Leaving G26"), -1); lcd_setstatusPGM(PSTR("Leaving G26"), -1);
wait_for_release();
retract_filament(destination); retract_filament(destination);
destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;
@ -914,7 +906,7 @@ void GcodeSuite::G26() {
#if HAS_HEATED_BED #if HAS_HEATED_BED
thermalManager.setTargetBed(0); thermalManager.setTargetBed(0);
#endif #endif
thermalManager.setTargetHotend(0, 0); thermalManager.setTargetHotend(active_extruder, 0);
} }
} }

View file

@ -30,7 +30,6 @@ extern bool screen_changed;
constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP); constexpr int16_t heater_maxtemp[HOTENDS] = ARRAY_BY_HOTENDS(HEATER_0_MAXTEMP, HEATER_1_MAXTEMP, HEATER_2_MAXTEMP, HEATER_3_MAXTEMP, HEATER_4_MAXTEMP);
void scroll_screen(const uint8_t limit, const bool is_menu); void scroll_screen(const uint8_t limit, const bool is_menu);
bool use_click();
bool printer_busy(); bool printer_busy();
void lcd_completion_feedback(const bool good=true); void lcd_completion_feedback(const bool good=true);
void lcd_save_previous_screen(); void lcd_save_previous_screen();

View file

@ -244,8 +244,8 @@ bool lcd_blink() {
#if HAS_LCD_MENU #if HAS_LCD_MENU
if (RRK(EN_REPRAPWORLD_KEYPAD_DOWN)) encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM; if (RRK(EN_REPRAPWORLD_KEYPAD_DOWN)) encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM;
else if (RRK(EN_REPRAPWORLD_KEYPAD_UP)) encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; else if (RRK(EN_REPRAPWORLD_KEYPAD_UP)) encoderPosition += ENCODER_STEPS_PER_MENU_ITEM;
else if (RRK(EN_REPRAPWORLD_KEYPAD_LEFT)) { menu_item_back::action(); lcd_quick_feedback(true); } else if (RRK(EN_REPRAPWORLD_KEYPAD_LEFT)) { menu_item_back::action(); lcd_quick_feedback(); }
else if (RRK(EN_REPRAPWORLD_KEYPAD_RIGHT)) { lcd_return_to_status(); lcd_quick_feedback(true); } else if (RRK(EN_REPRAPWORLD_KEYPAD_RIGHT)) { lcd_return_to_status(); lcd_quick_feedback(); }
#endif #endif
} }
else if (RRK(EN_REPRAPWORLD_KEYPAD_DOWN)) encoderPosition += ENCODER_PULSES_PER_STEP; else if (RRK(EN_REPRAPWORLD_KEYPAD_DOWN)) encoderPosition += ENCODER_PULSES_PER_STEP;
@ -484,7 +484,7 @@ void kill_screen(PGM_P lcd_msg) {
} }
#endif #endif
void lcd_quick_feedback(const bool clear_buttons) { void lcd_quick_feedback(const bool clear_buttons/*=true*/) {
#if HAS_LCD_MENU #if HAS_LCD_MENU
lcd_refresh(); lcd_refresh();
@ -661,14 +661,14 @@ void lcd_update() {
wait_for_unclick = true; // Set debounce flag to ignore continous clicks wait_for_unclick = true; // Set debounce flag to ignore continous clicks
lcd_clicked = !wait_for_user && !no_reentry; // Keep the click if not waiting for a user-click lcd_clicked = !wait_for_user && !no_reentry; // Keep the click if not waiting for a user-click
wait_for_user = false; // Any click clears wait for user wait_for_user = false; // Any click clears wait for user
lcd_quick_feedback(true); // Always make a click sound lcd_quick_feedback(); // Always make a click sound
} }
} }
else wait_for_unclick = false; else wait_for_unclick = false;
#if BUTTON_EXISTS(BACK) #if BUTTON_EXISTS(BACK)
if (LCD_BACK_CLICKED) { if (LCD_BACK_CLICKED) {
lcd_quick_feedback(true); lcd_quick_feedback();
lcd_goto_previous_menu(); lcd_goto_previous_menu();
} }
#endif #endif

View file

@ -242,7 +242,7 @@
inline void lcd_buzz(const long duration, const uint16_t freq) { UNUSED(duration); UNUSED(freq); } inline void lcd_buzz(const long duration, const uint16_t freq) { UNUSED(duration); UNUSED(freq); }
#endif #endif
void lcd_quick_feedback(const bool clear_buttons); // Audible feedback for a button click - could also be visual void lcd_quick_feedback(const bool clear_buttons=true); // Audible feedback for a button click - could also be visual
#if ENABLED(LCD_PROGRESS_BAR) #if ENABLED(LCD_PROGRESS_BAR)
extern millis_t progress_bar_ms; // Start time for the current progress bar cycle extern millis_t progress_bar_ms; // Start time for the current progress bar cycle
@ -351,6 +351,8 @@
bool lcd_blink(); bool lcd_blink();
bool use_click();
#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION)
bool is_lcd_clicked(); bool is_lcd_clicked();
void wait_for_release(); void wait_for_release();

View file

@ -2441,7 +2441,11 @@ void Temperature::isr() {
#define MIN_COOLING_SLOPE_TIME 60 #define MIN_COOLING_SLOPE_TIME 60
#endif #endif
bool Temperature::wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling/*=true*/) { bool Temperature::wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling/*=true*/
#if G26_CLICK_CAN_CANCEL
, const bool click_to_cancel/*=false*/
#endif
) {
#if TEMP_RESIDENCY_TIME > 0 #if TEMP_RESIDENCY_TIME > 0
millis_t residency_start_ms = 0; millis_t residency_start_ms = 0;
// Loop until the temperature has stabilized // Loop until the temperature has stabilized
@ -2525,6 +2529,13 @@ void Temperature::isr() {
} }
} }
#if G26_CLICK_CAN_CANCEL
if (click_to_cancel && use_click()) {
wait_for_heatup = false;
lcd_quick_feedback();
}
#endif
} while (wait_for_heatup && TEMP_CONDITIONS); } while (wait_for_heatup && TEMP_CONDITIONS);
if (wait_for_heatup) { if (wait_for_heatup) {
@ -2552,7 +2563,11 @@ void Temperature::isr() {
#define MIN_COOLING_SLOPE_TIME_BED 60 #define MIN_COOLING_SLOPE_TIME_BED 60
#endif #endif
void Temperature::wait_for_bed(const bool no_wait_for_cooling) { bool Temperature::wait_for_bed(const bool no_wait_for_cooling
#if G26_CLICK_CAN_CANCEL
, const bool click_to_cancel/*=false*/
#endif
) {
#if TEMP_BED_RESIDENCY_TIME > 0 #if TEMP_BED_RESIDENCY_TIME > 0
millis_t residency_start_ms = 0; millis_t residency_start_ms = 0;
// Loop until the temperature has stabilized // Loop until the temperature has stabilized
@ -2639,6 +2654,13 @@ void Temperature::isr() {
} }
} }
#if G26_CLICK_CAN_CANCEL
if (click_to_cancel && use_click()) {
wait_for_heatup = false;
lcd_quick_feedback();
}
#endif
} while (wait_for_heatup && TEMP_BED_CONDITIONS); } while (wait_for_heatup && TEMP_BED_CONDITIONS);
if (wait_for_heatup) lcd_reset_status(); if (wait_for_heatup) lcd_reset_status();
@ -2646,6 +2668,8 @@ void Temperature::isr() {
#if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE) #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
gcode.busy_state = old_busy_state; gcode.busy_state = old_busy_state;
#endif #endif
return wait_for_heatup;
} }
#endif // HAS_HEATED_BED #endif // HAS_HEATED_BED

View file

@ -138,6 +138,8 @@ enum ADCSensorState : char {
#define unscalePID_d(d) ( float(d) * PID_dT ) #define unscalePID_d(d) ( float(d) * PID_dT )
#endif #endif
#define G26_CLICK_CAN_CANCEL (HAS_LCD_MENU && ENABLED(G26_MESH_VALIDATION))
class Temperature { class Temperature {
public: public:
@ -426,7 +428,11 @@ class Temperature {
} }
#if HAS_TEMP_HOTEND #if HAS_TEMP_HOTEND
static bool wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling=true); static bool wait_for_hotend(const uint8_t target_extruder, const bool no_wait_for_cooling=true
#if G26_CLICK_CAN_CANCEL
, const bool click_to_cancel=false
#endif
);
#endif #endif
#if HAS_HEATED_BED #if HAS_HEATED_BED
@ -459,7 +465,11 @@ class Temperature {
static void start_watching_bed(); static void start_watching_bed();
#endif #endif
static void wait_for_bed(const bool no_wait_for_cooling); static bool wait_for_bed(const bool no_wait_for_cooling
#if G26_CLICK_CAN_CANCEL
, const bool click_to_cancel=false
#endif
);
#endif // HAS_HEATED_BED #endif // HAS_HEATED_BED