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:
		| @@ -630,7 +630,7 @@ | ||||
|  | ||||
|     #if HAS_LCD_MENU | ||||
|       lcd_reset_alert_level(); | ||||
|       lcd_quick_feedback(true); | ||||
|       lcd_quick_feedback(); | ||||
|       lcd_reset_status(); | ||||
|       lcd_external_control = false; | ||||
|     #endif | ||||
| @@ -689,16 +689,14 @@ | ||||
|  | ||||
|     bool click_and_hold(const clickFunc_t func=NULL) { | ||||
|       if (is_lcd_clicked()) { | ||||
|         lcd_quick_feedback(false); // Do NOT clear button status!  If cleared, the code | ||||
|                                    // code can not look for a 'click and hold' | ||||
|         lcd_quick_feedback(false);                // Preserve button state for click-and-hold | ||||
|         const millis_t nxt = millis() + 1500UL; | ||||
|         while (is_lcd_clicked()) {                // Loop while the encoder is pressed. Uses hardware flag! | ||||
|           idle();                                 // idle, of course | ||||
|           if (ELAPSED(millis(), nxt)) {           // After 1.5 seconds | ||||
|             lcd_quick_feedback(true); | ||||
|             lcd_quick_feedback(); | ||||
|             if (func) (*func)(); | ||||
|             wait_for_release(); | ||||
|             safe_delay(50);                       // Debounce the Encoder wheel | ||||
|             return true; | ||||
|           } | ||||
|         } | ||||
| @@ -721,7 +719,7 @@ | ||||
|         lcd_external_control = true; | ||||
|       #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(); | ||||
|  | ||||
|       uint16_t count = GRID_MAX_POINTS; | ||||
| @@ -731,14 +729,13 @@ | ||||
|  | ||||
|         #if HAS_LCD_MENU | ||||
|           if (is_lcd_clicked()) { | ||||
|             lcd_quick_feedback(false); // Preserve button state for click-and-hold | ||||
|             SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n"); | ||||
|             lcd_quick_feedback(false); | ||||
|             STOW_PROBE(); | ||||
|             while (is_lcd_clicked()) idle(); | ||||
|             wait_for_release(); | ||||
|             lcd_quick_feedback(); | ||||
|             lcd_external_control = false; | ||||
|             restore_ubl_active_state_and_leave(); | ||||
|             lcd_quick_feedback(true); | ||||
|             safe_delay(50);  // Debounce the Encoder wheel | ||||
|             return; | ||||
|           } | ||||
|         #endif | ||||
| @@ -843,7 +840,7 @@ | ||||
|       do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); | ||||
|       lcd_external_control = false; | ||||
|       KEEPALIVE_STATE(IN_HANDLER); | ||||
|       lcd_quick_feedback(true); | ||||
|       lcd_quick_feedback(); | ||||
|       ubl.restore_ubl_active_state_and_leave(); | ||||
|     } | ||||
|  | ||||
| @@ -910,12 +907,16 @@ | ||||
|     } | ||||
|   #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 err_flag = false; | ||||
|  | ||||
|     #if HAS_LCD_MENU | ||||
|       LCD_MESSAGEPGM(MSG_UBL_DOING_G29); | ||||
|       lcd_quick_feedback(true); | ||||
|       set_message_with_feedback(PSTR(MSG_UBL_DOING_G29)); | ||||
|     #endif | ||||
|  | ||||
|     g29_constant = 0; | ||||
| @@ -1037,8 +1038,7 @@ | ||||
|       if (ubl_state_recursion_chk != 1) { | ||||
|         SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); | ||||
|         #if HAS_LCD_MENU | ||||
|           LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); | ||||
|           lcd_quick_feedback(true); | ||||
|           set_message_with_feedback(PSTR(MSG_UBL_SAVE_ERROR)); | ||||
|         #endif | ||||
|         return; | ||||
|       } | ||||
| @@ -1052,8 +1052,7 @@ | ||||
|       if (--ubl_state_recursion_chk) { | ||||
|         SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); | ||||
|         #if HAS_LCD_MENU | ||||
|           LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); | ||||
|           lcd_quick_feedback(true); | ||||
|           set_message_with_feedback(PSTR(MSG_UBL_RESTORE_ERROR)); | ||||
|         #endif | ||||
|         return; | ||||
|       } | ||||
| @@ -1344,8 +1343,7 @@ | ||||
|     void abort_fine_tune() { | ||||
|       lcd_return_to_status(); | ||||
|       do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); | ||||
|       LCD_MESSAGEPGM(MSG_EDITING_STOPPED); | ||||
|       lcd_quick_feedback(true); | ||||
|       set_message_with_feedback(PSTR(MSG_EDITING_STOPPED)); | ||||
|     } | ||||
|  | ||||
|     void unified_bed_leveling::fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) { | ||||
|   | ||||
| @@ -38,6 +38,7 @@ | ||||
| #include "../../module/planner.h" | ||||
| #include "../../module/stepper.h" | ||||
| #include "../../module/motion.h" | ||||
| #include "../../module/tool_change.h" | ||||
| #include "../../module/temperature.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 | ||||
|     lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99); | ||||
|     #if HAS_LCD_MENU | ||||
|       lcd_quick_feedback(true); | ||||
|       lcd_quick_feedback(); | ||||
|     #endif | ||||
|     wait_for_release(); | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   bool exit_from_g26() { | ||||
|     lcd_setstatusPGM(PSTR("Leaving G26"), -1); | ||||
|     wait_for_release(); | ||||
|     return G26_ERR; | ||||
|   } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| 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. | ||||
|  */ | ||||
| inline bool turn_on_heaters() { | ||||
|   millis_t next = millis() + 5000UL; | ||||
|  | ||||
|   SERIAL_ECHOLNPGM("Waiting for heatup."); | ||||
|  | ||||
|   #if HAS_HEATED_BED | ||||
|     #if ENABLED(ULTRA_LCD) | ||||
|  | ||||
|     if (g26_bed_temp > 25) { | ||||
|       #if ENABLED(ULTRA_LCD) | ||||
|         lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99); | ||||
|         lcd_quick_feedback(true); | ||||
|         lcd_quick_feedback(); | ||||
|         #if HAS_LCD_MENU | ||||
|           lcd_external_control = true; | ||||
|         #endif | ||||
|       #endif | ||||
|       thermalManager.setTargetBed(g26_bed_temp); | ||||
|         while (ABS(thermalManager.degBed() - g26_bed_temp) > 3) { | ||||
|  | ||||
|           #if HAS_LCD_MENU | ||||
|             if (is_lcd_clicked()) return exit_from_g26(); | ||||
|       // Wait for the temperature to stabilize | ||||
|       if (!thermalManager.wait_for_bed(true | ||||
|           #if G26_CLICK_CAN_CANCEL | ||||
|             , true | ||||
|           #endif | ||||
|         ) | ||||
|       ) return G26_ERR; | ||||
|     } | ||||
|  | ||||
|           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(true); | ||||
|     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 | ||||
|  | ||||
|   // 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. | ||||
|   } | ||||
|     ) | ||||
|   ) return G26_ERR; | ||||
|  | ||||
|   #if ENABLED(ULTRA_LCD) | ||||
|     lcd_reset_status(); | ||||
|     lcd_quick_feedback(true); | ||||
|     lcd_quick_feedback(); | ||||
|   #endif | ||||
|  | ||||
|   return G26_OK; | ||||
| @@ -507,7 +494,7 @@ inline bool prime_nozzle() { | ||||
|       wait_for_release(); | ||||
|  | ||||
|       lcd_setstatusPGM(PSTR("Done Priming"), 99); | ||||
|       lcd_quick_feedback(true); | ||||
|       lcd_quick_feedback(); | ||||
|       lcd_external_control = false; | ||||
|     } | ||||
|     else | ||||
| @@ -515,7 +502,7 @@ inline bool prime_nozzle() { | ||||
|   { | ||||
|     #if ENABLED(ULTRA_LCD) | ||||
|       lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99); | ||||
|       lcd_quick_feedback(true); | ||||
|       lcd_quick_feedback(); | ||||
|     #endif | ||||
|     set_destination_from_current(); | ||||
|     destination[E_AXIS] += g26_prime_length; | ||||
| @@ -553,17 +540,21 @@ float valid_trig_angle(float d) { | ||||
|  *  Q  Retraction multiplier | ||||
|  *  R  Repetitions (number of grid points) | ||||
|  *  S  Nozzle Size (diameter) in mm | ||||
|  *  T  Tool index to change to, if included | ||||
|  *  U  Random deviation (50 if no value given) | ||||
|  *  X  X position | ||||
|  *  Y  Y position | ||||
|  */ | ||||
| void GcodeSuite::G26() { | ||||
|   SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s)."); | ||||
|   SERIAL_ECHOLNPGM("G26 starting..."); | ||||
|  | ||||
|   // Don't allow Mesh Validation without homing first, | ||||
|   // or if the parameter parsing did not go OK, abort | ||||
|   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_retraction_multiplier   = RETRACTION_MULTIPLIER; | ||||
|   g26_layer_height            = MESH_TEST_LAYER_HEIGHT; | ||||
| @@ -891,6 +882,7 @@ void GcodeSuite::G26() { | ||||
|  | ||||
|   LEAVE: | ||||
|   lcd_setstatusPGM(PSTR("Leaving G26"), -1); | ||||
|   wait_for_release(); | ||||
|  | ||||
|   retract_filament(destination); | ||||
|   destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; | ||||
| @@ -914,7 +906,7 @@ void GcodeSuite::G26() { | ||||
|     #if HAS_HEATED_BED | ||||
|       thermalManager.setTargetBed(0); | ||||
|     #endif | ||||
|     thermalManager.setTargetHotend(0, 0); | ||||
|     thermalManager.setTargetHotend(active_extruder, 0); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
| void scroll_screen(const uint8_t limit, const bool is_menu); | ||||
| bool use_click(); | ||||
| bool printer_busy(); | ||||
| void lcd_completion_feedback(const bool good=true); | ||||
| void lcd_save_previous_screen(); | ||||
|   | ||||
| @@ -244,8 +244,8 @@ bool lcd_blink() { | ||||
|           #if HAS_LCD_MENU | ||||
|             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_LEFT))   { menu_item_back::action(); lcd_quick_feedback(true); } | ||||
|             else if (RRK(EN_REPRAPWORLD_KEYPAD_RIGHT))  { lcd_return_to_status(); 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(); } | ||||
|           #endif | ||||
|         } | ||||
|         else if (RRK(EN_REPRAPWORLD_KEYPAD_DOWN))     encoderPosition += ENCODER_PULSES_PER_STEP; | ||||
| @@ -484,7 +484,7 @@ void kill_screen(PGM_P lcd_msg) { | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| void lcd_quick_feedback(const bool clear_buttons) { | ||||
| void lcd_quick_feedback(const bool clear_buttons/*=true*/) { | ||||
|  | ||||
|   #if HAS_LCD_MENU | ||||
|     lcd_refresh(); | ||||
| @@ -661,14 +661,14 @@ void lcd_update() { | ||||
|         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 | ||||
|         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; | ||||
|  | ||||
|     #if BUTTON_EXISTS(BACK) | ||||
|       if (LCD_BACK_CLICKED) { | ||||
|         lcd_quick_feedback(true); | ||||
|         lcd_quick_feedback(); | ||||
|         lcd_goto_previous_menu(); | ||||
|       } | ||||
|     #endif | ||||
|   | ||||
| @@ -242,7 +242,7 @@ | ||||
|     inline void lcd_buzz(const long duration, const uint16_t freq) { UNUSED(duration); UNUSED(freq); } | ||||
|   #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) | ||||
|     extern millis_t progress_bar_ms;  // Start time for the current progress bar cycle | ||||
| @@ -351,6 +351,8 @@ | ||||
|  | ||||
|   bool lcd_blink(); | ||||
|  | ||||
|   bool use_click(); | ||||
|  | ||||
|   #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) | ||||
|     bool is_lcd_clicked(); | ||||
|     void wait_for_release(); | ||||
|   | ||||
| @@ -2441,7 +2441,11 @@ void Temperature::isr() { | ||||
|       #define MIN_COOLING_SLOPE_TIME 60 | ||||
|     #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 | ||||
|         millis_t residency_start_ms = 0; | ||||
|         // 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); | ||||
|  | ||||
|       if (wait_for_heatup) { | ||||
| @@ -2552,7 +2563,11 @@ void Temperature::isr() { | ||||
|       #define MIN_COOLING_SLOPE_TIME_BED 60 | ||||
|     #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 | ||||
|         millis_t residency_start_ms = 0; | ||||
|         // 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); | ||||
|  | ||||
|       if (wait_for_heatup) lcd_reset_status(); | ||||
| @@ -2646,6 +2668,8 @@ void Temperature::isr() { | ||||
|       #if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE) | ||||
|         gcode.busy_state = old_busy_state; | ||||
|       #endif | ||||
|  | ||||
|       return wait_for_heatup; | ||||
|     } | ||||
|  | ||||
|   #endif // HAS_HEATED_BED | ||||
|   | ||||
| @@ -138,6 +138,8 @@ enum ADCSensorState : char { | ||||
|   #define unscalePID_d(d) ( float(d) * PID_dT ) | ||||
| #endif | ||||
|  | ||||
| #define G26_CLICK_CAN_CANCEL (HAS_LCD_MENU && ENABLED(G26_MESH_VALIDATION)) | ||||
|  | ||||
| class Temperature { | ||||
|  | ||||
|   public: | ||||
| @@ -426,7 +428,11 @@ class Temperature { | ||||
|     } | ||||
|  | ||||
|     #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 | ||||
|  | ||||
|     #if HAS_HEATED_BED | ||||
| @@ -459,7 +465,11 @@ class Temperature { | ||||
|         static void start_watching_bed(); | ||||
|       #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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user