Browse Source

Added menu option for bed leveling.

Edward Patel 9 years ago
parent
commit
8005d22c81

+ 2
- 1
Marlin/Configuration.h View File

@@ -384,8 +384,9 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
384 384
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
385 385
   #define MESH_MIN_Y 10
386 386
   #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
387
-  #define MESH_NUM_X_POINTS 4
387
+  #define MESH_NUM_X_POINTS 3
388 388
   #define MESH_NUM_Y_POINTS 3
389
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
389 390
 #endif  // MESH_BED_LEVELING
390 391
 
391 392
 //===========================================================================

+ 23
- 1
Marlin/ConfigurationStore.cpp View File

@@ -20,6 +20,10 @@
20 20
  *  max_e_jerk
21 21
  *  add_homing (x3)
22 22
  *
23
+ * Mesh bed leveling:
24
+ *  active
25
+ *  z_values[][]
26
+ *
23 27
  * DELTA:
24 28
  *  endstop_adj (x3)
25 29
  *  delta_radius
@@ -69,6 +73,10 @@
69 73
 #include "ultralcd.h"
70 74
 #include "ConfigurationStore.h"
71 75
 
76
+#if defined(MESH_BED_LEVELING)
77
+   #include "mesh_bed_leveling.h"
78
+#endif  // MESH_BED_LEVELING
79
+
72 80
 void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) {
73 81
   uint8_t c;
74 82
   while(size--) {
@@ -128,6 +136,11 @@ void Config_StoreSettings()  {
128 136
   EEPROM_WRITE_VAR(i, max_e_jerk);
129 137
   EEPROM_WRITE_VAR(i, add_homing);
130 138
 
139
+  #if defined(MESH_BED_LEVELING)
140
+    EEPROM_WRITE_VAR(i, mbl.active);
141
+    EEPROM_WRITE_VAR(i, mbl.z_values);
142
+  #endif  // MESH_BED_LEVELING
143
+
131 144
   #ifdef DELTA
132 145
     EEPROM_WRITE_VAR(i, endstop_adj);               // 3 floats
133 146
     EEPROM_WRITE_VAR(i, delta_radius);              // 1 float
@@ -250,7 +263,7 @@ void Config_RetrieveSettings() {
250 263
     EEPROM_READ_VAR(i, max_feedrate);
251 264
     EEPROM_READ_VAR(i, max_acceleration_units_per_sq_second);
252 265
 
253
-        // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
266
+    // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
254 267
     reset_acceleration_rates();
255 268
 
256 269
     EEPROM_READ_VAR(i, acceleration);
@@ -264,6 +277,11 @@ void Config_RetrieveSettings() {
264 277
     EEPROM_READ_VAR(i, max_e_jerk);
265 278
     EEPROM_READ_VAR(i, add_homing);
266 279
 
280
+    #if defined(MESH_BED_LEVELING)
281
+      EEPROM_READ_VAR(i, mbl.active);
282
+      EEPROM_READ_VAR(i, mbl.z_values);
283
+    #endif  // MESH_BED_LEVELING
284
+
267 285
     #ifdef DELTA
268 286
       EEPROM_READ_VAR(i, endstop_adj);                // 3 floats
269 287
       EEPROM_READ_VAR(i, delta_radius);               // 1 float
@@ -392,6 +410,10 @@ void Config_ResetDefault() {
392 410
   max_e_jerk = DEFAULT_EJERK;
393 411
   add_homing[X_AXIS] = add_homing[Y_AXIS] = add_homing[Z_AXIS] = 0;
394 412
 
413
+  #if defined(MESH_BED_LEVELING)
414
+    mbl.active = 0;
415
+  #endif  // MESH_BED_LEVELING
416
+
395 417
   #ifdef DELTA
396 418
     endstop_adj[X_AXIS] = endstop_adj[Y_AXIS] = endstop_adj[Z_AXIS] = 0;
397 419
     delta_radius =  DELTA_RADIUS;

+ 54
- 1
Marlin/Marlin_main.cpp View File

@@ -1566,6 +1566,11 @@ inline void gcode_G28() {
1566 1566
     plan_bed_level_matrix.set_to_identity();  //Reset the plane ("erase" all leveling data)
1567 1567
   #endif
1568 1568
 
1569
+  #if defined(MESH_BED_LEVELING)
1570
+    uint8_t mbl_was_active = mbl.active;
1571
+    mbl.active = 0;
1572
+  #endif  // MESH_BED_LEVELING
1573
+
1569 1574
   saved_feedrate = feedrate;
1570 1575
   saved_feedmultiply = feedmultiply;
1571 1576
   feedmultiply = 100;
@@ -1780,6 +1785,23 @@ inline void gcode_G28() {
1780 1785
     enable_endstops(false);
1781 1786
   #endif
1782 1787
 
1788
+  #if defined(MESH_BED_LEVELING)
1789
+    if (mbl_was_active) {
1790
+      current_position[X_AXIS] = mbl.get_x(0);
1791
+      current_position[Y_AXIS] = mbl.get_y(0);
1792
+      destination[X_AXIS] = current_position[X_AXIS];
1793
+      destination[Y_AXIS] = current_position[Y_AXIS];
1794
+      destination[Z_AXIS] = current_position[Z_AXIS];
1795
+      destination[E_AXIS] = current_position[E_AXIS];
1796
+      feedrate = homing_feedrate[X_AXIS];
1797
+      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
1798
+      st_synchronize();
1799
+      current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1800
+      plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1801
+      mbl.active = 1;
1802
+    }
1803
+  #endif
1804
+
1783 1805
   feedrate = saved_feedrate;
1784 1806
   feedmultiply = saved_feedmultiply;
1785 1807
   previous_millis_cmd = millis();
@@ -4998,6 +5020,13 @@ void calculate_delta(float cartesian[3])
4998 5020
 // This function is used to split lines on mesh borders so each segment is only part of one mesh area
4999 5021
 void mesh_plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder, uint8_t x_splits=0xff, uint8_t y_splits=0xff)
5000 5022
 {
5023
+  if (!mbl.active) {
5024
+    plan_buffer_line(x, y, z, e, feed_rate, extruder);
5025
+    for(int8_t i=0; i < NUM_AXIS; i++) {
5026
+      current_position[i] = destination[i];
5027
+    }
5028
+    return;
5029
+  }
5001 5030
   int pix = mbl.select_x_index(current_position[X_AXIS]);
5002 5031
   int piy = mbl.select_y_index(current_position[Y_AXIS]);
5003 5032
   int ix = mbl.select_x_index(x);
@@ -5012,7 +5041,13 @@ void mesh_plan_buffer_line(float x, float y, float z, const float &e, float feed
5012 5041
     float ny = current_position[Y_AXIS] + (y - current_position[Y_AXIS]) * normalized_dist;
5013 5042
     float ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5014 5043
     x_splits ^= 1 << ix;
5044
+    destination[X_AXIS] = nx;
5045
+    destination[Y_AXIS] = ny;
5046
+    destination[E_AXIS] = ne;
5015 5047
     mesh_plan_buffer_line(nx, ny, z, ne, feed_rate, extruder, x_splits, y_splits);
5048
+    destination[X_AXIS] = x;
5049
+    destination[Y_AXIS] = y;
5050
+    destination[E_AXIS] = e;
5016 5051
     mesh_plan_buffer_line(x, y, z, e, feed_rate, extruder, x_splits, y_splits);
5017 5052
     return;
5018 5053
   } else if (ix < pix && (x_splits)&(1<<pix)) {
@@ -5021,7 +5056,13 @@ void mesh_plan_buffer_line(float x, float y, float z, const float &e, float feed
5021 5056
     float ny = current_position[Y_AXIS] + (y - current_position[Y_AXIS]) * normalized_dist;
5022 5057
     float ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5023 5058
     x_splits ^= 1 << pix;
5059
+    destination[X_AXIS] = nx;
5060
+    destination[Y_AXIS] = ny;
5061
+    destination[E_AXIS] = ne;
5024 5062
     mesh_plan_buffer_line(nx, ny, z, ne, feed_rate, extruder, x_splits, y_splits);
5063
+    destination[X_AXIS] = x;
5064
+    destination[Y_AXIS] = y;
5065
+    destination[E_AXIS] = e;
5025 5066
     mesh_plan_buffer_line(x, y, z, e, feed_rate, extruder, x_splits, y_splits);
5026 5067
     return;
5027 5068
   } else if (iy > piy && (y_splits)&(1<<iy)) {
@@ -5030,7 +5071,13 @@ void mesh_plan_buffer_line(float x, float y, float z, const float &e, float feed
5030 5071
     float nx = current_position[X_AXIS] + (x - current_position[X_AXIS]) * normalized_dist;
5031 5072
     float ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5032 5073
     y_splits ^= 1 << iy;
5074
+    destination[X_AXIS] = nx;
5075
+    destination[Y_AXIS] = ny;
5076
+    destination[E_AXIS] = ne;
5033 5077
     mesh_plan_buffer_line(nx, ny, z, ne, feed_rate, extruder, x_splits, y_splits);
5078
+    destination[X_AXIS] = x;
5079
+    destination[Y_AXIS] = y;
5080
+    destination[E_AXIS] = e;
5034 5081
     mesh_plan_buffer_line(x, y, z, e, feed_rate, extruder, x_splits, y_splits);
5035 5082
     return;
5036 5083
   } else if (iy < piy && (y_splits)&(1<<piy)) {
@@ -5039,11 +5086,17 @@ void mesh_plan_buffer_line(float x, float y, float z, const float &e, float feed
5039 5086
     float nx = current_position[X_AXIS] + (x - current_position[X_AXIS]) * normalized_dist;
5040 5087
     float ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5041 5088
     y_splits ^= 1 << piy;
5089
+    destination[X_AXIS] = nx;
5090
+    destination[Y_AXIS] = ny;
5091
+    destination[E_AXIS] = ne;
5042 5092
     mesh_plan_buffer_line(nx, ny, z, ne, feed_rate, extruder, x_splits, y_splits);
5093
+    destination[X_AXIS] = x;
5094
+    destination[Y_AXIS] = y;
5095
+    destination[E_AXIS] = e;
5043 5096
     mesh_plan_buffer_line(x, y, z, e, feed_rate, extruder, x_splits, y_splits);
5044 5097
     return;
5045 5098
   }
5046
-  plan_buffer_line(x, y, z, e, feedrate, extruder);
5099
+  plan_buffer_line(x, y, z, e, feed_rate, extruder);
5047 5100
   for(int8_t i=0; i < NUM_AXIS; i++) {
5048 5101
     current_position[i] = destination[i];
5049 5102
   }

+ 3
- 0
Marlin/language_en.h View File

@@ -95,6 +95,9 @@
95 95
 #ifndef MSG_MOVE_AXIS
96 96
 #define MSG_MOVE_AXIS                       "Move axis"
97 97
 #endif
98
+#ifndef MSG_LEVEL_BED
99
+#define MSG_LEVEL_BED                       "Level bed"
100
+#endif
98 101
 #ifndef MSG_MOVE_X
99 102
 #define MSG_MOVE_X                          "Move X"
100 103
 #endif

+ 13
- 0
Marlin/mesh_bed_leveling.cpp View File

@@ -4,4 +4,17 @@
4 4
 
5 5
 mesh_bed_leveling mbl;
6 6
 
7
+mesh_bed_leveling::mesh_bed_leveling() {
8
+    reset();
9
+}
10
+    
11
+void mesh_bed_leveling::reset() {
12
+    for (int y=0; y<MESH_NUM_Y_POINTS; y++) {
13
+        for (int x=0; x<MESH_NUM_X_POINTS; x++) {
14
+            z_values[y][x] = 0;
15
+        }
16
+    }
17
+    active = 0;
18
+}
19
+
7 20
 #endif  // MESH_BED_LEVELING

+ 3
- 11
Marlin/mesh_bed_leveling.h View File

@@ -7,20 +7,12 @@
7 7
 
8 8
 class mesh_bed_leveling {
9 9
 public:
10
-    
10
+    uint8_t active;
11 11
     float z_values[MESH_NUM_Y_POINTS][MESH_NUM_X_POINTS];
12 12
     
13
-    mesh_bed_leveling() {
14
-        reset();
15
-    }
13
+    mesh_bed_leveling();
16 14
     
17
-    void reset() {
18
-        for (int y=0; y<MESH_NUM_Y_POINTS; y++) {
19
-            for (int x=0; x<MESH_NUM_X_POINTS; x++) {
20
-                z_values[y][x] = 0;
21
-            }
22
-        }
23
-    }
15
+    void reset();
24 16
     
25 17
     float get_x(int i) { return MESH_MIN_X + MESH_X_DIST*i; }
26 18
     float get_y(int i) { return MESH_MIN_Y + MESH_Y_DIST*i; }

+ 6
- 2
Marlin/planner.cpp View File

@@ -553,7 +553,9 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
553 553
   }
554 554
 
555 555
 #if defined(MESH_BED_LEVELING)
556
-  z += mbl.get_z(x, y);
556
+  if (mbl.active) {
557
+    z += mbl.get_z(x, y);
558
+  }
557 559
 #endif  // MESH_BED_LEVELING
558 560
 
559 561
 #ifdef ENABLE_AUTO_BED_LEVELING
@@ -1095,7 +1097,9 @@ void plan_set_position(const float &x, const float &y, const float &z, const flo
1095 1097
 #if defined(ENABLE_AUTO_BED_LEVELING)
1096 1098
   apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
1097 1099
 #elif defined(MESH_BED_LEVELING)
1098
-  z += mbl.get_z(x, y);
1100
+  if (mbl.active) {
1101
+    z += mbl.get_z(x, y);
1102
+  }
1099 1103
 #endif  // ENABLE_AUTO_BED_LEVELING
1100 1104
 
1101 1105
   position[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]);

+ 88
- 1
Marlin/ultralcd.cpp View File

@@ -68,6 +68,13 @@ static void lcd_sdcard_menu();
68 68
 static void lcd_delta_calibrate_menu();
69 69
 #endif // DELTA_CALIBRATION_MENU
70 70
 
71
+#if defined(MANUAL_BED_LEVELING)
72
+#include "mesh_bed_leveling.h"
73
+static void _lcd_level_bed();
74
+static void _lcd_level_bed_homing();
75
+static void lcd_level_bed();
76
+#endif  // MANUAL_BED_LEVELING
77
+
71 78
 static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
72 79
 
73 80
 /* Different types of actions that can be used in menu items. */
@@ -615,6 +622,10 @@ static void lcd_prepare_menu() {
615 622
     }
616 623
   #endif
617 624
   MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu);
625
+
626
+  #if defined(MANUAL_BED_LEVELING)
627
+    MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed);
628
+  #endif
618 629
 	
619 630
   END_MENU();
620 631
 }
@@ -1326,7 +1337,12 @@ void lcd_update() {
1326 1337
     #endif
1327 1338
 
1328 1339
     #ifdef ULTIPANEL
1329
-      if (currentMenu != lcd_status_screen && millis() > timeoutToStatus) {
1340
+      if (currentMenu != lcd_status_screen &&
1341
+        #if defined(MANUAL_BED_LEVELING)
1342
+          currentMenu != _lcd_level_bed && 
1343
+          currentMenu != _lcd_level_bed_homing && 
1344
+        #endif  // MANUAL_BED_LEVELING
1345
+          millis() > timeoutToStatus) {
1330 1346
         lcd_return_to_status();
1331 1347
         lcdDrawUpdate = 2;
1332 1348
       }
@@ -1745,4 +1761,75 @@ char *ftostr52(const float &x)
1745 1761
   return conv;
1746 1762
 }
1747 1763
 
1764
+#if defined(MANUAL_BED_LEVELING)
1765
+static int _lcd_level_bed_position;
1766
+static void _lcd_level_bed()
1767
+{
1768
+  if (encoderPosition != 0) {
1769
+    refresh_cmd_timeout();
1770
+    current_position[Z_AXIS] += float((int)encoderPosition) * 0.05;
1771
+    if (min_software_endstops && current_position[Z_AXIS] < Z_MIN_POS) current_position[Z_AXIS] = Z_MIN_POS;
1772
+    if (max_software_endstops && current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
1773
+    encoderPosition = 0;
1774
+    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[Z_AXIS]/60, active_extruder);
1775
+    lcdDrawUpdate = 1;
1776
+  }
1777
+  if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR("Z"), ftostr32(current_position[Z_AXIS]));
1778
+  static bool debounce_click = false;
1779
+  if (LCD_CLICKED) {
1780
+    if (!debounce_click) {
1781
+      debounce_click = true;
1782
+      int ix = _lcd_level_bed_position % MESH_NUM_X_POINTS;
1783
+      int iy = _lcd_level_bed_position / MESH_NUM_X_POINTS;
1784
+      mbl.set_z(ix, iy, current_position[Z_AXIS]);
1785
+      _lcd_level_bed_position++;
1786
+      if (_lcd_level_bed_position == MESH_NUM_X_POINTS*MESH_NUM_Y_POINTS) {
1787
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1788
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[X_AXIS]/60, active_extruder);
1789
+        mbl.active = 1;
1790
+        enquecommands_P(PSTR("G28"));
1791
+        lcd_return_to_status();
1792
+      } else {
1793
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1794
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[X_AXIS]/60, active_extruder);
1795
+        ix = _lcd_level_bed_position % MESH_NUM_X_POINTS;
1796
+        iy = _lcd_level_bed_position / MESH_NUM_X_POINTS;
1797
+        if (iy&1) { // Zig zag
1798
+          ix = (MESH_NUM_X_POINTS - 1) - ix;
1799
+        }
1800
+        current_position[X_AXIS] = mbl.get_x(ix);
1801
+        current_position[Y_AXIS] = mbl.get_y(iy);
1802
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[X_AXIS]/60, active_extruder);
1803
+        lcdDrawUpdate = 1;
1804
+      }
1805
+    }
1806
+  } else {
1807
+    debounce_click = false;
1808
+  }
1809
+}
1810
+static void _lcd_level_bed_homing()
1811
+{
1812
+  if (axis_known_position[X_AXIS] &&
1813
+      axis_known_position[Y_AXIS] &&
1814
+      axis_known_position[Z_AXIS]) {
1815
+    current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1816
+    plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1817
+    current_position[X_AXIS] = MESH_MIN_X;
1818
+    current_position[Y_AXIS] = MESH_MIN_Y;
1819
+    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[X_AXIS]/60, active_extruder);
1820
+    _lcd_level_bed_position = 0;
1821
+    lcd_goto_menu(_lcd_level_bed);
1822
+  }
1823
+}
1824
+static void lcd_level_bed()
1825
+{
1826
+  axis_known_position[X_AXIS] = false;
1827
+  axis_known_position[Y_AXIS] = false;
1828
+  axis_known_position[Z_AXIS] = false;
1829
+  mbl.reset();
1830
+  enquecommands_P(PSTR("G28"));
1831
+  lcd_goto_menu(_lcd_level_bed_homing);
1832
+}
1833
+#endif  // MANUAL_BED_LEVELING
1834
+
1748 1835
 #endif //ULTRA_LCD

Loading…
Cancel
Save