diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 93948af68..3a1e454ea 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -111,9 +111,6 @@ static void lcd_status_screen(); #if ENABLED(MANUAL_BED_LEVELING) #include "mesh_bed_leveling.h" - static void _lcd_level_bed(); - static void _lcd_level_bed_homing(); - static void lcd_level_bed(); #endif /* Different types of actions that can be used in menu items. */ @@ -464,6 +461,15 @@ static void lcd_status_screen() { #if ENABLED(ULTIPANEL) +inline void line_to_current(AxisEnum axis) { + #if ENABLED(DELTA) + calculate_delta(current_position); + plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder); + #else + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder); + #endif +} + #if ENABLED(SDSUPPORT) static void lcd_sdcard_pause() { card.pauseSDPrint(); } @@ -852,6 +858,147 @@ void lcd_cooldown() { } #endif + +#if ENABLED(MANUAL_BED_LEVELING) + + /** + * + * "Prepare" > "Bed Leveling" handlers + * + */ + + static int _lcd_level_bed_position; + + /** + * MBL Wait for controller movement and clicks: + * - Movement adjusts the Z axis + * - Click saves the Z and goes to the next mesh point + */ + static void _lcd_level_bed_procedure() { + static bool mbl_wait_for_move = false; + // Menu handlers may be called in a re-entrant fashion + // if they call st_synchronize or plan_buffer_line. So + // while waiting for a move we just ignore new input. + if (mbl_wait_for_move) { + lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; + return; + } + + ENCODER_DIRECTION_NORMAL(); + + // Encoder wheel adjusts the Z position + if (encoderPosition != 0 && movesplanned() <= 3) { + refresh_cmd_timeout(); + current_position[Z_AXIS] += float((int)encoderPosition) * (MBL_Z_STEP); + if (min_software_endstops) NOLESS(current_position[Z_AXIS], Z_MIN_POS); + if (max_software_endstops) NOMORE(current_position[Z_AXIS], Z_MAX_POS); + encoderPosition = 0; + line_to_current(Z_AXIS); + lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; + } + + // Update on first display, then only on updates to Z position + if (lcdDrawUpdate) { + float v = current_position[Z_AXIS] - MESH_HOME_SEARCH_Z; + lcd_implementation_drawedit(PSTR(MSG_MOVE_Z), ftostr43(v + (v < 0 ? -0.0001 : 0.0001), '+')); + } + + // We want subsequent calls, but don't force redraw + // Set here so it can be overridden by lcd_return_to_status below + lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; + + // Click sets the current Z and moves to the next position + static bool debounce_click = false; + if (LCD_CLICKED) { + if (!debounce_click) { + debounce_click = true; // ignore multiple "clicks" in a row + int ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS), + iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS); + if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag + mbl.set_z(ix, iy, current_position[Z_AXIS]); + _lcd_level_bed_position++; + if (_lcd_level_bed_position == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)) { + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; + mbl_wait_for_move = true; + line_to_current(Z_AXIS); + st_synchronize(); + mbl.active = 1; + enqueue_and_echo_commands_P(PSTR("G28")); + mbl_wait_for_move = false; + lcd_return_to_status(); + #if ENABLED(NEWPANEL) + lcd_quick_feedback(); + #endif + LCD_ALERTMESSAGEPGM(MSG_LEVEL_BED_DONE); + #if HAS_BUZZER + buzz(200, 659); + buzz(200, 698); + #endif + } + else { + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; + line_to_current(Z_AXIS); + ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS); + iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS); + if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag + current_position[X_AXIS] = mbl.get_x(ix); + current_position[Y_AXIS] = mbl.get_y(iy); + line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS); + } + } + } + else { + debounce_click = false; + } + } + + static void _lcd_level_bed_homing_done() { + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING), NULL); + lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; + if (LCD_CLICKED) { + current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + current_position[X_AXIS] = MESH_MIN_X; + current_position[Y_AXIS] = MESH_MIN_Y; + line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS); + _lcd_level_bed_position = 0; + lcd_goto_menu(_lcd_level_bed_procedure, true); + } + } + + /** + * MBL Move to mesh starting point + */ + static void _lcd_level_bed_homing() { + if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL); + lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; + if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS]) + lcd_goto_menu(_lcd_level_bed_homing_done); + } + + /** + * MBL Continue Bed Leveling... + */ + static void _lcd_level_bed_continue() { + defer_return_to_status = true; + axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false; + mbl.reset(); + enqueue_and_echo_commands_P(PSTR("G28")); + lcd_goto_menu(_lcd_level_bed_homing, true); + } + + /** + * MBL entry-point + */ + static void lcd_level_bed() { + START_MENU(); + MENU_ITEM(back, MSG_LEVEL_BED_CANCEL); + MENU_ITEM(submenu, MSG_LEVEL_BED, _lcd_level_bed_continue); + END_MENU(); + } + +#endif // MANUAL_BED_LEVELING + /** * * "Prepare" submenu @@ -951,15 +1098,6 @@ static void lcd_prepare_menu() { #endif // DELTA_CALIBRATION_MENU -inline void line_to_current(AxisEnum axis) { - #if ENABLED(DELTA) - calculate_delta(current_position); - plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder); - #else - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder); - #endif -} - /** * * "Prepare" > "Move Axis" submenu @@ -2495,138 +2633,4 @@ char* ftostr52(const float& x) { return conv; } -#if ENABLED(MANUAL_BED_LEVELING) - - static int _lcd_level_bed_position; - - /** - * MBL Wait for controller movement and clicks: - * - Movement adjusts the Z axis - * - Click saves the Z and goes to the next mesh point - */ - static void _lcd_level_bed_procedure() { - static bool mbl_wait_for_move = false; - // Menu handlers may be called in a re-entrant fashion - // if they call st_synchronize or plan_buffer_line. So - // while waiting for a move we just ignore new input. - if (mbl_wait_for_move) { - lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; - return; - } - - ENCODER_DIRECTION_NORMAL(); - - // Encoder wheel adjusts the Z position - if (encoderPosition != 0 && movesplanned() <= 3) { - refresh_cmd_timeout(); - current_position[Z_AXIS] += float((int)encoderPosition) * (MBL_Z_STEP); - if (min_software_endstops) NOLESS(current_position[Z_AXIS], Z_MIN_POS); - if (max_software_endstops) NOMORE(current_position[Z_AXIS], Z_MAX_POS); - encoderPosition = 0; - line_to_current(Z_AXIS); - lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; - } - - // Update on first display, then only on updates to Z position - if (lcdDrawUpdate) { - float v = current_position[Z_AXIS] - MESH_HOME_SEARCH_Z; - lcd_implementation_drawedit(PSTR(MSG_MOVE_Z), ftostr43(v + (v < 0 ? -0.0001 : 0.0001), '+')); - } - - // We want subsequent calls, but don't force redraw - // Set here so it can be overridden by lcd_return_to_status below - lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; - - // Click sets the current Z and moves to the next position - static bool debounce_click = false; - if (LCD_CLICKED) { - if (!debounce_click) { - debounce_click = true; // ignore multiple "clicks" in a row - int ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS), - iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS); - if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag - mbl.set_z(ix, iy, current_position[Z_AXIS]); - _lcd_level_bed_position++; - if (_lcd_level_bed_position == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)) { - current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; - mbl_wait_for_move = true; - line_to_current(Z_AXIS); - st_synchronize(); - mbl.active = 1; - enqueue_and_echo_commands_P(PSTR("G28")); - mbl_wait_for_move = false; - lcd_return_to_status(); - #if ENABLED(NEWPANEL) - lcd_quick_feedback(); - #endif - LCD_ALERTMESSAGEPGM(MSG_LEVEL_BED_DONE); - #if HAS_BUZZER - buzz(200, 659); - buzz(200, 698); - #endif - } - else { - current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; - line_to_current(Z_AXIS); - ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS); - iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS); - if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag - current_position[X_AXIS] = mbl.get_x(ix); - current_position[Y_AXIS] = mbl.get_y(iy); - line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS); - } - } - } - else { - debounce_click = false; - } - } - - static void _lcd_level_bed_homing_done() { - if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING), NULL); - lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; - if (LCD_CLICKED) { - current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - current_position[X_AXIS] = MESH_MIN_X; - current_position[Y_AXIS] = MESH_MIN_Y; - line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS); - _lcd_level_bed_position = 0; - lcd_goto_menu(_lcd_level_bed_procedure, true); - } - } - - /** - * MBL Move to mesh starting point - */ - static void _lcd_level_bed_homing() { - if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL); - lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW; - if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS]) - lcd_goto_menu(_lcd_level_bed_homing_done); - } - - /** - * MBL Continue Bed Leveling... - */ - static void _lcd_level_bed_continue() { - defer_return_to_status = true; - axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false; - mbl.reset(); - enqueue_and_echo_commands_P(PSTR("G28")); - lcd_goto_menu(_lcd_level_bed_homing, true); - } - - /** - * MBL entry-point - */ - static void lcd_level_bed() { - START_MENU(); - MENU_ITEM(back, MSG_LEVEL_BED_CANCEL); - MENU_ITEM(submenu, MSG_LEVEL_BED, _lcd_level_bed_continue); - END_MENU(); - } - -#endif // MANUAL_BED_LEVELING - #endif // ULTRA_LCD