diff --git a/.travis.yml b/.travis.yml index 5bfb6809b..16bf75043 100644 --- a/.travis.yml +++ b/.travis.yml @@ -145,10 +145,10 @@ script: - opt_enable MESH_BED_LEVELING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER - build_marlin # - # Test PROBE_MANUALLY feature + # Test PROBE_MANUALLY feature, with LCD support # - restore_configs - - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR + - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR LCD_BED_LEVELING ULTIMAKERCONTROLLER - build_marlin # # Test EEPROM_SETTINGS, EEPROM_CHITCHAT, M100_FREE_MEMORY_WATCHER, diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 7be9be703..67e97dd78 100755 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -3503,7 +3503,7 @@ inline void gcode_G4() { #endif // Z_SAFE_HOMING #if ENABLED(PROBE_MANUALLY) - static bool g29_in_progress = false; + bool g29_in_progress = false; #else constexpr bool g29_in_progress = false; #endif diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index f8cdec5f5..f40742442 100755 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -457,13 +457,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 */ + extern uint8_t commands_in_queue; + inline void lcd_synchronize() { lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, PSTR(MSG_MOVING)); if (no_reentrance) return; no_reentrance = true; screenFunc_t old_screen = currentScreen; lcd_goto_screen(lcd_synchronize); - stepper.synchronize(); + while (commands_in_queue) { + idle(); + stepper.synchronize(); + } no_reentrance = false; lcd_goto_screen(old_screen); } @@ -982,7 +987,7 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999); // Manual bed leveling, Bed Z: - #if ENABLED(LCD_BED_LEVELING) + #if ENABLED(MESH_BED_LEVELING) && ENABLED(LCD_BED_LEVELING) MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1); #endif @@ -1325,30 +1330,53 @@ void kill_screen(const char* lcd_msg) { /** * - * "Prepare" > "Bed Leveling" handlers + * "Prepare" > "Level Bed" handlers * */ static uint8_t manual_probe_index; - // Utility to go to the next mesh point - inline void _manual_probe_xy(float x, float y) { - if (no_reentrance) return; - #if MANUAL_PROBE_HEIGHT > 0 - current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT; - line_to_current(Z_AXIS); - #endif - current_position[X_AXIS] = LOGICAL_X_POSITION(x); - current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); - planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); - #if MANUAL_PROBE_HEIGHT > 0 - current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + 0.2; - line_to_current(Z_AXIS); + #if ENABLED(PROBE_MANUALLY) + extern bool g29_in_progress; + #endif + + // LCD probed points are from defaults + constexpr uint8_t total_probe_points = + #if ABL_GRID + (ABL_GRID_MAX_POINTS_X) * (ABL_GRID_MAX_POINTS_Y) + #elif ENABLED(AUTO_BED_LEVELING_3POINT) + int(3) + #elif ENABLED(AUTO_BED_LEVELING_UBL) + (UBL_MESH_NUM_X_POINTS) * (UBL_MESH_NUM_Y_POINTS) + #elif ENABLED(MESH_BED_LEVELING) + (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS) #endif - lcd_synchronize(); - } + ; - void _lcd_level_goto_next_point(); + #if ENABLED(MESH_BED_LEVELING) + + // Utility to go to the next mesh point + inline void _manual_probe_goto_xy(float x, float y) { + if (no_reentrance) return; + #if MANUAL_PROBE_HEIGHT > 0 + current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT; + line_to_current(Z_AXIS); + #endif + current_position[X_AXIS] = LOGICAL_X_POSITION(x); + current_position[Y_AXIS] = LOGICAL_Y_POSITION(y); + planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder); + #if MANUAL_PROBE_HEIGHT > 0 + current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + 0.2; + line_to_current(Z_AXIS); + #endif + lcd_synchronize(); + } + + #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)); @@ -1356,7 +1384,19 @@ void kill_screen(const char* lcd_msg) { } /** - * Step 7: Get the Z coordinate, then goto next point or exit + * 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; + } + + /** + * Step 7: Get the Z coordinate, click goes to the next point or exits */ void _lcd_level_bed_get_z() { ENCODER_DIRECTION_NORMAL(); @@ -1368,77 +1408,129 @@ void kill_screen(const char* lcd_msg) { 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); + 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) { - mbl.set_zigzag_z(manual_probe_index++, current_position[Z_AXIS]); - if (manual_probe_index == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)) { + + // Use a hook to set the probe point z + // (zigzag arranges in XY order) + #if ENABLED(AUTO_BED_LEVELING_UBL) + + // UBL set-z handling goes here + + #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]); + + #endif + + // If done... + if (manual_probe_index == total_probe_points) { + + // Say "Done!" lcd_goto_screen(_lcd_level_bed_done); + // Raise Z to the "manual probe height" #if MANUAL_PROBE_HEIGHT > 0 current_position[Z_AXIS] = LOGICAL_Z_POSITION(Z_MIN_POS) + MANUAL_PROBE_HEIGHT; line_to_current(Z_AXIS); lcd_synchronize(); #endif - mbl.set_has_mesh(true); - mbl.set_reactivate(true); - enqueue_and_echo_commands_P(PSTR("G28")); + // Enable leveling, if needed + #if ENABLED(MESH_BED_LEVELING) + + mbl.set_has_mesh(true); + mbl.set_reactivate(true); + enqueue_and_echo_commands_P(PSTR("G28")); + + #elif ENABLED(AUTO_BED_LEVELING_UBL) + + // UBL enable goes here + + #elif ENABLED(PROBE_MANUALLY) + + // ABL will be enabled due to "G29". + + #endif + lcd_return_to_status(); //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE); lcd_completion_feedback(); } else { - lcd_goto_screen(_lcd_level_goto_next_point); + + // Move to the next probe point, if needed + #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) + + _lcd_level_goto_next_point(); + + #elif ENABLED(AUTO_BED_LEVELING_UBL) + + // UBL goto-next-point goes here + + #endif } } -KeepDrawing: + KeepDrawing: + // Update on first display, then only on updates to Z position // Show message above on clicks instead if (lcdDrawUpdate) { const float v = current_position[Z_AXIS]; lcd_implementation_drawedit(PSTR(MSG_MOVE_Z), ftostr43sign(v + (v < 0 ? -0.0001 : 0.0001), '+')); } - } - /** - * Step 6: Display "Next point: 1 / 9" while waiting for move to finish - */ - void _lcd_level_bed_moving() { - if (lcdDrawUpdate) { - char msg[10]; + #if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY) + + /** + * Step 5: Initiate a move to the next point + */ + void _lcd_level_goto_next_point() { + + // Set the menu to display ahead of blocking call + lcd_goto_screen(_lcd_level_bed_moving); + #if ENABLED(MESH_BED_LEVELING) - sprintf_P(msg, PSTR("%i / %u"), (int)(manual_probe_index + 1), (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)); + + int8_t px, py; + mbl.zigzag(manual_probe_index, px, py); + + // 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]) + ); + #elif ENABLED(AUTO_BED_LEVELING_UBL) - sprintf_P(msg, PSTR("%i / %u"), (int)(manual_probe_index + 1), (UBL_MESH_NUM_X_POINTS) * (UBL_MESH_NUM_Y_POINTS)); - #endif - lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_NEXT_POINT), msg); - } - lcdDrawUpdate = LCDVIEW_KEEP_REDRAWING; - } + // UBL may have its own methodology - /** - * Step 5: Initiate a move to the next point - */ - void _lcd_level_goto_next_point() { - // Set the menu to display ahead of blocking call - lcd_goto_screen(_lcd_level_bed_moving); + #elif ENABLED(PROBE_MANUALLY) + + // Just wait for the G29 move to complete + lcd_synchronize(); - // _manual_probe_xy runs the menu loop until the move is done - int8_t px, py; - mbl.zigzag(manual_probe_index, px, py); - _manual_probe_xy(mbl.index_to_xpos[px], mbl.index_to_ypos[py]); + #endif - // After the blocking function returns, change menus - lcd_goto_screen(_lcd_level_bed_get_z); - } + // After the blocking function returns, change menus + lcd_goto_screen(_lcd_level_bed_get_z); + } + + #endif // MESH_BED_LEVELING /** * Step 4: Display "Click to Begin", wait for click @@ -1448,7 +1540,14 @@ KeepDrawing: if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING)); if (lcd_clicked) { manual_probe_index = 0; - lcd_goto_screen(_lcd_level_goto_next_point); + #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 } } @@ -1466,15 +1565,17 @@ KeepDrawing: * Step 2: Continue Bed Leveling... */ void _lcd_level_bed_continue() { + #if PLANNER_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL) + reset_bed_level(); + #endif defer_return_to_status = true; axis_homed[X_AXIS] = axis_homed[Y_AXIS] = axis_homed[Z_AXIS] = false; - mbl.reset(); - enqueue_and_echo_commands_P(PSTR("G28")); lcd_goto_screen(_lcd_level_bed_homing); + enqueue_and_echo_commands_P(PSTR("G28")); } /** - * Step 1: MBL entry-point: "Cancel" or "Level Bed" + * Step 1: Bed Level entry-point: "Cancel" or "Level Bed" */ void lcd_level_bed() { START_MENU(); @@ -1483,7 +1584,7 @@ KeepDrawing: END_MENU(); } - #endif // LCD_BED_LEVELING + #endif // LCD_BED_LEVELING /** * @@ -1520,12 +1621,19 @@ KeepDrawing: // // Level Bed // - #if HAS_ABL + #if ENABLED(LCD_BED_LEVELING) + + #if ENABLED(PROBE_MANUALLY) + if (!g29_in_progress) + #endif + MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed); + + #elif HAS_ABL + MENU_ITEM(gcode, MSG_LEVEL_BED, axis_homed[X_AXIS] && axis_homed[Y_AXIS] ? PSTR("G29") : PSTR("G28\nG29") ); - #elif ENABLED(LCD_BED_LEVELING) - MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed); + #endif #if DISABLED(NO_WORKSPACE_OFFSETS) @@ -2253,7 +2361,7 @@ KeepDrawing: MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX); #endif // Manual bed leveling, Bed Z: - #if ENABLED(LCD_BED_LEVELING) + #if ENABLED(MESH_BED_LEVELING) && ENABLED(LCD_BED_LEVELING) MENU_ITEM_EDIT(float43, MSG_BED_Z, &mbl.z_offset, -1, 1); #endif MENU_ITEM_EDIT(float5, MSG_ACC, &planner.acceleration, 10, 99000);