diff --git a/.gitignore b/.gitignore index a9267a2dcc..74f5a99dd4 100755 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ tags *.lo *.o *.obj +*.ino.cpp # Precompiled Headers *.gch diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index a5c42c5f6b..1806188a80 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -3800,6 +3800,10 @@ void home_all_axes() { gcode_G28(true); } #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) + #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING) + extern bool lcd_wait_for_move; + #endif + inline void _manual_goto_xy(const float &x, const float &y) { const float old_feedrate_mm_s = feedrate_mm_s; @@ -3822,6 +3826,10 @@ void home_all_axes() { gcode_G28(true); } feedrate_mm_s = old_feedrate_mm_s; stepper.synchronize(); + + #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING) + lcd_wait_for_move = false; + #endif } #endif @@ -4190,7 +4198,7 @@ void home_all_axes() { gcode_G28(true); } if (!g29_in_progress) { #if ENABLED(PROBE_MANUALLY) || ENABLED(AUTO_BED_LEVELING_LINEAR) - abl_probe_index = 0; + abl_probe_index = -1; #endif abl_should_enable = planner.abl_enabled; @@ -4397,30 +4405,40 @@ void home_all_axes() { gcode_G28(true); } #if ENABLED(PROBE_MANUALLY) + const bool seenA = parser.seen('A'), seenQ = parser.seen('Q'); + + // For manual probing, get the next index to probe now. + // On the first probe this will be incremented to 0. + if (!seenA && !seenQ) { + ++abl_probe_index; + g29_in_progress = true; + } + // Abort current G29 procedure, go back to ABLStart - if (parser.seen('A') && g29_in_progress) { + if (seenA && g29_in_progress) { SERIAL_PROTOCOLLNPGM("Manual G29 aborted"); #if HAS_SOFTWARE_ENDSTOPS soft_endstops_enabled = enable_soft_endstops; #endif planner.abl_enabled = abl_should_enable; g29_in_progress = false; + #if ENABLED(LCD_BED_LEVELING) + lcd_wait_for_move = false; + #endif } // Query G29 status - if (parser.seen('Q')) { - if (!g29_in_progress) - SERIAL_PROTOCOLLNPGM("Manual G29 idle"); - else { - SERIAL_PROTOCOLPAIR("Manual G29 point ", abl_probe_index + 1); + if (verbose_level || seenQ) { + SERIAL_PROTOCOLPGM("Manual G29 "); + if (g29_in_progress) { + SERIAL_PROTOCOLPAIR("point ", abl_probe_index + 1); SERIAL_PROTOCOLLNPAIR(" of ", abl2); } + else + SERIAL_PROTOCOLLNPGM("idle"); } - if (parser.seen('A') || parser.seen('Q')) return; - - // Fall through to probe the first point - g29_in_progress = true; + if (seenA || seenQ) return; if (abl_probe_index == 0) { // For the initial G29 save software endstop state @@ -4458,20 +4476,20 @@ void home_all_axes() { gcode_G28(true); } #if ABL_GRID - // Find a next point to probe - // On the first G29 this will be the first probe point + // Skip any unreachable points while (abl_probe_index < abl2) { // Set xCount, yCount based on abl_probe_index, with zig-zag PR_OUTER_VAR = abl_probe_index / PR_INNER_END; PR_INNER_VAR = abl_probe_index - (PR_OUTER_VAR * PR_INNER_END); - bool zig = (PR_OUTER_VAR & 1) != ((PR_OUTER_END) & 1); + // Probe in reverse order for every other row/column + bool zig = (PR_OUTER_VAR & 1); // != ((PR_OUTER_END) & 1); if (zig) PR_INNER_VAR = (PR_INNER_END - 1) - PR_INNER_VAR; - const float xBase = left_probe_bed_position + xGridSpacing * xCount, - yBase = front_probe_bed_position + yGridSpacing * yCount; + const float xBase = xCount * xGridSpacing + left_probe_bed_position, + yBase = yCount * yGridSpacing + front_probe_bed_position; xProbe = floor(xBase + (xBase < 0 ? 0 : 0.5)); yProbe = floor(yBase + (yBase < 0 ? 0 : 0.5)); @@ -4488,7 +4506,6 @@ void home_all_axes() { gcode_G28(true); } // Is there a next point to move to? if (abl_probe_index < abl2) { _manual_goto_xy(xProbe, yProbe); // Can be used here too! - ++abl_probe_index; #if HAS_SOFTWARE_ENDSTOPS // Disable software endstops to allow manual adjustment // If G29 is not completed, they will not be re-enabled @@ -4497,10 +4514,9 @@ void home_all_axes() { gcode_G28(true); } return; } else { - // Then leveling is done! - // G29 finishing code goes here - // After recording the last point, activate abl + // Leveling done! Fall through to G29 finishing code below + SERIAL_PROTOCOLLNPGM("Grid probing done."); g29_in_progress = false; @@ -4514,9 +4530,8 @@ void home_all_axes() { gcode_G28(true); } // Probe at 3 arbitrary points if (abl_probe_index < 3) { - xProbe = LOGICAL_X_POSITION(points[i].x); - yProbe = LOGICAL_Y_POSITION(points[i].y); - ++abl_probe_index; + xProbe = LOGICAL_X_POSITION(points[abl_probe_index].x); + yProbe = LOGICAL_Y_POSITION(points[abl_probe_index].y); #if HAS_SOFTWARE_ENDSTOPS // Disable software endstops to allow manual adjustment // If G29 is not completed, they will not be re-enabled @@ -4587,7 +4602,7 @@ void home_all_axes() { gcode_G28(true); } yProbe = floor(yBase + (yBase < 0 ? 0 : 0.5)); #if ENABLED(AUTO_BED_LEVELING_LINEAR) - indexIntoAB[xCount][yCount] = ++abl_probe_index; + indexIntoAB[xCount][yCount] = ++abl_probe_index; // 0... #endif #if IS_KINEMATIC @@ -4665,7 +4680,10 @@ void home_all_axes() { gcode_G28(true); } // G29 Finishing Code // // Unless this is a dry run, auto bed leveling will - // definitely be enabled after this point + // definitely be enabled after this point. + // + // If code above wants to continue leveling, it should + // return or loop before this point. // // Restore state after probing @@ -4675,6 +4693,10 @@ void home_all_axes() { gcode_G28(true); } if (DEBUGGING(LEVELING)) DEBUG_POS("> probing complete", current_position); #endif + #if ENABLED(PROBE_MANUALLY) && ENABLED(LCD_BED_LEVELING) + lcd_wait_for_move = false; + #endif + // Calculate leveling, print reports, correct the position #if ENABLED(AUTO_BED_LEVELING_BILINEAR) diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 2d2a225793..c39508f50d 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -1344,9 +1344,8 @@ void MarlinSettings::reset() { #else #define LINEAR_UNIT(N) N #define VOLUMETRIC_UNIT(N) N - SERIAL_ECHOLNPGM(" G21 ; Units in mm\n"); + SERIAL_ECHOLNPGM(" G21 ; Units in mm"); #endif - SERIAL_EOL; #if ENABLED(ULTIPANEL) @@ -1361,12 +1360,13 @@ void MarlinSettings::reset() { serialprintPGM(parser.temp_units_name()); #else #define TEMP_UNIT(N) N - SERIAL_ECHOLNPGM(" M149 C ; Units in Celsius\n"); + SERIAL_ECHOLNPGM(" M149 C ; Units in Celsius"); #endif - SERIAL_EOL; #endif + SERIAL_EOL; + /** * Volumetric extrusion M200 */ diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp old mode 100644 new mode 100755 index 9a2b9c46d0..54da69fc56 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -78,9 +78,6 @@ uint16_t max_display_update_time = 0; #if ENABLED(DOGLCD) bool drawing_screen = false; - #define LCDVIEW_KEEP_REDRAWING LCDVIEW_CALL_REDRAW_NEXT -#else - #define LCDVIEW_KEEP_REDRAWING LCDVIEW_REDRAW_NOW #endif #if ENABLED(DAC_STEPPER_CURRENT) @@ -479,22 +476,18 @@ uint16_t max_display_update_time = 0; } /** - * Synchronize safely while holding the current screen - * This blocks all further screen or stripe updates once called + * Show "Moving..." till moves are done, then revert to previous display. */ - extern uint8_t commands_in_queue; - inline void lcd_synchronize() { static bool no_reentry = false; lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, PSTR(MSG_MOVING)); if (no_reentry) return; + + // Make this the current handler till all moves are done no_reentry = true; screenFunc_t old_screen = currentScreen; lcd_goto_screen(lcd_synchronize); - while (commands_in_queue) { - idle(); - stepper.synchronize(); - } + stepper.synchronize(); no_reentry = false; lcd_goto_screen(old_screen); } @@ -879,7 +872,7 @@ void kill_screen(const char* lcd_msg) { if (encoderPosition) { const int babystep_increment = (int32_t)encoderPosition * (BABYSTEP_MULTIPLICATOR); encoderPosition = 0; - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; thermalManager.babystep_axis(axis, babystep_increment); babysteps_done += babystep_increment; } @@ -912,7 +905,7 @@ void kill_screen(const char* lcd_msg) { zprobe_zoffset = new_zoffset; refresh_zprobe_zoffset(true); - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; } } if (lcdDrawUpdate) @@ -943,7 +936,7 @@ void kill_screen(const char* lcd_msg) { mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005 / 2.0; mesh_edit_value = mesh_edit_accumulator; encoderPosition = 0; - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; const int32_t rounded = (int32_t)(mesh_edit_value * 1000.0); mesh_edit_value = float(rounded - (rounded % 5L)) / 1000.0; @@ -1422,7 +1415,7 @@ void kill_screen(const char* lcd_msg) { constexpr uint8_t total_probe_points = ( #if ENABLED(AUTO_BED_LEVELING_3POINT) 3 - #elif ABL_GRID || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING) + #elif ABL_GRID || ENABLED(MESH_BED_LEVELING) GRID_MAX_POINTS #endif ); @@ -1447,26 +1440,12 @@ void kill_screen(const char* lcd_msg) { #endif // MESH_BED_LEVELING - #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) - void _lcd_level_goto_next_point(); - #endif - void _lcd_level_bed_done() { if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_DONE)); - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; } - /** - * Step 6: Display "Next point: 1 / 9" while waiting for move to finish - */ - void _lcd_level_bed_moving() { - if (lcdDrawUpdate) { - char msg[10]; - sprintf_P(msg, PSTR("%i / %u"), (int)(manual_probe_index + 1), total_probe_points); - lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_NEXT_POINT), msg); - } - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; - } + void _lcd_level_goto_next_point(); /** * Step 7: Get the Z coordinate, click goes to the next point or exits @@ -1474,40 +1453,24 @@ void kill_screen(const char* lcd_msg) { void _lcd_level_bed_get_z() { ENCODER_DIRECTION_NORMAL(); - // Encoder knob or keypad buttons adjust the Z position - if (encoderPosition) { - refresh_cmd_timeout(); - current_position[Z_AXIS] += float((int32_t)encoderPosition) * (MBL_Z_STEP); - NOLESS(current_position[Z_AXIS], -(LCD_PROBE_Z_RANGE) * 0.5); - NOMORE(current_position[Z_AXIS], (LCD_PROBE_Z_RANGE) * 0.5); - line_to_current(Z_AXIS); - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; - encoderPosition = 0; - } - if (lcd_clicked) { // Use a hook to set the probe point z - // (zigzag arranges in XY order) - #if ENABLED(AUTO_BED_LEVELING_UBL) + #if ENABLED(MESH_BED_LEVELING) - // UBL set-z handling goes here + // MBL records the position but doesn't move to the next one + mbl.set_zigzag_z(manual_probe_index, current_position[Z_AXIS]); #elif ENABLED(PROBE_MANUALLY) - // G29 helpfully records Z and goes to the next - // point (or beeps if done) - enqueue_and_echo_commands_P(PSTR("G29")); - manual_probe_index++; - - #elif ENABLED(MESH_BED_LEVELING) - - mbl.set_zigzag_z(manual_probe_index++, current_position[Z_AXIS]); + // The last G29 will record but not move + if (manual_probe_index == total_probe_points - 1) + enqueue_and_echo_commands_P("G29 V1"); #endif // If done... - if (manual_probe_index == total_probe_points) { + if (++manual_probe_index >= total_probe_points) { // Say "Done!" lcd_goto_screen(_lcd_level_bed_done); @@ -1526,10 +1489,6 @@ void kill_screen(const char* lcd_msg) { mbl.set_has_mesh(true); mesh_probing_done(); - #elif ENABLED(AUTO_BED_LEVELING_UBL) - - // UBL enable goes here - #elif ENABLED(PROBE_MANUALLY) // ABL will be enabled due to "G29". @@ -1540,19 +1499,21 @@ void kill_screen(const char* lcd_msg) { //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE); lcd_completion_feedback(); } - else { + else + _lcd_level_goto_next_point(); - // Move to the next probe point, if needed - #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) + return; + } - _lcd_level_goto_next_point(); - - #elif ENABLED(AUTO_BED_LEVELING_UBL) - - // UBL goto-next-point goes here - - #endif - } + // Encoder knob or keypad buttons adjust the Z position + if (encoderPosition) { + refresh_cmd_timeout(); + current_position[Z_AXIS] += float((int32_t)encoderPosition) * (MBL_Z_STEP); + NOLESS(current_position[Z_AXIS], -(LCD_PROBE_Z_RANGE) * 0.5); + NOMORE(current_position[Z_AXIS], (LCD_PROBE_Z_RANGE) * 0.5); + line_to_current(Z_AXIS); + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; + encoderPosition = 0; } // Update on first display, then only on updates to Z position @@ -1563,43 +1524,56 @@ void kill_screen(const char* lcd_msg) { } } - #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) + /** + * Step 6: Display "Next point: 1 / 9" while waiting for move to finish + */ - /** - * Step 5: Initiate a move to the next point - */ - void _lcd_level_goto_next_point() { + #if ENABLED(PROBE_MANUALLY) + bool lcd_wait_for_move; + #endif - // Set the menu to display ahead of blocking call - lcd_goto_screen(_lcd_level_bed_moving); + void _lcd_level_bed_moving() { + if (lcdDrawUpdate) { + char msg[10]; + sprintf_P(msg, PSTR("%i / %u"), (int)(manual_probe_index + 1), total_probe_points); + lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_NEXT_POINT), msg); + } + lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; + #if ENABLED(PROBE_MANUALLY) + if (!lcd_wait_for_move) lcd_goto_screen(_lcd_level_bed_get_z); + #endif + } - #if ENABLED(MESH_BED_LEVELING) + /** + * Step 5: Initiate a move to the next point + */ + void _lcd_level_goto_next_point() { - int8_t px, py; - mbl.zigzag(manual_probe_index, px, py); + // Set the menu to display ahead of blocking call + lcd_goto_screen(_lcd_level_bed_moving); - // Controls the loop until the move is done - _manual_probe_goto_xy( - LOGICAL_X_POSITION(mbl.index_to_xpos[px]), - LOGICAL_Y_POSITION(mbl.index_to_ypos[py]) - ); + #if ENABLED(MESH_BED_LEVELING) - #elif ENABLED(AUTO_BED_LEVELING_UBL) + int8_t px, py; + mbl.zigzag(manual_probe_index, px, py); - // UBL may have its own methodology - - #elif ENABLED(PROBE_MANUALLY) - - // Just wait for the G29 move to complete - lcd_synchronize(); - - #endif + // Controls the loop until the move is done + _manual_probe_goto_xy( + LOGICAL_X_POSITION(mbl.index_to_xpos[px]), + LOGICAL_Y_POSITION(mbl.index_to_ypos[py]) + ); // After the blocking function returns, change menus lcd_goto_screen(_lcd_level_bed_get_z); - } - #endif // MESH_BED_LEVELING + #elif ENABLED(PROBE_MANUALLY) + + // G29 will signal when it's done + lcd_wait_for_move = true; + enqueue_and_echo_commands_P(PSTR("G29 V1")); + + #endif + } /** * Step 4: Display "Click to Begin", wait for click @@ -1609,14 +1583,7 @@ void kill_screen(const char* lcd_msg) { if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING)); if (lcd_clicked) { manual_probe_index = 0; - #if ENABLED(MESH_BED_LEVELING) - _lcd_level_goto_next_point(); - #elif ENABLED(AUTO_BED_LEVELING_UBL) - // UBL click handling should go here - #elif ENABLED(PROBE_MANUALLY) - enqueue_and_echo_commands_P(PSTR("G29")); - _lcd_level_goto_next_point(); - #endif + _lcd_level_goto_next_point(); } } @@ -1625,15 +1592,11 @@ void kill_screen(const char* lcd_msg) { */ void _lcd_level_bed_homing() { if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL); + lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) lcd_goto_screen(_lcd_level_bed_homing_done); - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; } - #endif // LCD_BED_LEVELING - - #if ENABLED(LCD_BED_LEVELING) || HAS_ABL - #if ENABLED(PROBE_MANUALLY) extern bool g29_in_progress; #endif @@ -1642,15 +1605,10 @@ void kill_screen(const char* lcd_msg) { * Step 2: Continue Bed Leveling... */ void _lcd_level_bed_continue() { - #if ENABLED(LCD_BED_LEVELING) defer_return_to_status = true; axis_homed[X_AXIS] = axis_homed[Y_AXIS] = axis_homed[Z_AXIS] = false; lcd_goto_screen(_lcd_level_bed_homing); enqueue_and_echo_commands_P(PSTR("G28")); - #else - lcd_return_to_status(); - enqueue_and_echo_commands_P(axis_homed[X_AXIS] && axis_homed[Y_AXIS] ? PSTR("G29") : PSTR("G28\nG29")); - #endif } /** @@ -1663,368 +1621,367 @@ void kill_screen(const char* lcd_msg) { END_MENU(); } - #if ENABLED(AUTO_BED_LEVELING_UBL) + #elif ENABLED(AUTO_BED_LEVELING_UBL) - void _lcd_ubl_level_bed(); + void _lcd_ubl_level_bed(); - static int ubl_storage_slot = 0, - custom_bed_temp = 50, - custom_hotend_temp = 190, - side_points = 3, - ubl_fillin_amount = 5, - ubl_height_amount, - map_type; + static int ubl_storage_slot = 0, + custom_bed_temp = 50, + custom_hotend_temp = 190, + side_points = 3, + ubl_fillin_amount = 5, + ubl_height_amount, + map_type; - /** - * UBL Build Custom Mesh Command - */ - void _lcd_ubl_build_custom_mesh() { - char UBL_LCD_GCODE[20]; - enqueue_and_echo_commands_P(PSTR("G28")); - #if WATCH_THE_BED - sprintf_P(UBL_LCD_GCODE, PSTR("M190 S%i"), custom_bed_temp); - enqueue_and_echo_command(UBL_LCD_GCODE); - #endif - sprintf_P(UBL_LCD_GCODE, PSTR("M109 S%i"), custom_hotend_temp); + /** + * UBL Build Custom Mesh Command + */ + void _lcd_ubl_build_custom_mesh() { + char UBL_LCD_GCODE[20]; + enqueue_and_echo_commands_P(PSTR("G28")); + #if WATCH_THE_BED + sprintf_P(UBL_LCD_GCODE, PSTR("M190 S%i"), custom_bed_temp); enqueue_and_echo_command(UBL_LCD_GCODE); - enqueue_and_echo_commands_P(PSTR("G29 P1")); - } + #endif + sprintf_P(UBL_LCD_GCODE, PSTR("M109 S%i"), custom_hotend_temp); + enqueue_and_echo_command(UBL_LCD_GCODE); + enqueue_and_echo_commands_P(PSTR("G29 P1")); + } - /** - * UBL Custom Mesh submenu - */ - void _lcd_ubl_custom_mesh() { - START_MENU(); - MENU_BACK(MSG_UBL_BUILD_MESH_MENU); - MENU_ITEM_EDIT(int3, MSG_UBL_CUSTOM_HOTEND_TEMP, &custom_hotend_temp, EXTRUDE_MINTEMP, (HEATER_0_MAXTEMP - 10)); + /** + * UBL Custom Mesh submenu + */ + void _lcd_ubl_custom_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_BUILD_MESH_MENU); + MENU_ITEM_EDIT(int3, MSG_UBL_CUSTOM_HOTEND_TEMP, &custom_hotend_temp, EXTRUDE_MINTEMP, (HEATER_0_MAXTEMP - 10)); + #if WATCH_THE_BED + MENU_ITEM_EDIT(int3, MSG_UBL_CUSTOM_BED_TEMP, &custom_bed_temp, BED_MINTEMP, (BED_MAXTEMP - 5)); + #endif + MENU_ITEM(function, MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_build_custom_mesh); + END_MENU(); + } + + /** + * UBL Adjust Mesh Height Command + */ + void _lcd_ubl_adjust_height_cmd() { + char UBL_LCD_GCODE[16]; + const int ind = ubl_height_amount < 0 ? 6 : 7; + strcpy_P(UBL_LCD_GCODE, PSTR("G29 P6-")); + sprintf_P(&UBL_LCD_GCODE[ind], PSTR(".%i"), abs(ubl_height_amount)); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Adjust Mesh Height submenu + */ + void _lcd_ubl_height_adjust_menu() { + START_MENU(); + MENU_BACK(MSG_UBL_EDIT_MESH_MENU); + MENU_ITEM_EDIT(int3, MSG_UBL_MESH_HEIGHT_AMOUNT, &ubl_height_amount, -9, 9); + MENU_ITEM(function, MSG_UBL_MESH_HEIGHT_ADJUST, _lcd_ubl_adjust_height_cmd); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } + + /** + * UBL Edit Mesh submenu + */ + void _lcd_ubl_edit_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + MENU_BACK(MSG_UBL_LEVEL_BED); + MENU_ITEM(gcode, MSG_UBL_FINE_TUNE_ALL, PSTR("G29 P4 R T")); + MENU_ITEM(gcode, MSG_UBL_FINE_TUNE_CLOSEST, PSTR("G29 P4 T")); + MENU_ITEM(submenu, MSG_UBL_MESH_HEIGHT_ADJUST, _lcd_ubl_height_adjust_menu); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } + + /** + * UBL Validate Custom Mesh Command + */ + void _lcd_ubl_validate_custom_mesh() { + char UBL_LCD_GCODE[24]; + const int temp = #if WATCH_THE_BED - MENU_ITEM_EDIT(int3, MSG_UBL_CUSTOM_BED_TEMP, &custom_bed_temp, BED_MINTEMP, (BED_MAXTEMP - 5)); - #endif - MENU_ITEM(function, MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_build_custom_mesh); - END_MENU(); - } - - /** - * UBL Adjust Mesh Height Command - */ - void _lcd_ubl_adjust_height_cmd() { - char UBL_LCD_GCODE[16]; - const int ind = ubl_height_amount < 0 ? 6 : 7; - strcpy_P(UBL_LCD_GCODE, PSTR("G29 P6-")); - sprintf_P(&UBL_LCD_GCODE[ind], PSTR(".%i"), abs(ubl_height_amount)); - enqueue_and_echo_command(UBL_LCD_GCODE); - } - - /** - * UBL Adjust Mesh Height submenu - */ - void _lcd_ubl_height_adjust_menu() { - START_MENU(); - MENU_BACK(MSG_UBL_EDIT_MESH_MENU); - MENU_ITEM_EDIT(int3, MSG_UBL_MESH_HEIGHT_AMOUNT, &ubl_height_amount, -9, 9); - MENU_ITEM(function, MSG_UBL_MESH_HEIGHT_ADJUST, _lcd_ubl_adjust_height_cmd); - MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); - END_MENU(); - } - - /** - * UBL Edit Mesh submenu - */ - void _lcd_ubl_edit_mesh() { - START_MENU(); - MENU_BACK(MSG_UBL_TOOLS); - MENU_BACK(MSG_UBL_LEVEL_BED); - MENU_ITEM(gcode, MSG_UBL_FINE_TUNE_ALL, PSTR("G29 P4 R T")); - MENU_ITEM(gcode, MSG_UBL_FINE_TUNE_CLOSEST, PSTR("G29 P4 T")); - MENU_ITEM(submenu, MSG_UBL_MESH_HEIGHT_ADJUST, _lcd_ubl_height_adjust_menu); - MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); - END_MENU(); - } - - /** - * UBL Validate Custom Mesh Command - */ - void _lcd_ubl_validate_custom_mesh() { - char UBL_LCD_GCODE[24]; - const int temp = - #if WATCH_THE_BED - custom_bed_temp - #else - 0 - #endif - ; - sprintf_P(UBL_LCD_GCODE, PSTR("G28\nG26 C B%i H%i P"), temp, custom_hotend_temp); - enqueue_and_echo_command(UBL_LCD_GCODE); - } - - /** - * UBL Validate Mesh submenu - */ - void _lcd_ubl_validate_mesh() { - START_MENU(); - MENU_BACK(MSG_UBL_TOOLS); - #if WATCH_THE_BED - MENU_ITEM(gcode, MSG_UBL_VALIDATE_PLA_MESH, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_1_TEMP_BED) " H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); - MENU_ITEM(gcode, MSG_UBL_VALIDATE_ABS_MESH, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_2_TEMP_BED) " H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); + custom_bed_temp #else - MENU_ITEM(gcode, MSG_UBL_VALIDATE_PLA_MESH, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); - MENU_ITEM(gcode, MSG_UBL_VALIDATE_ABS_MESH, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); + 0 #endif - MENU_ITEM(function, MSG_UBL_VALIDATE_CUSTOM_MESH, _lcd_ubl_validate_custom_mesh); - MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); - END_MENU(); - } + ; + sprintf_P(UBL_LCD_GCODE, PSTR("G28\nG26 C B%i H%i P"), temp, custom_hotend_temp); + enqueue_and_echo_command(UBL_LCD_GCODE); + } - /** - * UBL Grid Leveling Command - */ - void _lcd_ubl_grid_level_cmd() { - char UBL_LCD_GCODE[10]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points); - enqueue_and_echo_command(UBL_LCD_GCODE); - } + /** + * UBL Validate Mesh submenu + */ + void _lcd_ubl_validate_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + #if WATCH_THE_BED + MENU_ITEM(gcode, MSG_UBL_VALIDATE_PLA_MESH, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_1_TEMP_BED) " H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); + MENU_ITEM(gcode, MSG_UBL_VALIDATE_ABS_MESH, PSTR("G28\nG26 C B" STRINGIFY(PREHEAT_2_TEMP_BED) " H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); + #else + MENU_ITEM(gcode, MSG_UBL_VALIDATE_PLA_MESH, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_1_TEMP_HOTEND) " P")); + MENU_ITEM(gcode, MSG_UBL_VALIDATE_ABS_MESH, PSTR("G28\nG26 C B0 H" STRINGIFY(PREHEAT_2_TEMP_HOTEND) " P")); + #endif + MENU_ITEM(function, MSG_UBL_VALIDATE_CUSTOM_MESH, _lcd_ubl_validate_custom_mesh); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } - /** - * UBL Grid Leveling submenu - */ - void _lcd_ubl_grid_level() { - START_MENU(); - MENU_BACK(MSG_UBL_TOOLS); - MENU_ITEM_EDIT(int3, MSG_UBL_SIDE_POINTS, &side_points, 2, 6); - MENU_ITEM(function, MSG_UBL_MESH_LEVEL, _lcd_ubl_grid_level_cmd); - END_MENU(); - } + /** + * UBL Grid Leveling Command + */ + void _lcd_ubl_grid_level_cmd() { + char UBL_LCD_GCODE[10]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points); + enqueue_and_echo_command(UBL_LCD_GCODE); + } - /** - * UBL Mesh Leveling submenu - */ - void _lcd_ubl_mesh_leveling() { - START_MENU(); - MENU_BACK(MSG_UBL_TOOLS); - MENU_ITEM(gcode, MSG_UBL_3POINT_MESH_LEVELING, PSTR("G29 J0")); - MENU_ITEM(submenu, MSG_UBL_GRID_MESH_LEVELING, _lcd_ubl_grid_level); - MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); - END_MENU(); - } + /** + * UBL Grid Leveling submenu + */ + void _lcd_ubl_grid_level() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + MENU_ITEM_EDIT(int3, MSG_UBL_SIDE_POINTS, &side_points, 2, 6); + MENU_ITEM(function, MSG_UBL_MESH_LEVEL, _lcd_ubl_grid_level_cmd); + END_MENU(); + } - /** - * UBL Fill-in Amount Mesh Command - */ - void _lcd_ubl_fillin_amount_cmd() { - char UBL_LCD_GCODE[16]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount); - enqueue_and_echo_command(UBL_LCD_GCODE); - } + /** + * UBL Mesh Leveling submenu + */ + void _lcd_ubl_mesh_leveling() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + MENU_ITEM(gcode, MSG_UBL_3POINT_MESH_LEVELING, PSTR("G29 J0")); + MENU_ITEM(submenu, MSG_UBL_GRID_MESH_LEVELING, _lcd_ubl_grid_level); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } - /** - * UBL Smart Fill-in Command - */ - void _lcd_ubl_smart_fillin_cmd() { - char UBL_LCD_GCODE[12]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 T%i"), map_type); - enqueue_and_echo_command(UBL_LCD_GCODE); - } + /** + * UBL Fill-in Amount Mesh Command + */ + void _lcd_ubl_fillin_amount_cmd() { + char UBL_LCD_GCODE[16]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount); + enqueue_and_echo_command(UBL_LCD_GCODE); + } - /** - * UBL Fill-in Mesh submenu - */ - void _lcd_ubl_fillin_menu() { - START_MENU(); - MENU_BACK(MSG_UBL_BUILD_MESH_MENU); - MENU_ITEM_EDIT(int3, MSG_UBL_FILLIN_AMOUNT, &ubl_fillin_amount, 0, 9); - MENU_ITEM(function, MSG_UBL_FILLIN_MESH, _lcd_ubl_fillin_amount_cmd); - MENU_ITEM(function, MSG_UBL_SMART_FILLIN, _lcd_ubl_smart_fillin_cmd); - MENU_ITEM(gcode, MSG_UBL_MANUAL_FILLIN, PSTR("G29 P2 B T0")); - MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); - END_MENU(); - } + /** + * UBL Smart Fill-in Command + */ + void _lcd_ubl_smart_fillin_cmd() { + char UBL_LCD_GCODE[12]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 T%i"), map_type); + enqueue_and_echo_command(UBL_LCD_GCODE); + } - void _lcd_ubl_invalidate() { - ubl.invalidate(); - SERIAL_PROTOCOLLNPGM("Mesh invalidated."); - } + /** + * UBL Fill-in Mesh submenu + */ + void _lcd_ubl_fillin_menu() { + START_MENU(); + MENU_BACK(MSG_UBL_BUILD_MESH_MENU); + MENU_ITEM_EDIT(int3, MSG_UBL_FILLIN_AMOUNT, &ubl_fillin_amount, 0, 9); + MENU_ITEM(function, MSG_UBL_FILLIN_MESH, _lcd_ubl_fillin_amount_cmd); + MENU_ITEM(function, MSG_UBL_SMART_FILLIN, _lcd_ubl_smart_fillin_cmd); + MENU_ITEM(gcode, MSG_UBL_MANUAL_FILLIN, PSTR("G29 P2 B T0")); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } - /** - * UBL Build Mesh submenu - */ - void _lcd_ubl_build_mesh() { - START_MENU(); - MENU_BACK(MSG_UBL_TOOLS); - #if WATCH_THE_BED - MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, PSTR( - "G28\n" - "M190 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\n" - "M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0\n" - "M140 S0" - )); - MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, PSTR( - "G28\n" - "M190 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\n" - "M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0\n" - "M140 S0" - )); - #else - MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, PSTR( - "G28\n" - "M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0" - )); - MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, PSTR( - "G28\n" - "M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n" - "G29 P1\n" - "M104 S0" - )); - #endif - MENU_ITEM(submenu, MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_custom_mesh); - MENU_ITEM(gcode, MSG_UBL_BUILD_COLD_MESH, PSTR("G28\nG29 P1")); - MENU_ITEM(submenu, MSG_UBL_FILLIN_MESH, _lcd_ubl_fillin_menu); - MENU_ITEM(gcode, MSG_UBL_CONTINUE_MESH, PSTR("G29 P1 C")); - MENU_ITEM(function, MSG_UBL_INVALIDATE_ALL, _lcd_ubl_invalidate); - MENU_ITEM(gcode, MSG_UBL_INVALIDATE_CLOSEST, PSTR("G29 I")); - MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); - END_MENU(); - } + void _lcd_ubl_invalidate() { + ubl.invalidate(); + SERIAL_PROTOCOLLNPGM("Mesh invalidated."); + } - /** - * UBL Load Mesh Command - */ - void _lcd_ubl_load_mesh_cmd() { - char UBL_LCD_GCODE[8]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 L%i"), ubl_storage_slot); - enqueue_and_echo_command(UBL_LCD_GCODE); - } + /** + * UBL Build Mesh submenu + */ + void _lcd_ubl_build_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + #if WATCH_THE_BED + MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, PSTR( + "G28\n" + "M190 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\n" + "M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n" + "G29 P1\n" + "M104 S0\n" + "M140 S0" + )); + MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, PSTR( + "G28\n" + "M190 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\n" + "M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n" + "G29 P1\n" + "M104 S0\n" + "M140 S0" + )); + #else + MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, PSTR( + "G28\n" + "M109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\n" + "G29 P1\n" + "M104 S0" + )); + MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, PSTR( + "G28\n" + "M109 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) "\n" + "G29 P1\n" + "M104 S0" + )); + #endif + MENU_ITEM(submenu, MSG_UBL_BUILD_CUSTOM_MESH, _lcd_ubl_custom_mesh); + MENU_ITEM(gcode, MSG_UBL_BUILD_COLD_MESH, PSTR("G28\nG29 P1")); + MENU_ITEM(submenu, MSG_UBL_FILLIN_MESH, _lcd_ubl_fillin_menu); + MENU_ITEM(gcode, MSG_UBL_CONTINUE_MESH, PSTR("G29 P1 C")); + MENU_ITEM(function, MSG_UBL_INVALIDATE_ALL, _lcd_ubl_invalidate); + MENU_ITEM(gcode, MSG_UBL_INVALIDATE_CLOSEST, PSTR("G29 I")); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } - /** - * UBL Save Mesh Command - */ - void _lcd_ubl_save_mesh_cmd() { - char UBL_LCD_GCODE[8]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 S%i"), ubl_storage_slot); - enqueue_and_echo_command(UBL_LCD_GCODE); - } + /** + * UBL Load Mesh Command + */ + void _lcd_ubl_load_mesh_cmd() { + char UBL_LCD_GCODE[8]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 L%i"), ubl_storage_slot); + enqueue_and_echo_command(UBL_LCD_GCODE); + } - /** - * UBL Mesh Storage submenu - */ - void _lcd_ubl_storage_mesh() { - START_MENU(); - MENU_BACK(MSG_UBL_LEVEL_BED); - MENU_ITEM_EDIT(int3, MSG_UBL_STORAGE_SLOT, &ubl_storage_slot, 0, 9); - MENU_ITEM(function, MSG_UBL_LOAD_MESH, _lcd_ubl_load_mesh_cmd); - MENU_ITEM(function, MSG_UBL_SAVE_MESH, _lcd_ubl_save_mesh_cmd); - END_MENU(); - } + /** + * UBL Save Mesh Command + */ + void _lcd_ubl_save_mesh_cmd() { + char UBL_LCD_GCODE[8]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 S%i"), ubl_storage_slot); + enqueue_and_echo_command(UBL_LCD_GCODE); + } - /** - * UBL Output map Command - */ - void _lcd_ubl_output_map_cmd() { - char UBL_LCD_GCODE[10]; - sprintf_P(UBL_LCD_GCODE, PSTR("G29 T%i"), map_type); - enqueue_and_echo_command(UBL_LCD_GCODE); - } + /** + * UBL Mesh Storage submenu + */ + void _lcd_ubl_storage_mesh() { + START_MENU(); + MENU_BACK(MSG_UBL_LEVEL_BED); + MENU_ITEM_EDIT(int3, MSG_UBL_STORAGE_SLOT, &ubl_storage_slot, 0, 9); + MENU_ITEM(function, MSG_UBL_LOAD_MESH, _lcd_ubl_load_mesh_cmd); + MENU_ITEM(function, MSG_UBL_SAVE_MESH, _lcd_ubl_save_mesh_cmd); + END_MENU(); + } - /** - * UBL Output map submenu - */ - void _lcd_ubl_output_map() { - START_MENU(); - MENU_BACK(MSG_UBL_LEVEL_BED); - MENU_ITEM_EDIT(int3, MSG_UBL_MAP_TYPE, &map_type, 0, 1); - if (map_type == 0) MENU_ITEM(function, MSG_UBL_OUTPUT_MAP_HOST, _lcd_ubl_output_map_cmd); - if (map_type == 1) MENU_ITEM(function, MSG_UBL_OUTPUT_MAP_CSV, _lcd_ubl_output_map_cmd); - END_MENU(); - } + /** + * UBL Output map Command + */ + void _lcd_ubl_output_map_cmd() { + char UBL_LCD_GCODE[10]; + sprintf_P(UBL_LCD_GCODE, PSTR("G29 T%i"), map_type); + enqueue_and_echo_command(UBL_LCD_GCODE); + } - /** - * UBL Tools submenu - */ - void _lcd_ubl_tools_menu() { - START_MENU(); - MENU_BACK(MSG_UBL_LEVEL_BED); - MENU_ITEM(submenu, MSG_UBL_BUILD_MESH_MENU, _lcd_ubl_build_mesh); - MENU_ITEM(submenu, MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); - MENU_ITEM(submenu, MSG_UBL_EDIT_MESH_MENU, _lcd_ubl_edit_mesh); - MENU_ITEM(submenu, MSG_UBL_MESH_LEVELING, _lcd_ubl_mesh_leveling); - END_MENU(); - } + /** + * UBL Output map submenu + */ + void _lcd_ubl_output_map() { + START_MENU(); + MENU_BACK(MSG_UBL_LEVEL_BED); + MENU_ITEM_EDIT(int3, MSG_UBL_MAP_TYPE, &map_type, 0, 1); + if (map_type == 0) MENU_ITEM(function, MSG_UBL_OUTPUT_MAP_HOST, _lcd_ubl_output_map_cmd); + if (map_type == 1) MENU_ITEM(function, MSG_UBL_OUTPUT_MAP_CSV, _lcd_ubl_output_map_cmd); + END_MENU(); + } - /** - * UBL System submenu - * - * Prepare - * - Unified Bed Leveling - * - Activate UBL - * - Deactivate UBL - * - Mesh Storage - * Memory Slot: - * Load Bed Mesh - * Save Bed Mesh - * - Output Map - * Map Type: - * Output Bed Mesh Host / Output Bed Mesh CSV - * - UBL Tools - * - Build Mesh - * Build PLA Mesh - * Build ABS Mesh - * - Build Custom Mesh - * Hotend Temp: - * Bed Temp: - * Build Custom Mesh - * Info Screen - * - Build Cold Mesh - * - Fill-in Mesh - * Fill-in Mesh - * Smart Fill-in - * Manual Fill-in - * Info Screen - * Continue Bed Mesh - * Invalidate All - * Invalidate Closest - * - Validate Mesh - * PLA Mesh Validation - * ABS Mesh Validation - * - Custom Mesh Validation - * Hotend Temp: - * Bed Temp: - * Validate Mesh - * Info Screen - * - Edit Mesh - * Fine Tune All - * Fine Tune Closest - * - Adjust Mesh Height - * Height Amount: - * Adjust Mesh Height - * Info Screen - * - Mesh Leveling - * 3-Point Mesh Leveling - * - Grid Mesh Leveling - * Side points: - * Level Mesh - * Info Screen - * - Output UBL Info - */ + /** + * UBL Tools submenu + */ + void _lcd_ubl_tools_menu() { + START_MENU(); + MENU_BACK(MSG_UBL_LEVEL_BED); + MENU_ITEM(submenu, MSG_UBL_BUILD_MESH_MENU, _lcd_ubl_build_mesh); + MENU_ITEM(submenu, MSG_UBL_VALIDATE_MESH_MENU, _lcd_ubl_validate_mesh); + MENU_ITEM(submenu, MSG_UBL_EDIT_MESH_MENU, _lcd_ubl_edit_mesh); + MENU_ITEM(submenu, MSG_UBL_MESH_LEVELING, _lcd_ubl_mesh_leveling); + END_MENU(); + } - void _lcd_ubl_level_bed() { - START_MENU(); - MENU_BACK(MSG_PREPARE); - MENU_ITEM(gcode, MSG_UBL_ACTIVATE_MESH, PSTR("G29 A")); - MENU_ITEM(gcode, MSG_UBL_DEACTIVATE_MESH, PSTR("G29 D")); - MENU_ITEM(submenu, MSG_UBL_STORAGE_MESH_MENU, _lcd_ubl_storage_mesh); - MENU_ITEM(submenu, MSG_UBL_OUTPUT_MAP, _lcd_ubl_output_map); - MENU_ITEM(submenu, MSG_UBL_TOOLS, _lcd_ubl_tools_menu); - MENU_ITEM(gcode, MSG_UBL_INFO_UBL, PSTR("G29 W")); - END_MENU(); - } - #endif + /** + * UBL System submenu + * + * Prepare + * - Unified Bed Leveling + * - Activate UBL + * - Deactivate UBL + * - Mesh Storage + * Memory Slot: + * Load Bed Mesh + * Save Bed Mesh + * - Output Map + * Map Type: + * Output Bed Mesh Host / Output Bed Mesh CSV + * - UBL Tools + * - Build Mesh + * Build PLA Mesh + * Build ABS Mesh + * - Build Custom Mesh + * Hotend Temp: + * Bed Temp: + * Build Custom Mesh + * Info Screen + * - Build Cold Mesh + * - Fill-in Mesh + * Fill-in Mesh + * Smart Fill-in + * Manual Fill-in + * Info Screen + * Continue Bed Mesh + * Invalidate All + * Invalidate Closest + * - Validate Mesh + * PLA Mesh Validation + * ABS Mesh Validation + * - Custom Mesh Validation + * Hotend Temp: + * Bed Temp: + * Validate Mesh + * Info Screen + * - Edit Mesh + * Fine Tune All + * Fine Tune Closest + * - Adjust Mesh Height + * Height Amount: + * Adjust Mesh Height + * Info Screen + * - Mesh Leveling + * 3-Point Mesh Leveling + * - Grid Mesh Leveling + * Side points: + * Level Mesh + * Info Screen + * - Output UBL Info + */ - #endif // LCD_BED_LEVELING || HAS_ABL + void _lcd_ubl_level_bed() { + START_MENU(); + MENU_BACK(MSG_PREPARE); + MENU_ITEM(gcode, MSG_UBL_ACTIVATE_MESH, PSTR("G29 A")); + MENU_ITEM(gcode, MSG_UBL_DEACTIVATE_MESH, PSTR("G29 D")); + MENU_ITEM(submenu, MSG_UBL_STORAGE_MESH_MENU, _lcd_ubl_storage_mesh); + MENU_ITEM(submenu, MSG_UBL_OUTPUT_MAP, _lcd_ubl_output_map); + MENU_ITEM(submenu, MSG_UBL_TOOLS, _lcd_ubl_tools_menu); + MENU_ITEM(gcode, MSG_UBL_INFO_UBL, PSTR("G29 W")); + END_MENU(); + } + + #endif // AUTO_BED_LEVELING_UBL /** * @@ -2061,18 +2018,14 @@ void kill_screen(const char* lcd_msg) { // // Level Bed // - #if ENABLED(LCD_BED_LEVELING) || HAS_ABL - + #if ENABLED(AUTO_BED_LEVELING_UBL) + MENU_ITEM(submenu, MSG_UBL_LEVEL_BED, _lcd_ubl_level_bed); + #elif ENABLED(LCD_BED_LEVELING) #if ENABLED(PROBE_MANUALLY) if (!g29_in_progress) #endif - #if ENABLED(AUTO_BED_LEVELING_UBL) - MENU_ITEM(submenu, MSG_UBL_LEVEL_BED, _lcd_ubl_level_bed); - #else - MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed); - #endif - - #endif // LCD_BED_LEVELING || HAS_ABL + MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed); + #endif #if HAS_M206_COMMAND // @@ -2158,7 +2111,7 @@ void kill_screen(const char* lcd_msg) { void _lcd_calibrate_homing() { if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, PSTR(MSG_LEVEL_BED_HOMING)); - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) lcd_goto_previous_menu(); } @@ -2292,7 +2245,7 @@ void kill_screen(const char* lcd_msg) { manual_move_to_current(axis); encoderPosition = 0; - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; } if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr41sign(current_position[axis])); } @@ -2314,7 +2267,7 @@ void kill_screen(const char* lcd_msg) { , eindex #endif ); - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; } if (lcdDrawUpdate) { PGM_P pos_label; @@ -3243,7 +3196,7 @@ void kill_screen(const char* lcd_msg) { encoderPosition += ENCODER_STEPS_PER_MENU_ITEM; \ ++encoderLine; \ } \ - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; \ + lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; \ } \ ++_thisItemNr; \ } while(0) @@ -3775,9 +3728,9 @@ bool lcd_blink() { * - if (lcdDrawUpdate) { redraw } * - Before exiting the handler set lcdDrawUpdate to: * - LCDVIEW_CLEAR_CALL_REDRAW to clear screen and set LCDVIEW_CALL_REDRAW_NEXT. - * - LCDVIEW_REDRAW_NOW or LCDVIEW_NONE to keep drawing, but only in this loop. - * - LCDVIEW_CALL_REDRAW_NEXT to keep drawing and draw on the next loop also. - * - LCDVIEW_CALL_NO_REDRAW to keep drawing (or start drawing) with no redraw on the next loop. + * - LCDVIEW_REDRAW_NOW to draw now (including remaining stripes). + * - LCDVIEW_CALL_REDRAW_NEXT to draw now and get LCDVIEW_REDRAW_NOW on the next loop. + * - LCDVIEW_CALL_NO_REDRAW to draw now and get LCDVIEW_NONE on the next loop. * - NOTE: For graphical displays menu handlers may be called 2 or more times per loop, * so don't change lcdDrawUpdate without considering this. * @@ -3897,7 +3850,7 @@ void lcd_update() { encoderDiff = 0; } return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; } #endif // ULTIPANEL