|
@@ -111,9 +111,6 @@ static void lcd_status_screen();
|
111
|
111
|
|
112
|
112
|
#if ENABLED(MANUAL_BED_LEVELING)
|
113
|
113
|
#include "mesh_bed_leveling.h"
|
114
|
|
- static void _lcd_level_bed();
|
115
|
|
- static void _lcd_level_bed_homing();
|
116
|
|
- static void lcd_level_bed();
|
117
|
114
|
#endif
|
118
|
115
|
|
119
|
116
|
/* Different types of actions that can be used in menu items. */
|
|
@@ -464,6 +461,15 @@ static void lcd_status_screen() {
|
464
|
461
|
|
465
|
462
|
#if ENABLED(ULTIPANEL)
|
466
|
463
|
|
|
464
|
+inline void line_to_current(AxisEnum axis) {
|
|
465
|
+ #if ENABLED(DELTA)
|
|
466
|
+ calculate_delta(current_position);
|
|
467
|
+ plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder);
|
|
468
|
+ #else
|
|
469
|
+ 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);
|
|
470
|
+ #endif
|
|
471
|
+}
|
|
472
|
+
|
467
|
473
|
#if ENABLED(SDSUPPORT)
|
468
|
474
|
|
469
|
475
|
static void lcd_sdcard_pause() { card.pauseSDPrint(); }
|
|
@@ -852,6 +858,147 @@ void lcd_cooldown() {
|
852
|
858
|
}
|
853
|
859
|
|
854
|
860
|
#endif
|
|
861
|
+
|
|
862
|
+#if ENABLED(MANUAL_BED_LEVELING)
|
|
863
|
+
|
|
864
|
+ /**
|
|
865
|
+ *
|
|
866
|
+ * "Prepare" > "Bed Leveling" handlers
|
|
867
|
+ *
|
|
868
|
+ */
|
|
869
|
+
|
|
870
|
+ static int _lcd_level_bed_position;
|
|
871
|
+
|
|
872
|
+ /**
|
|
873
|
+ * MBL Wait for controller movement and clicks:
|
|
874
|
+ * - Movement adjusts the Z axis
|
|
875
|
+ * - Click saves the Z and goes to the next mesh point
|
|
876
|
+ */
|
|
877
|
+ static void _lcd_level_bed_procedure() {
|
|
878
|
+ static bool mbl_wait_for_move = false;
|
|
879
|
+ // Menu handlers may be called in a re-entrant fashion
|
|
880
|
+ // if they call st_synchronize or plan_buffer_line. So
|
|
881
|
+ // while waiting for a move we just ignore new input.
|
|
882
|
+ if (mbl_wait_for_move) {
|
|
883
|
+ lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
|
884
|
+ return;
|
|
885
|
+ }
|
|
886
|
+
|
|
887
|
+ ENCODER_DIRECTION_NORMAL();
|
|
888
|
+
|
|
889
|
+ // Encoder wheel adjusts the Z position
|
|
890
|
+ if (encoderPosition != 0 && movesplanned() <= 3) {
|
|
891
|
+ refresh_cmd_timeout();
|
|
892
|
+ current_position[Z_AXIS] += float((int)encoderPosition) * (MBL_Z_STEP);
|
|
893
|
+ if (min_software_endstops) NOLESS(current_position[Z_AXIS], Z_MIN_POS);
|
|
894
|
+ if (max_software_endstops) NOMORE(current_position[Z_AXIS], Z_MAX_POS);
|
|
895
|
+ encoderPosition = 0;
|
|
896
|
+ line_to_current(Z_AXIS);
|
|
897
|
+ lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
|
898
|
+ }
|
|
899
|
+
|
|
900
|
+ // Update on first display, then only on updates to Z position
|
|
901
|
+ if (lcdDrawUpdate) {
|
|
902
|
+ float v = current_position[Z_AXIS] - MESH_HOME_SEARCH_Z;
|
|
903
|
+ lcd_implementation_drawedit(PSTR(MSG_MOVE_Z), ftostr43(v + (v < 0 ? -0.0001 : 0.0001), '+'));
|
|
904
|
+ }
|
|
905
|
+
|
|
906
|
+ // We want subsequent calls, but don't force redraw
|
|
907
|
+ // Set here so it can be overridden by lcd_return_to_status below
|
|
908
|
+ lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
|
909
|
+
|
|
910
|
+ // Click sets the current Z and moves to the next position
|
|
911
|
+ static bool debounce_click = false;
|
|
912
|
+ if (LCD_CLICKED) {
|
|
913
|
+ if (!debounce_click) {
|
|
914
|
+ debounce_click = true; // ignore multiple "clicks" in a row
|
|
915
|
+ int ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS),
|
|
916
|
+ iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS);
|
|
917
|
+ if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag
|
|
918
|
+ mbl.set_z(ix, iy, current_position[Z_AXIS]);
|
|
919
|
+ _lcd_level_bed_position++;
|
|
920
|
+ if (_lcd_level_bed_position == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)) {
|
|
921
|
+ current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
|
|
922
|
+ mbl_wait_for_move = true;
|
|
923
|
+ line_to_current(Z_AXIS);
|
|
924
|
+ st_synchronize();
|
|
925
|
+ mbl.active = 1;
|
|
926
|
+ enqueue_and_echo_commands_P(PSTR("G28"));
|
|
927
|
+ mbl_wait_for_move = false;
|
|
928
|
+ lcd_return_to_status();
|
|
929
|
+ #if ENABLED(NEWPANEL)
|
|
930
|
+ lcd_quick_feedback();
|
|
931
|
+ #endif
|
|
932
|
+ LCD_ALERTMESSAGEPGM(MSG_LEVEL_BED_DONE);
|
|
933
|
+ #if HAS_BUZZER
|
|
934
|
+ buzz(200, 659);
|
|
935
|
+ buzz(200, 698);
|
|
936
|
+ #endif
|
|
937
|
+ }
|
|
938
|
+ else {
|
|
939
|
+ current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
|
|
940
|
+ line_to_current(Z_AXIS);
|
|
941
|
+ ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS);
|
|
942
|
+ iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS);
|
|
943
|
+ if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag
|
|
944
|
+ current_position[X_AXIS] = mbl.get_x(ix);
|
|
945
|
+ current_position[Y_AXIS] = mbl.get_y(iy);
|
|
946
|
+ line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS);
|
|
947
|
+ }
|
|
948
|
+ }
|
|
949
|
+ }
|
|
950
|
+ else {
|
|
951
|
+ debounce_click = false;
|
|
952
|
+ }
|
|
953
|
+ }
|
|
954
|
+
|
|
955
|
+ static void _lcd_level_bed_homing_done() {
|
|
956
|
+ if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING), NULL);
|
|
957
|
+ lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
|
958
|
+ if (LCD_CLICKED) {
|
|
959
|
+ current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
|
|
960
|
+ plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
|
961
|
+ current_position[X_AXIS] = MESH_MIN_X;
|
|
962
|
+ current_position[Y_AXIS] = MESH_MIN_Y;
|
|
963
|
+ line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS);
|
|
964
|
+ _lcd_level_bed_position = 0;
|
|
965
|
+ lcd_goto_menu(_lcd_level_bed_procedure, true);
|
|
966
|
+ }
|
|
967
|
+ }
|
|
968
|
+
|
|
969
|
+ /**
|
|
970
|
+ * MBL Move to mesh starting point
|
|
971
|
+ */
|
|
972
|
+ static void _lcd_level_bed_homing() {
|
|
973
|
+ if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL);
|
|
974
|
+ lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
|
975
|
+ if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])
|
|
976
|
+ lcd_goto_menu(_lcd_level_bed_homing_done);
|
|
977
|
+ }
|
|
978
|
+
|
|
979
|
+ /**
|
|
980
|
+ * MBL Continue Bed Leveling...
|
|
981
|
+ */
|
|
982
|
+ static void _lcd_level_bed_continue() {
|
|
983
|
+ defer_return_to_status = true;
|
|
984
|
+ axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false;
|
|
985
|
+ mbl.reset();
|
|
986
|
+ enqueue_and_echo_commands_P(PSTR("G28"));
|
|
987
|
+ lcd_goto_menu(_lcd_level_bed_homing, true);
|
|
988
|
+ }
|
|
989
|
+
|
|
990
|
+ /**
|
|
991
|
+ * MBL entry-point
|
|
992
|
+ */
|
|
993
|
+ static void lcd_level_bed() {
|
|
994
|
+ START_MENU();
|
|
995
|
+ MENU_ITEM(back, MSG_LEVEL_BED_CANCEL);
|
|
996
|
+ MENU_ITEM(submenu, MSG_LEVEL_BED, _lcd_level_bed_continue);
|
|
997
|
+ END_MENU();
|
|
998
|
+ }
|
|
999
|
+
|
|
1000
|
+#endif // MANUAL_BED_LEVELING
|
|
1001
|
+
|
855
|
1002
|
/**
|
856
|
1003
|
*
|
857
|
1004
|
* "Prepare" submenu
|
|
@@ -951,15 +1098,6 @@ static void lcd_prepare_menu() {
|
951
|
1098
|
|
952
|
1099
|
#endif // DELTA_CALIBRATION_MENU
|
953
|
1100
|
|
954
|
|
-inline void line_to_current(AxisEnum axis) {
|
955
|
|
- #if ENABLED(DELTA)
|
956
|
|
- calculate_delta(current_position);
|
957
|
|
- plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder);
|
958
|
|
- #else
|
959
|
|
- 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);
|
960
|
|
- #endif
|
961
|
|
-}
|
962
|
|
-
|
963
|
1101
|
/**
|
964
|
1102
|
*
|
965
|
1103
|
* "Prepare" > "Move Axis" submenu
|
|
@@ -2495,138 +2633,4 @@ char* ftostr52(const float& x) {
|
2495
|
2633
|
return conv;
|
2496
|
2634
|
}
|
2497
|
2635
|
|
2498
|
|
-#if ENABLED(MANUAL_BED_LEVELING)
|
2499
|
|
-
|
2500
|
|
- static int _lcd_level_bed_position;
|
2501
|
|
-
|
2502
|
|
- /**
|
2503
|
|
- * MBL Wait for controller movement and clicks:
|
2504
|
|
- * - Movement adjusts the Z axis
|
2505
|
|
- * - Click saves the Z and goes to the next mesh point
|
2506
|
|
- */
|
2507
|
|
- static void _lcd_level_bed_procedure() {
|
2508
|
|
- static bool mbl_wait_for_move = false;
|
2509
|
|
- // Menu handlers may be called in a re-entrant fashion
|
2510
|
|
- // if they call st_synchronize or plan_buffer_line. So
|
2511
|
|
- // while waiting for a move we just ignore new input.
|
2512
|
|
- if (mbl_wait_for_move) {
|
2513
|
|
- lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
2514
|
|
- return;
|
2515
|
|
- }
|
2516
|
|
-
|
2517
|
|
- ENCODER_DIRECTION_NORMAL();
|
2518
|
|
-
|
2519
|
|
- // Encoder wheel adjusts the Z position
|
2520
|
|
- if (encoderPosition != 0 && movesplanned() <= 3) {
|
2521
|
|
- refresh_cmd_timeout();
|
2522
|
|
- current_position[Z_AXIS] += float((int)encoderPosition) * (MBL_Z_STEP);
|
2523
|
|
- if (min_software_endstops) NOLESS(current_position[Z_AXIS], Z_MIN_POS);
|
2524
|
|
- if (max_software_endstops) NOMORE(current_position[Z_AXIS], Z_MAX_POS);
|
2525
|
|
- encoderPosition = 0;
|
2526
|
|
- line_to_current(Z_AXIS);
|
2527
|
|
- lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
2528
|
|
- }
|
2529
|
|
-
|
2530
|
|
- // Update on first display, then only on updates to Z position
|
2531
|
|
- if (lcdDrawUpdate) {
|
2532
|
|
- float v = current_position[Z_AXIS] - MESH_HOME_SEARCH_Z;
|
2533
|
|
- lcd_implementation_drawedit(PSTR(MSG_MOVE_Z), ftostr43(v + (v < 0 ? -0.0001 : 0.0001), '+'));
|
2534
|
|
- }
|
2535
|
|
-
|
2536
|
|
- // We want subsequent calls, but don't force redraw
|
2537
|
|
- // Set here so it can be overridden by lcd_return_to_status below
|
2538
|
|
- lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
2539
|
|
-
|
2540
|
|
- // Click sets the current Z and moves to the next position
|
2541
|
|
- static bool debounce_click = false;
|
2542
|
|
- if (LCD_CLICKED) {
|
2543
|
|
- if (!debounce_click) {
|
2544
|
|
- debounce_click = true; // ignore multiple "clicks" in a row
|
2545
|
|
- int ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS),
|
2546
|
|
- iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS);
|
2547
|
|
- if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag
|
2548
|
|
- mbl.set_z(ix, iy, current_position[Z_AXIS]);
|
2549
|
|
- _lcd_level_bed_position++;
|
2550
|
|
- if (_lcd_level_bed_position == (MESH_NUM_X_POINTS) * (MESH_NUM_Y_POINTS)) {
|
2551
|
|
- current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
|
2552
|
|
- mbl_wait_for_move = true;
|
2553
|
|
- line_to_current(Z_AXIS);
|
2554
|
|
- st_synchronize();
|
2555
|
|
- mbl.active = 1;
|
2556
|
|
- enqueue_and_echo_commands_P(PSTR("G28"));
|
2557
|
|
- mbl_wait_for_move = false;
|
2558
|
|
- lcd_return_to_status();
|
2559
|
|
- #if ENABLED(NEWPANEL)
|
2560
|
|
- lcd_quick_feedback();
|
2561
|
|
- #endif
|
2562
|
|
- LCD_ALERTMESSAGEPGM(MSG_LEVEL_BED_DONE);
|
2563
|
|
- #if HAS_BUZZER
|
2564
|
|
- buzz(200, 659);
|
2565
|
|
- buzz(200, 698);
|
2566
|
|
- #endif
|
2567
|
|
- }
|
2568
|
|
- else {
|
2569
|
|
- current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
|
2570
|
|
- line_to_current(Z_AXIS);
|
2571
|
|
- ix = _lcd_level_bed_position % (MESH_NUM_X_POINTS);
|
2572
|
|
- iy = _lcd_level_bed_position / (MESH_NUM_X_POINTS);
|
2573
|
|
- if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // Zig zag
|
2574
|
|
- current_position[X_AXIS] = mbl.get_x(ix);
|
2575
|
|
- current_position[Y_AXIS] = mbl.get_y(iy);
|
2576
|
|
- line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS);
|
2577
|
|
- }
|
2578
|
|
- }
|
2579
|
|
- }
|
2580
|
|
- else {
|
2581
|
|
- debounce_click = false;
|
2582
|
|
- }
|
2583
|
|
- }
|
2584
|
|
-
|
2585
|
|
- static void _lcd_level_bed_homing_done() {
|
2586
|
|
- if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_WAITING), NULL);
|
2587
|
|
- lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
2588
|
|
- if (LCD_CLICKED) {
|
2589
|
|
- current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
|
2590
|
|
- plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
2591
|
|
- current_position[X_AXIS] = MESH_MIN_X;
|
2592
|
|
- current_position[Y_AXIS] = MESH_MIN_Y;
|
2593
|
|
- line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS);
|
2594
|
|
- _lcd_level_bed_position = 0;
|
2595
|
|
- lcd_goto_menu(_lcd_level_bed_procedure, true);
|
2596
|
|
- }
|
2597
|
|
- }
|
2598
|
|
-
|
2599
|
|
- /**
|
2600
|
|
- * MBL Move to mesh starting point
|
2601
|
|
- */
|
2602
|
|
- static void _lcd_level_bed_homing() {
|
2603
|
|
- if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL);
|
2604
|
|
- lcdDrawUpdate = LCD_DRAW_UPDATE_CALL_NO_REDRAW;
|
2605
|
|
- if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])
|
2606
|
|
- lcd_goto_menu(_lcd_level_bed_homing_done);
|
2607
|
|
- }
|
2608
|
|
-
|
2609
|
|
- /**
|
2610
|
|
- * MBL Continue Bed Leveling...
|
2611
|
|
- */
|
2612
|
|
- static void _lcd_level_bed_continue() {
|
2613
|
|
- defer_return_to_status = true;
|
2614
|
|
- axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false;
|
2615
|
|
- mbl.reset();
|
2616
|
|
- enqueue_and_echo_commands_P(PSTR("G28"));
|
2617
|
|
- lcd_goto_menu(_lcd_level_bed_homing, true);
|
2618
|
|
- }
|
2619
|
|
-
|
2620
|
|
- /**
|
2621
|
|
- * MBL entry-point
|
2622
|
|
- */
|
2623
|
|
- static void lcd_level_bed() {
|
2624
|
|
- START_MENU();
|
2625
|
|
- MENU_ITEM(back, MSG_LEVEL_BED_CANCEL);
|
2626
|
|
- MENU_ITEM(submenu, MSG_LEVEL_BED, _lcd_level_bed_continue);
|
2627
|
|
- END_MENU();
|
2628
|
|
- }
|
2629
|
|
-
|
2630
|
|
-#endif // MANUAL_BED_LEVELING
|
2631
|
|
-
|
2632
|
2636
|
#endif // ULTRA_LCD
|