diff --git a/Marlin/language_en.h b/Marlin/language_en.h index 78d674c715..7dd2edf0af 100644 --- a/Marlin/language_en.h +++ b/Marlin/language_en.h @@ -153,6 +153,145 @@ #ifndef MSG_LEVEL_BED #define MSG_LEVEL_BED _UxGT("Level bed") #endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #ifndef MSG_UBL_UNHOMED + #define MSG_UBL_UNHOMED _UxGT("Home XYZ first") + #endif + #ifndef MSG_UBL_TOOLS + #define MSG_UBL_TOOLS _UxGT("UBL Tools") + #endif + #ifndef MSG_UBL_LEVEL_BED + #define MSG_UBL_LEVEL_BED _UxGT("Unified Bed Leveling") + #endif + #ifndef MSG_UBL_ACTIVATE_MESH + #define MSG_UBL_ACTIVATE_MESH _UxGT("Activate UBL") + #endif + #ifndef MSG_UBL_DEACTIVATE_MESH + #define MSG_UBL_DEACTIVATE_MESH _UxGT("Deactivate UBL") + #endif + #ifndef MSG_UBL_CUSTOM_BED_TEMP + #define MSG_UBL_CUSTOM_BED_TEMP _UxGT("Bed Temp") + #endif + #ifndef MSG_UBL_SET_BED_TEMP + #define MSG_UBL_SET_BED_TEMP _UxGT("Bed Temp") + #endif + #ifndef MSG_UBL_CUSTOM_HOTEND_TEMP + #define MSG_UBL_CUSTOM_HOTEND_TEMP _UxGT("Hotend Temp") + #endif + #ifndef MSG_UBL_SET_HOTEND_TEMP + #define MSG_UBL_SET_HOTEND_TEMP _UxGT("Hotend Temp") + #endif + #ifndef MSG_UBL_EDIT_CUSTOM_MESH + #define MSG_UBL_EDIT_CUSTOM_MESH _UxGT("Edit Custom Mesh") + #endif + #ifndef MSG_UBL_BUILD_CUSTOM_MESH + #define MSG_UBL_BUILD_CUSTOM_MESH _UxGT("Build Custom Mesh") + #endif + #ifndef MSG_UBL_BUILD_MESH_MENU + #define MSG_UBL_BUILD_MESH_MENU _UxGT("Build Mesh") + #endif + #ifndef MSG_UBL_BUILD_PLA_MESH + #define MSG_UBL_BUILD_PLA_MESH _UxGT("Build PLA Mesh") + #endif + #ifndef MSG_UBL_BUILD_ABS_MESH + #define MSG_UBL_BUILD_ABS_MESH _UxGT("Build ABS Mesh") + #endif + #ifndef MSG_UBL_BUILD_COLD_MESH + #define MSG_UBL_BUILD_COLD_MESH _UxGT("Build Cold Mesh") + #endif + #ifndef MSG_UBL_MESH_HEIGHT_ADJUST + #define MSG_UBL_MESH_HEIGHT_ADJUST _UxGT("Adjust Mesh Height") + #endif + #ifndef MSG_UBL_MESH_HEIGHT_AMOUNT + #define MSG_UBL_MESH_HEIGHT_AMOUNT _UxGT("Height Amount") + #endif + #ifndef MSG_UBL_VALIDATE_MESH_MENU + #define MSG_UBL_VALIDATE_MESH_MENU _UxGT("Validate Mesh") + #endif + #ifndef MSG_UBL_VALIDATE_PLA_MESH + #define MSG_UBL_VALIDATE_PLA_MESH _UxGT("Validate PLA Mesh") + #endif + #ifndef MSG_UBL_VALIDATE_ABS_MESH + #define MSG_UBL_VALIDATE_ABS_MESH _UxGT("Validate ABS Mesh") + #endif + #ifndef MSG_UBL_VALIDATE_CUSTOM_MESH + #define MSG_UBL_VALIDATE_CUSTOM_MESH _UxGT("Validate Custom Mesh") + #endif + #ifndef MSG_UBL_CONTINUE_MESH + #define MSG_UBL_CONTINUE_MESH _UxGT("Continue Bed Mesh") + #endif + #ifndef MSG_UBL_MESH_LEVELING + #define MSG_UBL_MESH_LEVELING _UxGT("Mesh Leveling") + #endif + #ifndef MSG_UBL_3POINT_MESH_LEVELING + #define MSG_UBL_3POINT_MESH_LEVELING _UxGT("3-Point Leveling") + #endif + #ifndef MSG_UBL_GRID_MESH_LEVELING + #define MSG_UBL_GRID_MESH_LEVELING _UxGT("Grid Mesh Leveling") + #endif + #ifndef MSG_UBL_MESH_LEVEL + #define MSG_UBL_MESH_LEVEL _UxGT("Level Mesh") + #endif + #ifndef MSG_UBL_SIDE_POINTS + #define MSG_UBL_SIDE_POINTS _UxGT("Side Points") + #endif + #ifndef MSG_UBL_MAP_TYPE + #define MSG_UBL_MAP_TYPE _UxGT("Map Type") + #endif + #ifndef MSG_UBL_OUTPUT_MAP + #define MSG_UBL_OUTPUT_MAP _UxGT("Output Mesh Map") + #endif + #ifndef MSG_UBL_OUTPUT_MAP_HOST + #define MSG_UBL_OUTPUT_MAP_HOST _UxGT("Output for Host") + #endif + #ifndef MSG_UBL_OUTPUT_MAP_CSV + #define MSG_UBL_OUTPUT_MAP_CSV _UxGT("Output for CSV") + #endif + #ifndef MSG_UBL_INFO_UBL + #define MSG_UBL_INFO_UBL _UxGT("Output UBL Info") + #endif + #ifndef MSG_UBL_EDIT_MESH_MENU + #define MSG_UBL_EDIT_MESH_MENU _UxGT("Edit Mesh") + #endif + #ifndef MSG_UBL_FILLIN_AMOUNT + #define MSG_UBL_FILLIN_AMOUNT _UxGT("Fill-in Amount") + #endif + #ifndef MSG_UBL_MANUAL_FILLIN + #define MSG_UBL_MANUAL_FILLIN _UxGT("Manual Fill-in") + #endif + #ifndef MSG_UBL_SMART_FILLIN + #define MSG_UBL_SMART_FILLIN _UxGT("Smart Fill-in") + #endif + #ifndef MSG_UBL_FILLIN_MESH + #define MSG_UBL_FILLIN_MESH _UxGT("Fill-in Mesh") + #endif + #ifndef MSG_UBL_INVALIDATE_ALL + #define MSG_UBL_INVALIDATE_ALL _UxGT("Invalidate All") + #endif + #ifndef MSG_UBL_INVALIDATE_CLOSEST + #define MSG_UBL_INVALIDATE_CLOSEST _UxGT("Invalidate Closest") + #endif + #ifndef MSG_UBL_FINE_TUNE_ALL + #define MSG_UBL_FINE_TUNE_ALL _UxGT("Fine Tune All") + #endif + #ifndef MSG_UBL_FINE_TUNE_CLOSEST + #define MSG_UBL_FINE_TUNE_CLOSEST _UxGT("Fine Tune Closest") + #endif + #ifndef MSG_UBL_STORAGE_MESH_MENU + #define MSG_UBL_STORAGE_MESH_MENU _UxGT("Mesh Storage") + #endif + #ifndef MSG_UBL_STORAGE_SLOT + #define MSG_UBL_STORAGE_SLOT _UxGT("Memory Slot") + #endif + #ifndef MSG_UBL_LOAD_MESH + #define MSG_UBL_LOAD_MESH _UxGT("Load Bed Mesh") + #endif + #ifndef MSG_UBL_SAVE_MESH + #define MSG_UBL_SAVE_MESH _UxGT("Save Bed Mesh") + #endif +#endif // AUTO_BED_LEVELING_UBL + #ifndef MSG_MOVING #define MSG_MOVING _UxGT("Moving...") #endif @@ -324,6 +463,9 @@ #ifndef MSG_RESTORE_FAILSAFE #define MSG_RESTORE_FAILSAFE _UxGT("Restore failsafe") #endif +#ifndef MSG_INIT_EEPROM + #define MSG_INIT_EEPROM _UxGT("Initalize Memory") +#endif #ifndef MSG_REFRESH #define MSG_REFRESH _UxGT("Refresh") #endif @@ -590,7 +732,6 @@ #ifndef MSG_INFO_PSU #define MSG_INFO_PSU _UxGT("Power Supply") #endif - #ifndef MSG_DRIVE_STRENGTH #define MSG_DRIVE_STRENGTH _UxGT("Drive Strength") #endif diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp index 7a174f702d..6e794a3b05 100644 --- a/Marlin/ubl_G29.cpp +++ b/Marlin/ubl_G29.cpp @@ -55,12 +55,16 @@ extern float probe_pt(float x, float y, bool, int); extern bool set_probe_deployed(bool); void smart_fill_mesh(); + float measure_business_card_thickness(float &in_height); + void manually_probe_remaining_mesh(const float &lx, const float &ly, float &z_clearance, const float &card_thickness, const bool do_ubl_mesh_map); bool ProbeStay = true; - #define SIZE_OF_LITTLE_RAISE 0 + #define SIZE_OF_LITTLE_RAISE 1 #define BIG_RAISE_NOT_NEEDED 0 - extern void lcd_quick_feedback(); + extern void lcd_status_screen(); + typedef void (*screenFunc_t)(); + extern void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder = 0); /** * G29: Unified Bed Leveling by Roxy @@ -444,7 +448,7 @@ y_pos = current_position[Y_AXIS]; } - const float height = code_seen('H') && code_has_value() ? code_value_float() : Z_CLEARANCE_BETWEEN_PROBES; + float height = code_seen('H') && code_has_value() ? code_value_float() : Z_CLEARANCE_BETWEEN_PROBES; if (code_seen('B')) { card_thickness = code_has_value() ? code_value_float() : measure_business_card_thickness(height); @@ -876,7 +880,7 @@ SERIAL_PROTOCOLLNPGM(" and take a measurement."); } - float measure_business_card_thickness(const float &in_height) { + float measure_business_card_thickness(float &in_height) { ubl.has_control_of_lcd_panel = true; ubl.save_ubl_active_state_and_disable(); // Disable bed level correction for probing @@ -886,6 +890,8 @@ stepper.synchronize(); SERIAL_PROTOCOLPGM("Place shim under nozzle."); + LCD_MESSAGEPGM("Place shim & measure"); + lcd_goto_screen(lcd_status_screen); say_and_take_a_measurement(); const float z1 = use_encoder_wheel_to_measure_point(); @@ -893,29 +899,33 @@ stepper.synchronize(); SERIAL_PROTOCOLPGM("Remove shim."); + LCD_MESSAGEPGM("Remove & measure"); + say_and_take_a_measurement(); const float z2 = use_encoder_wheel_to_measure_point(); - do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE); + do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES); if (g29_verbose_level > 1) { SERIAL_PROTOCOLPGM("Business Card is: "); SERIAL_PROTOCOL_F(abs(z1 - z2), 6); SERIAL_PROTOCOLLNPGM("mm thick."); } + in_height = current_position[Z_AXIS]; // do manual probing at lower height ubl.has_control_of_lcd_panel = false; ubl.restore_ubl_active_state_and_leave(); return abs(z1 - z2); } - void manually_probe_remaining_mesh(const float &lx, const float &ly, const float &z_clearance, const float &card_thickness, const bool do_ubl_mesh_map) { + void manually_probe_remaining_mesh(const float &lx, const float &ly, float &z_clearance, const float &card_thickness, const bool do_ubl_mesh_map) { ubl.has_control_of_lcd_panel = true; ubl.save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe do_blocking_move_to_z(z_clearance); do_blocking_move_to_xy(lx, ly); + lcd_goto_screen(lcd_status_screen); float last_x = -9999.99, last_y = -9999.99; mesh_index_pair location; do { @@ -943,6 +953,7 @@ do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE); else do_blocking_move_to_z(z_clearance); + LCD_MESSAGEPGM("Moving to next"); do_blocking_move_to_xy(xProbe, yProbe); @@ -953,6 +964,8 @@ ubl.has_control_of_lcd_panel = true; if (do_ubl_mesh_map) ubl.display_map(map_type); // show user where we're probing + if (code_seen('B')) {LCD_MESSAGEPGM("Place shim & measure");} + else {LCD_MESSAGEPGM("Measure");} while (ubl_lcd_clicked()) delay(50); // wait for user to release encoder wheel delay(50); // debounce @@ -1024,6 +1037,7 @@ repeat_flag = code_seen('R'); if (repeat_flag) { repetition_cnt = code_has_value() ? code_value_int() : (GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y); + repetition_cnt = min(repetition_cnt, (GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y)); if (repetition_cnt < 1) { SERIAL_PROTOCOLLNPGM("?(R)epetition count invalid (1+).\n"); return UBL_ERR; @@ -1056,7 +1070,6 @@ SERIAL_PROTOCOLLNPGM("Both X & Y locations must be specified.\n"); err_flag = true; } - if (!WITHIN(RAW_X_POSITION(x_pos), X_MIN_POS, X_MAX_POS)) { SERIAL_PROTOCOLLNPGM("Invalid X location specified.\n"); err_flag = true; @@ -1422,8 +1435,7 @@ do_blocking_move_to_xy(lx, ly); do { location = find_closest_mesh_point_of_type(SET_IN_BITMAP, lx, ly, USE_NOZZLE_AS_REFERENCE, not_done, false); - // It doesn't matter if the probe can't reach this - // location. This is a manual edit of the Mesh Point. + if (location.x_index < 0 && location.y_index < 0) continue; // abort if we can't find any more points. bit_clear(not_done, location.x_index, location.y_index); // Mark this location as 'adjusted' so we will find a @@ -1612,7 +1624,7 @@ SERIAL_ECHOPGM("Could not complete LSF!"); return; } - + if (g29_verbose_level > 3) { SERIAL_ECHOPGM("LSF Results A="); SERIAL_PROTOCOL_F(lsf_results.A, 7); diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 60771a5f51..29eb269bdc 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -1674,6 +1674,348 @@ void kill_screen(const char* lcd_msg) { END_MENU(); } + #if ENABLED(AUTO_BED_LEVELING_UBL) + + void _lcd_ubl_level_bed(); + + int UBL_STORAGE_SLOT = 0; + int CUSTOM_BED_TEMP = 50; + int CUSTOM_HOTEND_TEMP = 190; + int SIDE_POINTS = 3; + int UBL_FILLIN_AMOUNT = 5; + int UBL_HEIGHT_AMOUNT; + int map_type; + + char UBL_LCD_GCODE [30]; + + /** + * UBL Build Custom Mesh Command + */ + void _lcd_ubl_build_custom_mesh() { + enqueue_and_echo_command("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); + enqueue_and_echo_command(UBL_LCD_GCODE); + enqueue_and_echo_command("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)); + #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() { + if (UBL_HEIGHT_AMOUNT < 0) { + // Convert to positive for the `sprintf_P` string. + UBL_HEIGHT_AMOUNT = (UBL_HEIGHT_AMOUNT - (UBL_HEIGHT_AMOUNT * 2)); // Convert to positive + sprintf_P(UBL_LCD_GCODE, PSTR("G29 N Z-.%i"), UBL_HEIGHT_AMOUNT); + // Convert back to negative to preserve the user setting. + UBL_HEIGHT_AMOUNT = (UBL_HEIGHT_AMOUNT - (UBL_HEIGHT_AMOUNT * 2)); // Convert back to negative + } + else { + sprintf_P(UBL_LCD_GCODE, PSTR("G29 N Z.%i"), 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 O")); + MENU_ITEM(gcode, MSG_UBL_FINE_TUNE_CLOSEST, PSTR("G29 P4 O")); + 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() { + enqueue_and_echo_command("G28"); + #if (WATCH_THE_BED) + sprintf_P(UBL_LCD_GCODE, PSTR("G26 C B%i H%i P"), CUSTOM_BED_TEMP, CUSTOM_HOTEND_TEMP); + #else + sprintf_P(UBL_LCD_GCODE, PSTR("G26 C B0 H%i P"), CUSTOM_HOTEND_TEMP); + #endif + 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 Command + */ + void _lcd_ubl_grid_level_cmd() { + sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), SIDE_POINTS); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * 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 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 T")); + MENU_ITEM(submenu, MSG_UBL_GRID_MESH_LEVELING, _lcd_ubl_grid_level); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } + + /** + * UBL Fill-in Amount Mesh Command + */ + void _lcd_ubl_fillin_amount_cmd() { + sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i N"), UBL_FILLIN_AMOUNT); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Smart Fill-in Command + */ + void _lcd_ubl_smart_fillin_cmd() { + sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 N O%i"), map_type); + 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 O")); + MENU_ITEM(submenu, MSG_WATCH, lcd_status_screen); + END_MENU(); + } + + void _lcd_ubl_invalidate() { + ubl.invalidate(); + SERIAL_PROTOCOLLNPGM("Mesh invalidated."); + } + + /** + * UBL Build Mesh submenu + */ + void _lcd_ubl_build_mesh() { + int GRID_NUM_POINTS = GRID_MAX_POINTS_X * GRID_MAX_POINTS_Y ; + START_MENU(); + MENU_BACK(MSG_UBL_TOOLS); + #if (WATCH_THE_BED) + MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, PSTR("G28\nM190 S" STRINGIFY(PREHEAT_1_TEMP_BED) + "\nM109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\nG29 P1\nM104 S0\nM140 S0")); + MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, PSTR("G28\nM190 S" STRINGIFY(PREHEAT_1_TEMP_BED) + "\nM109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) "\nG29 P1\nM104 S0\nM140 S0")); + #else + MENU_ITEM(gcode, MSG_UBL_BUILD_PLA_MESH, PSTR("G28\nM109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + "\nG29 P1\nM104 S0")); + MENU_ITEM(gcode, MSG_UBL_BUILD_ABS_MESH, PSTR("G28\nM109 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) + "\nG29 P1\nM104 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 Load Mesh Command + */ + void _lcd_ubl_load_mesh_cmd() { + sprintf_P(UBL_LCD_GCODE, PSTR("G29 N L%i"), UBL_STORAGE_SLOT); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * UBL Save Mesh Command + */ + void _lcd_ubl_save_mesh_cmd() { + sprintf_P(UBL_LCD_GCODE, PSTR("G29 N S%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 Output map Command + */ + void _lcd_ubl_output_map_cmd() { + sprintf_P(UBL_LCD_GCODE, PSTR("G29 N O%i"), map_type); + enqueue_and_echo_command(UBL_LCD_GCODE); + } + + /** + * 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 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 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 + */ + + void _lcd_ubl_level_bed() { + START_MENU(); + MENU_BACK(MSG_PREPARE); + MENU_ITEM(gcode, MSG_UBL_ACTIVATE_MESH, PSTR("G29 A N")); + MENU_ITEM(gcode, MSG_UBL_DEACTIVATE_MESH, PSTR("G29 D N")); + 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 N")); + END_MENU(); + } + #endif + #endif // LCD_BED_LEVELING || HAS_ABL /** @@ -1716,7 +2058,11 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(PROBE_MANUALLY) if (!g29_in_progress) #endif - MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed); + #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 @@ -2158,7 +2504,7 @@ void kill_screen(const char* lcd_msg) { #endif MENU_ITEM(function, MSG_RESTORE_FAILSAFE, lcd_factory_settings); - END_MENU(); + END_MENU(); } /**