Browse Source

Latest upstream commits, plus fixes

- Also add Manual Bed Leveling to the rest of the configs
Scott Lahteine 9 years ago
parent
commit
88e81a4804

+ 17
- 0
Marlin/Configuration.h View File

375
 //#define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined.
375
 //#define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined.
376
 
376
 
377
 //===========================================================================
377
 //===========================================================================
378
+//============================ Manual Bed Leveling ==========================
379
+//===========================================================================
380
+
381
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
382
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
383
+
384
+#if defined(MESH_BED_LEVELING)
385
+  #define MESH_MIN_X 10
386
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
387
+  #define MESH_MIN_Y 10
388
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
389
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
390
+  #define MESH_NUM_Y_POINTS 3
391
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
392
+#endif  // MESH_BED_LEVELING
393
+
394
+//===========================================================================
378
 //============================= Bed Auto Leveling ===========================
395
 //============================= Bed Auto Leveling ===========================
379
 //===========================================================================
396
 //===========================================================================
380
 
397
 

+ 63
- 2
Marlin/ConfigurationStore.cpp View File

20
  *  max_e_jerk
20
  *  max_e_jerk
21
  *  add_homing (x3)
21
  *  add_homing (x3)
22
  *
22
  *
23
+ * Mesh bed leveling:
24
+ *  active
25
+ *  mesh_num_x
26
+ *  mesh_num_y
27
+ *  z_values[][]
28
+ *
23
  * DELTA:
29
  * DELTA:
24
  *  endstop_adj (x3)
30
  *  endstop_adj (x3)
25
  *  delta_radius
31
  *  delta_radius
69
 #include "ultralcd.h"
75
 #include "ultralcd.h"
70
 #include "ConfigurationStore.h"
76
 #include "ConfigurationStore.h"
71
 
77
 
78
+#if defined(MESH_BED_LEVELING)
79
+   #include "mesh_bed_leveling.h"
80
+#endif  // MESH_BED_LEVELING
81
+
72
 void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) {
82
 void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) {
73
   uint8_t c;
83
   uint8_t c;
74
   while(size--) {
84
   while(size--) {
105
 // wrong data being written to the variables.
115
 // wrong data being written to the variables.
106
 // ALSO:  always make sure the variables in the Store and retrieve sections are in the same order.
116
 // ALSO:  always make sure the variables in the Store and retrieve sections are in the same order.
107
 
117
 
108
-#define EEPROM_VERSION "V16"
118
+#define EEPROM_VERSION "V17"
109
 
119
 
110
 #ifdef EEPROM_SETTINGS
120
 #ifdef EEPROM_SETTINGS
111
 
121
 
128
   EEPROM_WRITE_VAR(i, max_e_jerk);
138
   EEPROM_WRITE_VAR(i, max_e_jerk);
129
   EEPROM_WRITE_VAR(i, add_homing);
139
   EEPROM_WRITE_VAR(i, add_homing);
130
 
140
 
141
+  uint8_t mesh_num_x = 3;
142
+  uint8_t mesh_num_y = 3;
143
+  #if defined(MESH_BED_LEVELING)
144
+    // Compile time test that sizeof(mbl.z_values) is as expected
145
+    typedef char c_assert[(sizeof(mbl.z_values) == MESH_NUM_X_POINTS*MESH_NUM_Y_POINTS*sizeof(dummy)) ? 1 : -1];
146
+    mesh_num_x = MESH_NUM_X_POINTS;
147
+    mesh_num_y = MESH_NUM_Y_POINTS;
148
+    EEPROM_WRITE_VAR(i, mbl.active);
149
+    EEPROM_WRITE_VAR(i, mesh_num_x);
150
+    EEPROM_WRITE_VAR(i, mesh_num_y);
151
+    EEPROM_WRITE_VAR(i, mbl.z_values);
152
+  #else
153
+    uint8_t dummy_uint8 = 0;
154
+    EEPROM_WRITE_VAR(i, dummy_uint8);
155
+    EEPROM_WRITE_VAR(i, mesh_num_x);
156
+    EEPROM_WRITE_VAR(i, mesh_num_y);
157
+    dummy = 0.0f;
158
+    for (int q=0; q<mesh_num_x*mesh_num_y; q++) {
159
+      EEPROM_WRITE_VAR(i, dummy);
160
+    }
161
+  #endif  // MESH_BED_LEVELING
162
+
131
   #ifdef DELTA
163
   #ifdef DELTA
132
     EEPROM_WRITE_VAR(i, endstop_adj);               // 3 floats
164
     EEPROM_WRITE_VAR(i, endstop_adj);               // 3 floats
133
     EEPROM_WRITE_VAR(i, delta_radius);              // 1 float
165
     EEPROM_WRITE_VAR(i, delta_radius);              // 1 float
250
     EEPROM_READ_VAR(i, max_feedrate);
282
     EEPROM_READ_VAR(i, max_feedrate);
251
     EEPROM_READ_VAR(i, max_acceleration_units_per_sq_second);
283
     EEPROM_READ_VAR(i, max_acceleration_units_per_sq_second);
252
 
284
 
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)
285
+    // 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
     reset_acceleration_rates();
286
     reset_acceleration_rates();
255
 
287
 
256
     EEPROM_READ_VAR(i, acceleration);
288
     EEPROM_READ_VAR(i, acceleration);
264
     EEPROM_READ_VAR(i, max_e_jerk);
296
     EEPROM_READ_VAR(i, max_e_jerk);
265
     EEPROM_READ_VAR(i, add_homing);
297
     EEPROM_READ_VAR(i, add_homing);
266
 
298
 
299
+    uint8_t mesh_num_x = 0;
300
+    uint8_t mesh_num_y = 0;
301
+    #if defined(MESH_BED_LEVELING)
302
+      EEPROM_READ_VAR(i, mbl.active);
303
+      EEPROM_READ_VAR(i, mesh_num_x);
304
+      EEPROM_READ_VAR(i, mesh_num_y);
305
+      if (mesh_num_x != MESH_NUM_X_POINTS ||
306
+          mesh_num_y != MESH_NUM_Y_POINTS) {
307
+        mbl.reset();
308
+        for (int q=0; q<mesh_num_x*mesh_num_y; q++) {
309
+          EEPROM_READ_VAR(i, dummy);
310
+        }
311
+      } else {
312
+        EEPROM_READ_VAR(i, mbl.z_values);
313
+      }
314
+    #else
315
+      uint8_t dummy_uint8 = 0;
316
+      EEPROM_READ_VAR(i, dummy_uint8);
317
+      EEPROM_READ_VAR(i, mesh_num_x);
318
+      EEPROM_READ_VAR(i, mesh_num_y);
319
+      for (int q=0; q<mesh_num_x*mesh_num_y; q++) {
320
+        EEPROM_READ_VAR(i, dummy);
321
+      }
322
+    #endif  // MESH_BED_LEVELING
323
+
267
     #ifdef DELTA
324
     #ifdef DELTA
268
       EEPROM_READ_VAR(i, endstop_adj);                // 3 floats
325
       EEPROM_READ_VAR(i, endstop_adj);                // 3 floats
269
       EEPROM_READ_VAR(i, delta_radius);               // 1 float
326
       EEPROM_READ_VAR(i, delta_radius);               // 1 float
392
   max_e_jerk = DEFAULT_EJERK;
449
   max_e_jerk = DEFAULT_EJERK;
393
   add_homing[X_AXIS] = add_homing[Y_AXIS] = add_homing[Z_AXIS] = 0;
450
   add_homing[X_AXIS] = add_homing[Y_AXIS] = add_homing[Z_AXIS] = 0;
394
 
451
 
452
+  #if defined(MESH_BED_LEVELING)
453
+    mbl.active = 0;
454
+  #endif  // MESH_BED_LEVELING
455
+
395
   #ifdef DELTA
456
   #ifdef DELTA
396
     endstop_adj[X_AXIS] = endstop_adj[Y_AXIS] = endstop_adj[Z_AXIS] = 0;
457
     endstop_adj[X_AXIS] = endstop_adj[Y_AXIS] = endstop_adj[Z_AXIS] = 0;
397
     delta_radius =  DELTA_RADIUS;
458
     delta_radius =  DELTA_RADIUS;

+ 201
- 6
Marlin/Marlin_main.cpp View File

41
 
41
 
42
 #define SERVO_LEVELING defined(ENABLE_AUTO_BED_LEVELING) && PROBE_SERVO_DEACTIVATION_DELAY > 0
42
 #define SERVO_LEVELING defined(ENABLE_AUTO_BED_LEVELING) && PROBE_SERVO_DEACTIVATION_DELAY > 0
43
 
43
 
44
+#if defined(MESH_BED_LEVELING)
45
+  #include "mesh_bed_leveling.h"
46
+#endif  // MESH_BED_LEVELING
47
+
44
 #include "ultralcd.h"
48
 #include "ultralcd.h"
45
 #include "planner.h"
49
 #include "planner.h"
46
 #include "stepper.h"
50
 #include "stepper.h"
1737
     #endif
1741
     #endif
1738
   #endif
1742
   #endif
1739
 
1743
 
1744
+  #if defined(MESH_BED_LEVELING)
1745
+    uint8_t mbl_was_active = mbl.active;
1746
+    mbl.active = 0;
1747
+  #endif  // MESH_BED_LEVELING
1748
+
1740
   saved_feedrate = feedrate;
1749
   saved_feedrate = feedrate;
1741
   saved_feedmultiply = feedmultiply;
1750
   saved_feedmultiply = feedmultiply;
1742
   feedmultiply = 100;
1751
   feedmultiply = 100;
1951
     enable_endstops(false);
1960
     enable_endstops(false);
1952
   #endif
1961
   #endif
1953
 
1962
 
1963
+  #if defined(MESH_BED_LEVELING)
1964
+    if (mbl_was_active) {
1965
+      current_position[X_AXIS] = mbl.get_x(0);
1966
+      current_position[Y_AXIS] = mbl.get_y(0);
1967
+      destination[X_AXIS] = current_position[X_AXIS];
1968
+      destination[Y_AXIS] = current_position[Y_AXIS];
1969
+      destination[Z_AXIS] = current_position[Z_AXIS];
1970
+      destination[E_AXIS] = current_position[E_AXIS];
1971
+      feedrate = homing_feedrate[X_AXIS];
1972
+      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
1973
+      st_synchronize();
1974
+      current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1975
+      plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1976
+      mbl.active = 1;
1977
+    }
1978
+  #endif
1979
+
1954
   feedrate = saved_feedrate;
1980
   feedrate = saved_feedrate;
1955
   feedmultiply = saved_feedmultiply;
1981
   feedmultiply = saved_feedmultiply;
1956
   previous_millis_cmd = millis();
1982
   previous_millis_cmd = millis();
1957
   endstops_hit_on_purpose();
1983
   endstops_hit_on_purpose();
1958
 }
1984
 }
1959
 
1985
 
1986
+#if defined(MESH_BED_LEVELING)
1987
+
1988
+  inline void gcode_G29() {
1989
+    static int probe_point = -1;
1990
+    int state = 0;
1991
+    if (code_seen('S') || code_seen('s')) {
1992
+      state = code_value_long();
1993
+      if (state < 0 || state > 2) {
1994
+        SERIAL_PROTOCOLPGM("S out of range (0-2).\n");
1995
+        return;
1996
+      }
1997
+    }
1998
+
1999
+    if (state == 0) { // Dump mesh_bed_leveling
2000
+      if (mbl.active) {
2001
+        SERIAL_PROTOCOLPGM("Num X,Y: ");
2002
+        SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
2003
+        SERIAL_PROTOCOLPGM(",");
2004
+        SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
2005
+        SERIAL_PROTOCOLPGM("\nZ search height: ");
2006
+        SERIAL_PROTOCOL(MESH_HOME_SEARCH_Z);
2007
+        SERIAL_PROTOCOLPGM("\nMeasured points:\n");              
2008
+        for (int y=0; y<MESH_NUM_Y_POINTS; y++) {
2009
+          for (int x=0; x<MESH_NUM_X_POINTS; x++) {
2010
+            SERIAL_PROTOCOLPGM("  ");              
2011
+            SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5);
2012
+          }
2013
+          SERIAL_EOL;
2014
+        }
2015
+      } else {
2016
+        SERIAL_PROTOCOLPGM("Mesh bed leveling not active.\n");
2017
+      }
2018
+
2019
+    } else if (state == 1) { // Begin probing mesh points
2020
+
2021
+      mbl.reset();
2022
+      probe_point = 0;
2023
+      enquecommands_P(PSTR("G28"));
2024
+      enquecommands_P(PSTR("G29 S2"));
2025
+
2026
+    } else if (state == 2) { // Goto next point
2027
+
2028
+      if (probe_point < 0) {
2029
+        SERIAL_PROTOCOLPGM("Mesh probing not started.\n");
2030
+        return;
2031
+      }
2032
+      int ix, iy;
2033
+      if (probe_point == 0) {
2034
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
2035
+        plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2036
+      } else {
2037
+        ix = (probe_point-1) % MESH_NUM_X_POINTS;
2038
+        iy = (probe_point-1) / MESH_NUM_X_POINTS;
2039
+        if (iy&1) { // Zig zag
2040
+          ix = (MESH_NUM_X_POINTS - 1) - ix;
2041
+        }
2042
+        mbl.set_z(ix, iy, current_position[Z_AXIS]);
2043
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
2044
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/60, active_extruder);
2045
+        st_synchronize();
2046
+      }
2047
+      if (probe_point == MESH_NUM_X_POINTS*MESH_NUM_Y_POINTS) {
2048
+        SERIAL_PROTOCOLPGM("Mesh done.\n");
2049
+        probe_point = -1;
2050
+        mbl.active = 1;
2051
+        enquecommands_P(PSTR("G28"));
2052
+        return;
2053
+      }
2054
+      ix = probe_point % MESH_NUM_X_POINTS;
2055
+      iy = probe_point / MESH_NUM_X_POINTS;
2056
+      if (iy&1) { // Zig zag
2057
+        ix = (MESH_NUM_X_POINTS - 1) - ix;
2058
+      }
2059
+      current_position[X_AXIS] = mbl.get_x(ix);
2060
+      current_position[Y_AXIS] = mbl.get_y(iy);
2061
+      plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/60, active_extruder);
2062
+      st_synchronize();
2063
+      probe_point++;
2064
+    }
2065
+  }
2066
+
2067
+#endif
2068
+
1960
 #ifdef ENABLE_AUTO_BED_LEVELING
2069
 #ifdef ENABLE_AUTO_BED_LEVELING
1961
 
2070
 
1962
   // Define the possible boundaries for probing based on set limits
2071
   // Define the possible boundaries for probing based on set limits
2118
 
2227
 
2119
     st_synchronize();
2228
     st_synchronize();
2120
 
2229
 
2121
-  #ifdef DELTA
2122
-    reset_bed_level();
2123
-  #else
2230
+    #ifdef DELTA
2231
+      reset_bed_level();
2232
+    #else
2233
+
2124
     // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
2234
     // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
2125
     //vector_3 corrected_position = plan_get_position_mm();
2235
     //vector_3 corrected_position = plan_get_position_mm();
2126
     //corrected_position.debug("position before G29");
2236
     //corrected_position.debug("position before G29");
4661
       gcode_G28();
4771
       gcode_G28();
4662
       break;
4772
       break;
4663
 
4773
 
4774
+    #if defined(MESH_BED_LEVELING)
4775
+      case 29: // G29 Handle mesh based leveling
4776
+        gcode_G29();
4777
+        break;
4778
+    #endif
4779
+
4664
     #ifdef ENABLE_AUTO_BED_LEVELING
4780
     #ifdef ENABLE_AUTO_BED_LEVELING
4665
 
4781
 
4666
       case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
4782
       case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
5280
 }
5396
 }
5281
 #endif //DELTA
5397
 #endif //DELTA
5282
 
5398
 
5399
+#if defined(MESH_BED_LEVELING)
5400
+#if !defined(MIN)
5401
+#define MIN(_v1, _v2) (((_v1) < (_v2)) ? (_v1) : (_v2))
5402
+#endif  // ! MIN
5403
+// This function is used to split lines on mesh borders so each segment is only part of one mesh area
5404
+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)
5405
+{
5406
+  if (!mbl.active) {
5407
+    plan_buffer_line(x, y, z, e, feed_rate, extruder);
5408
+    for(int8_t i=0; i < NUM_AXIS; i++) {
5409
+      current_position[i] = destination[i];
5410
+    }
5411
+    return;
5412
+  }
5413
+  int pix = mbl.select_x_index(current_position[X_AXIS]);
5414
+  int piy = mbl.select_y_index(current_position[Y_AXIS]);
5415
+  int ix = mbl.select_x_index(x);
5416
+  int iy = mbl.select_y_index(y);
5417
+  pix = MIN(pix, MESH_NUM_X_POINTS-2);
5418
+  piy = MIN(piy, MESH_NUM_Y_POINTS-2);
5419
+  ix = MIN(ix, MESH_NUM_X_POINTS-2);
5420
+  iy = MIN(iy, MESH_NUM_Y_POINTS-2);
5421
+  if (pix == ix && piy == iy) {
5422
+    // Start and end on same mesh square
5423
+    plan_buffer_line(x, y, z, e, feed_rate, extruder);
5424
+    for(int8_t i=0; i < NUM_AXIS; i++) {
5425
+      current_position[i] = destination[i];
5426
+    }
5427
+    return;
5428
+  }
5429
+  float nx, ny, ne, normalized_dist;
5430
+  if (ix > pix && (x_splits) & BIT(ix)) {
5431
+    nx = mbl.get_x(ix);
5432
+    normalized_dist = (nx - current_position[X_AXIS])/(x - current_position[X_AXIS]);
5433
+    ny = current_position[Y_AXIS] + (y - current_position[Y_AXIS]) * normalized_dist;
5434
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5435
+    x_splits ^= BIT(ix);
5436
+  } else if (ix < pix && (x_splits) & BIT(pix)) {
5437
+    nx = mbl.get_x(pix);
5438
+    normalized_dist = (nx - current_position[X_AXIS])/(x - current_position[X_AXIS]);
5439
+    ny = current_position[Y_AXIS] + (y - current_position[Y_AXIS]) * normalized_dist;
5440
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5441
+    x_splits ^= BIT(pix);
5442
+  } else if (iy > piy && (y_splits) & BIT(iy)) {
5443
+    ny = mbl.get_y(iy);
5444
+    normalized_dist = (ny - current_position[Y_AXIS])/(y - current_position[Y_AXIS]);
5445
+    nx = current_position[X_AXIS] + (x - current_position[X_AXIS]) * normalized_dist;
5446
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5447
+    y_splits ^= BIT(iy);
5448
+  } else if (iy < piy && (y_splits) & BIT(piy)) {
5449
+    ny = mbl.get_y(piy);
5450
+    normalized_dist = (ny - current_position[Y_AXIS])/(y - current_position[Y_AXIS]);
5451
+    nx = current_position[X_AXIS] + (x - current_position[X_AXIS]) * normalized_dist;
5452
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5453
+    y_splits ^= BIT(piy);
5454
+  } else {
5455
+    // Already split on a border
5456
+    plan_buffer_line(x, y, z, e, feed_rate, extruder);
5457
+    for(int8_t i=0; i < NUM_AXIS; i++) {
5458
+      current_position[i] = destination[i];
5459
+    }
5460
+    return;
5461
+  }
5462
+  // Do the split and look for more borders
5463
+  destination[X_AXIS] = nx;
5464
+  destination[Y_AXIS] = ny;
5465
+  destination[E_AXIS] = ne;
5466
+  mesh_plan_buffer_line(nx, ny, z, ne, feed_rate, extruder, x_splits, y_splits);
5467
+  destination[X_AXIS] = x;
5468
+  destination[Y_AXIS] = y;
5469
+  destination[E_AXIS] = e;
5470
+  mesh_plan_buffer_line(x, y, z, e, feed_rate, extruder, x_splits, y_splits);
5471
+}
5472
+#endif  // MESH_BED_LEVELING
5473
+
5283
 void prepare_move()
5474
 void prepare_move()
5284
 {
5475
 {
5285
   clamp_to_software_endstops(destination);
5476
   clamp_to_software_endstops(destination);
5395
 #if ! (defined DELTA || defined SCARA)
5586
 #if ! (defined DELTA || defined SCARA)
5396
   // Do not use feedmultiply for E or Z only moves
5587
   // Do not use feedmultiply for E or Z only moves
5397
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
5588
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
5398
-      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
5399
-  }
5400
-  else {
5589
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
5590
+  } else {
5591
+#if defined(MESH_BED_LEVELING)
5592
+    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
5593
+    return;
5594
+#else
5401
     plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
5595
     plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
5596
+#endif  // MESH_BED_LEVELING
5402
   }
5597
   }
5403
 #endif // !(DELTA || SCARA)
5598
 #endif // !(DELTA || SCARA)
5404
 
5599
 

+ 17
- 0
Marlin/configurator/config/Configuration.h View File

413
 
413
 
414
 
414
 
415
 //===========================================================================
415
 //===========================================================================
416
+//============================ Manual Bed Leveling ==========================
417
+//===========================================================================
418
+
419
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
420
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
421
+
422
+#if defined(MESH_BED_LEVELING)
423
+  #define MESH_MIN_X 10
424
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
425
+  #define MESH_MIN_Y 10
426
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
427
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
428
+  #define MESH_NUM_Y_POINTS 3
429
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
430
+#endif  // MESH_BED_LEVELING
431
+
432
+//===========================================================================
416
 //============================= Bed Auto Leveling ===========================
433
 //============================= Bed Auto Leveling ===========================
417
 //===========================================================================
434
 //===========================================================================
418
 
435
 

+ 17
- 0
Marlin/example_configurations/Felix/Configuration.h View File

359
 
359
 
360
 
360
 
361
 //===========================================================================
361
 //===========================================================================
362
+//============================ Manual Bed Leveling ==========================
363
+//===========================================================================
364
+
365
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
366
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
367
+
368
+#if defined(MESH_BED_LEVELING)
369
+  #define MESH_MIN_X 10
370
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
371
+  #define MESH_MIN_Y 10
372
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
373
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
374
+  #define MESH_NUM_Y_POINTS 3
375
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
376
+#endif  // MESH_BED_LEVELING
377
+
378
+//===========================================================================
362
 //============================= Bed Auto Leveling ===========================
379
 //============================= Bed Auto Leveling ===========================
363
 //===========================================================================
380
 //===========================================================================
364
 
381
 

+ 17
- 0
Marlin/example_configurations/Felix/Configuration_DUAL.h View File

359
 
359
 
360
 
360
 
361
 //===========================================================================
361
 //===========================================================================
362
+//============================ Manual Bed Leveling ==========================
363
+//===========================================================================
364
+
365
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
366
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
367
+
368
+#if defined(MESH_BED_LEVELING)
369
+  #define MESH_MIN_X 10
370
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
371
+  #define MESH_MIN_Y 10
372
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
373
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
374
+  #define MESH_NUM_Y_POINTS 3
375
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
376
+#endif  // MESH_BED_LEVELING
377
+
378
+//===========================================================================
362
 //============================= Bed Auto Leveling ===========================
379
 //============================= Bed Auto Leveling ===========================
363
 //===========================================================================
380
 //===========================================================================
364
 
381
 

+ 17
- 0
Marlin/example_configurations/Hephestos/Configuration.h View File

385
 
385
 
386
 
386
 
387
 //===========================================================================
387
 //===========================================================================
388
+//============================ Manual Bed Leveling ==========================
389
+//===========================================================================
390
+
391
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
392
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
393
+
394
+#if defined(MESH_BED_LEVELING)
395
+  #define MESH_MIN_X 10
396
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
397
+  #define MESH_MIN_Y 10
398
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
399
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
400
+  #define MESH_NUM_Y_POINTS 3
401
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
402
+#endif  // MESH_BED_LEVELING
403
+
404
+//===========================================================================
388
 //============================= Bed Auto Leveling ===========================
405
 //============================= Bed Auto Leveling ===========================
389
 //===========================================================================
406
 //===========================================================================
390
 
407
 

+ 17
- 0
Marlin/example_configurations/K8200/Configuration.h View File

390
 
390
 
391
 
391
 
392
 //===========================================================================
392
 //===========================================================================
393
+//============================ Manual Bed Leveling ==========================
394
+//===========================================================================
395
+
396
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
397
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
398
+
399
+#if defined(MESH_BED_LEVELING)
400
+  #define MESH_MIN_X 10
401
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
402
+  #define MESH_MIN_Y 10
403
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
404
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
405
+  #define MESH_NUM_Y_POINTS 3
406
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
407
+#endif  // MESH_BED_LEVELING
408
+
409
+//===========================================================================
393
 //============================= Bed Auto Leveling ===========================
410
 //============================= Bed Auto Leveling ===========================
394
 //===========================================================================
411
 //===========================================================================
395
 
412
 

+ 17
- 0
Marlin/example_configurations/SCARA/Configuration.h View File

414
 
414
 
415
 
415
 
416
 //===========================================================================
416
 //===========================================================================
417
+//============================ Manual Bed Leveling ==========================
418
+//===========================================================================
419
+
420
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
421
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
422
+
423
+#if defined(MESH_BED_LEVELING)
424
+  #define MESH_MIN_X 10
425
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
426
+  #define MESH_MIN_Y 10
427
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
428
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
429
+  #define MESH_NUM_Y_POINTS 3
430
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
431
+#endif  // MESH_BED_LEVELING
432
+
433
+//===========================================================================
417
 //============================= Bed Auto Leveling ===========================
434
 //============================= Bed Auto Leveling ===========================
418
 //===========================================================================
435
 //===========================================================================
419
 
436
 

+ 17
- 0
Marlin/example_configurations/WITBOX/Configuration.h View File

384
 
384
 
385
 
385
 
386
 //===========================================================================
386
 //===========================================================================
387
+//============================ Manual Bed Leveling ==========================
388
+//===========================================================================
389
+
390
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
391
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
392
+
393
+#if defined(MESH_BED_LEVELING)
394
+  #define MESH_MIN_X 10
395
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
396
+  #define MESH_MIN_Y 10
397
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
398
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
399
+  #define MESH_NUM_Y_POINTS 3
400
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
401
+#endif  // MESH_BED_LEVELING
402
+
403
+//===========================================================================
387
 //============================= Bed Auto Leveling ===========================
404
 //============================= Bed Auto Leveling ===========================
388
 //===========================================================================
405
 //===========================================================================
389
 
406
 

+ 17
- 0
Marlin/example_configurations/delta/generic/Configuration.h View File

414
 
414
 
415
 
415
 
416
 //===========================================================================
416
 //===========================================================================
417
+//============================ Manual Bed Leveling ==========================
418
+//===========================================================================
419
+
420
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
421
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
422
+
423
+#if defined(MESH_BED_LEVELING)
424
+  #define MESH_MIN_X 10
425
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
426
+  #define MESH_MIN_Y 10
427
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
428
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
429
+  #define MESH_NUM_Y_POINTS 3
430
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
431
+#endif  // MESH_BED_LEVELING
432
+
433
+//===========================================================================
417
 //============================= Bed Auto Leveling ===========================
434
 //============================= Bed Auto Leveling ===========================
418
 //===========================================================================
435
 //===========================================================================
419
 
436
 

+ 17
- 0
Marlin/example_configurations/delta/kossel_mini/Configuration.h View File

415
 
415
 
416
 
416
 
417
 //===========================================================================
417
 //===========================================================================
418
+//============================ Manual Bed Leveling ==========================
419
+//===========================================================================
420
+
421
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
422
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
423
+
424
+#if defined(MESH_BED_LEVELING)
425
+  #define MESH_MIN_X 10
426
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
427
+  #define MESH_MIN_Y 10
428
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
429
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
430
+  #define MESH_NUM_Y_POINTS 3
431
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
432
+#endif  // MESH_BED_LEVELING
433
+
434
+//===========================================================================
418
 //============================= Bed Auto Leveling ===========================
435
 //============================= Bed Auto Leveling ===========================
419
 //===========================================================================
436
 //===========================================================================
420
 
437
 

+ 17
- 0
Marlin/example_configurations/makibox/Configuration.h View File

382
 
382
 
383
 
383
 
384
 //===========================================================================
384
 //===========================================================================
385
+//============================ Manual Bed Leveling ==========================
386
+//===========================================================================
387
+
388
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
389
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
390
+
391
+#if defined(MESH_BED_LEVELING)
392
+  #define MESH_MIN_X 10
393
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
394
+  #define MESH_MIN_Y 10
395
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
396
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
397
+  #define MESH_NUM_Y_POINTS 3
398
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
399
+#endif  // MESH_BED_LEVELING
400
+
401
+//===========================================================================
385
 //============================= Bed Auto Leveling ===========================
402
 //============================= Bed Auto Leveling ===========================
386
 //===========================================================================
403
 //===========================================================================
387
 
404
 

+ 17
- 0
Marlin/example_configurations/tvrrug/Round2/Configuration.h View File

384
 
384
 
385
 
385
 
386
 //===========================================================================
386
 //===========================================================================
387
+//============================ Manual Bed Leveling ==========================
388
+//===========================================================================
389
+
390
+// #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
391
+// #define MESH_BED_LEVELING    // Enable mesh bed leveling
392
+
393
+#if defined(MESH_BED_LEVELING)
394
+  #define MESH_MIN_X 10
395
+  #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
396
+  #define MESH_MIN_Y 10
397
+  #define MESH_MAX_Y (Y_MAX_POS - MESH_MIN_Y)
398
+  #define MESH_NUM_X_POINTS 3  // Don't use more than 7 points per axis, implementation limited
399
+  #define MESH_NUM_Y_POINTS 3
400
+  #define MESH_HOME_SEARCH_Z 4  // Z after Home, bed somewhere below but above 0.0
401
+#endif  // MESH_BED_LEVELING
402
+
403
+//===========================================================================
387
 //============================= Bed Auto Leveling ===========================
404
 //============================= Bed Auto Leveling ===========================
388
 //===========================================================================
405
 //===========================================================================
389
 
406
 

+ 3
- 0
Marlin/language_en.h View File

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

+ 20
- 0
Marlin/mesh_bed_leveling.cpp View File

1
+#include "mesh_bed_leveling.h"
2
+
3
+#if defined(MESH_BED_LEVELING)
4
+
5
+mesh_bed_leveling mbl;
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
+
20
+#endif  // MESH_BED_LEVELING

+ 61
- 0
Marlin/mesh_bed_leveling.h View File

1
+#include "Marlin.h"
2
+
3
+#if defined(MESH_BED_LEVELING)
4
+
5
+#define MESH_X_DIST ((MESH_MAX_X - MESH_MIN_X)/(MESH_NUM_X_POINTS - 1))
6
+#define MESH_Y_DIST ((MESH_MAX_Y - MESH_MIN_Y)/(MESH_NUM_Y_POINTS - 1))
7
+
8
+class mesh_bed_leveling {
9
+public:
10
+    uint8_t active;
11
+    float z_values[MESH_NUM_Y_POINTS][MESH_NUM_X_POINTS];
12
+    
13
+    mesh_bed_leveling();
14
+    
15
+    void reset();
16
+    
17
+    float get_x(int i) { return MESH_MIN_X + MESH_X_DIST*i; }
18
+    float get_y(int i) { return MESH_MIN_Y + MESH_Y_DIST*i; }
19
+    void set_z(int ix, int iy, float z) { z_values[iy][ix] = z; }
20
+    
21
+    int select_x_index(float x) {
22
+        int i = 1;
23
+        while (x > get_x(i) && i < MESH_NUM_X_POINTS-1) {
24
+            i++;
25
+        }
26
+        return i-1;
27
+    }
28
+    
29
+    int select_y_index(float y) {
30
+        int i = 1;
31
+        while (y > get_y(i) && i < MESH_NUM_Y_POINTS-1) {
32
+            i++;
33
+        }
34
+        return i-1;
35
+    }
36
+    
37
+    float calc_z0(float a0, float a1, float z1, float a2, float z2) {
38
+        float delta_z = (z2 - z1)/(a2 - a1);
39
+        float delta_a = a0 - a1;
40
+        return z1 + delta_a * delta_z;
41
+    }
42
+    
43
+    float get_z(float x0, float y0) {
44
+        int x_index = select_x_index(x0);
45
+        int y_index = select_y_index(y0);
46
+        float z1 = calc_z0(x0,
47
+                           get_x(x_index), z_values[y_index][x_index],
48
+                           get_x(x_index+1), z_values[y_index][x_index+1]);
49
+        float z2 = calc_z0(x0,
50
+                           get_x(x_index), z_values[y_index+1][x_index],
51
+                           get_x(x_index+1), z_values[y_index+1][x_index+1]);
52
+        float z0 = calc_z0(y0,
53
+                           get_y(y_index), z1,
54
+                           get_y(y_index+1), z2);
55
+        return z0;
56
+    }
57
+};
58
+
59
+extern mesh_bed_leveling mbl;
60
+
61
+#endif  // MESH_BED_LEVELING

+ 25
- 16
Marlin/planner.cpp View File

58
 #include "ultralcd.h"
58
 #include "ultralcd.h"
59
 #include "language.h"
59
 #include "language.h"
60
 
60
 
61
+#if defined(MESH_BED_LEVELING)
62
+  #include "mesh_bed_leveling.h"
63
+#endif  // MESH_BED_LEVELING
64
+
61
 //===========================================================================
65
 //===========================================================================
62
 //============================= public variables ============================
66
 //============================= public variables ============================
63
 //===========================================================================
67
 //===========================================================================
464
 // Add a new linear movement to the buffer. steps[X_AXIS], _y and _z is the absolute position in 
468
 // Add a new linear movement to the buffer. steps[X_AXIS], _y and _z is the absolute position in 
465
 // mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
469
 // mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
466
 // calculation the caller must also provide the physical length of the line in millimeters.
470
 // calculation the caller must also provide the physical length of the line in millimeters.
467
-#ifdef ENABLE_AUTO_BED_LEVELING
471
+#if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
468
   void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder)
472
   void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder)
469
 #else
473
 #else
470
   void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder)
474
   void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder)
481
     lcd_update();
485
     lcd_update();
482
   }
486
   }
483
 
487
 
488
+  #ifdef MESH_BED_LEVELING
489
+    if (mbl.active) z += mbl.get_z(x, y);
490
+  #endif
491
+
484
   #ifdef ENABLE_AUTO_BED_LEVELING
492
   #ifdef ENABLE_AUTO_BED_LEVELING
485
     apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
493
     apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
486
   #endif
494
   #endif
948
 
956
 
949
 } // plan_buffer_line()
957
 } // plan_buffer_line()
950
 
958
 
951
-#ifdef ENABLE_AUTO_BED_LEVELING
952
-
953
-  #ifndef DELTA
954
-    vector_3 plan_get_position() {
955
-      vector_3 position = vector_3(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS), st_get_position_mm(Z_AXIS));
959
+#if defined(ENABLE_AUTO_BED_LEVELING) && !defined(DELTA)
960
+  vector_3 plan_get_position() {
961
+    vector_3 position = vector_3(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS), st_get_position_mm(Z_AXIS));
956
 
962
 
957
-      //position.debug("in plan_get position");
958
-      //plan_bed_level_matrix.debug("in plan_get bed_level");
959
-      matrix_3x3 inverse = matrix_3x3::transpose(plan_bed_level_matrix);
960
-      //inverse.debug("in plan_get inverse");
961
-      position.apply_rotation(inverse);
962
-      //position.debug("after rotation");
963
+    //position.debug("in plan_get position");
964
+    //plan_bed_level_matrix.debug("in plan_get bed_level");
965
+    matrix_3x3 inverse = matrix_3x3::transpose(plan_bed_level_matrix);
966
+    //inverse.debug("in plan_get inverse");
967
+    position.apply_rotation(inverse);
968
+    //position.debug("after rotation");
963
 
969
 
964
-      return position;
965
-    }
966
-  #endif //!DELTA
970
+    return position;
971
+  }
972
+#endif // ENABLE_AUTO_BED_LEVELING && !DELTA
967
 
973
 
974
+#if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
968
   void plan_set_position(float x, float y, float z, const float &e)
975
   void plan_set_position(float x, float y, float z, const float &e)
969
 #else
976
 #else
970
   void plan_set_position(const float &x, const float &y, const float &z, const float &e)
977
   void plan_set_position(const float &x, const float &y, const float &z, const float &e)
971
-#endif // ENABLE_AUTO_BED_LEVELING
978
+#endif // ENABLE_AUTO_BED_LEVELING || MESH_BED_LEVELING
972
   {
979
   {
973
     #ifdef ENABLE_AUTO_BED_LEVELING
980
     #ifdef ENABLE_AUTO_BED_LEVELING
974
       apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
981
       apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
982
+    #elif defined(MESH_BED_LEVELING)
983
+      if (mbl.active) z += mbl.get_z(x, y);
975
     #endif
984
     #endif
976
 
985
 
977
     float nx = position[X_AXIS] = lround(x * axis_steps_per_unit[X_AXIS]);
986
     float nx = position[X_AXIS] = lround(x * axis_steps_per_unit[X_AXIS]);

+ 11
- 11
Marlin/planner.h View File

79
 extern volatile unsigned char block_buffer_tail;
79
 extern volatile unsigned char block_buffer_tail;
80
 FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
80
 FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
81
 
81
 
82
-#ifdef ENABLE_AUTO_BED_LEVELING
83
-  #include "vector_3.h"
84
-  // this holds the required transform to compensate for bed level
85
-  extern matrix_3x3 plan_bed_level_matrix;
82
+#if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
83
+  #if defined(ENABLE_AUTO_BED_LEVELING)
84
+    #include "vector_3.h"
85
+    // this holds the required transform to compensate for bed level
86
+    extern matrix_3x3 plan_bed_level_matrix;
87
+    // Get the position applying the bed level matrix if enabled
88
+    vector_3 plan_get_position();
89
+  #endif  // ENABLE_AUTO_BED_LEVELING
86
   // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in 
90
   // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in 
87
-  // millimaters. Feed rate specifies the speed of the motion.
91
+  // millimeters. Feed rate specifies the speed of the motion.
88
   void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder);
92
   void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder);
89
   // Set position. Used for G92 instructions.
93
   // Set position. Used for G92 instructions.
90
   void plan_set_position(float x, float y, float z, const float &e);
94
   void plan_set_position(float x, float y, float z, const float &e);
91
-  #ifndef DELTA
92
-    // Get the position applying the bed level matrix if enabled
93
-    vector_3 plan_get_position();
94
-  #endif
95
-#else //!ENABLE_AUTO_BED_LEVELING
95
+#else
96
   void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
96
   void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
97
   void plan_set_position(const float &x, const float &y, const float &z, const float &e);
97
   void plan_set_position(const float &x, const float &y, const float &z, const float &e);
98
-#endif //!ENABLE_AUTO_BED_LEVELING
98
+#endif // ENABLE_AUTO_BED_LEVELING || MESH_BED_LEVELING
99
 
99
 
100
 void plan_set_e_position(const float &e);
100
 void plan_set_e_position(const float &e);
101
 
101
 

+ 67
- 34
Marlin/temperature.cpp View File

145
   static float temp_iState_min_bed;
145
   static float temp_iState_min_bed;
146
   static float temp_iState_max_bed;
146
   static float temp_iState_max_bed;
147
 #else //PIDTEMPBED
147
 #else //PIDTEMPBED
148
-	static unsigned long  previous_millis_bed_heater;
148
+  static unsigned long  previous_millis_bed_heater;
149
 #endif //PIDTEMPBED
149
 #endif //PIDTEMPBED
150
   static unsigned char soft_pwm[EXTRUDERS];
150
   static unsigned char soft_pwm[EXTRUDERS];
151
 
151
 
243
     SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
243
     SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
244
     return;
244
     return;
245
   }
245
   }
246
-	
246
+  
247
   SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
247
   SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
248
 
248
 
249
   disable_heater(); // switch off all heaters.
249
   disable_heater(); // switch off all heaters.
755
   #ifdef FILAMENT_SENSOR
755
   #ifdef FILAMENT_SENSOR
756
     if (filament_sensor) {
756
     if (filament_sensor) {
757
       meas_shift_index = delay_index1 - meas_delay_cm;
757
       meas_shift_index = delay_index1 - meas_delay_cm;
758
-		  if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1;  //loop around buffer if needed
759
-		  
758
+      if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1;  //loop around buffer if needed
759
+      
760
       // Get the delayed info and add 100 to reconstitute to a percent of
760
       // Get the delayed info and add 100 to reconstitute to a percent of
761
       // the nominal filament diameter then square it to get an area
761
       // the nominal filament diameter then square it to get an area
762
       meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
762
       meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
1259
 ISR(TIMER0_COMPB_vect) {
1259
 ISR(TIMER0_COMPB_vect) {
1260
   //these variables are only accesible from the ISR, but static, so they don't lose their value
1260
   //these variables are only accesible from the ISR, but static, so they don't lose their value
1261
   static unsigned char temp_count = 0;
1261
   static unsigned char temp_count = 0;
1262
-  static unsigned long raw_temp_0_value = 0;
1263
-  static unsigned long raw_temp_1_value = 0;
1264
-  static unsigned long raw_temp_2_value = 0;
1265
-  static unsigned long raw_temp_3_value = 0;
1262
+  static unsigned long raw_temp_value[EXTRUDERS] = { 0 };
1266
   static unsigned long raw_temp_bed_value = 0;
1263
   static unsigned long raw_temp_bed_value = 0;
1267
   static TempState temp_state = StartupDelay;
1264
   static TempState temp_state = StartupDelay;
1268
   static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
1265
   static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
1474
       break;
1471
       break;
1475
     case MeasureTemp_0:
1472
     case MeasureTemp_0:
1476
       #if HAS_TEMP_0
1473
       #if HAS_TEMP_0
1477
-        raw_temp_0_value += ADC;
1474
+        raw_temp_value[0] += ADC;
1478
       #endif
1475
       #endif
1479
       temp_state = PrepareTemp_BED;
1476
       temp_state = PrepareTemp_BED;
1480
       break;
1477
       break;
1500
       break;
1497
       break;
1501
     case MeasureTemp_1:
1498
     case MeasureTemp_1:
1502
       #if HAS_TEMP_1
1499
       #if HAS_TEMP_1
1503
-        raw_temp_1_value += ADC;
1500
+        raw_temp_value[1] += ADC;
1504
       #endif
1501
       #endif
1505
       temp_state = PrepareTemp_2;
1502
       temp_state = PrepareTemp_2;
1506
       break;
1503
       break;
1513
       break;
1510
       break;
1514
     case MeasureTemp_2:
1511
     case MeasureTemp_2:
1515
       #if HAS_TEMP_2
1512
       #if HAS_TEMP_2
1516
-        raw_temp_2_value += ADC;
1513
+        raw_temp_value[2] += ADC;
1517
       #endif
1514
       #endif
1518
       temp_state = PrepareTemp_3;
1515
       temp_state = PrepareTemp_3;
1519
       break;
1516
       break;
1526
       break;
1523
       break;
1527
     case MeasureTemp_3:
1524
     case MeasureTemp_3:
1528
       #if HAS_TEMP_3
1525
       #if HAS_TEMP_3
1529
-        raw_temp_3_value += ADC;
1526
+        raw_temp_value[3] += ADC;
1530
       #endif
1527
       #endif
1531
       temp_state = Prepare_FILWIDTH;
1528
       temp_state = Prepare_FILWIDTH;
1532
       break;
1529
       break;
1561
   if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256)  = 164ms.
1558
   if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256)  = 164ms.
1562
     if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading.
1559
     if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading.
1563
       #ifndef HEATER_0_USES_MAX6675
1560
       #ifndef HEATER_0_USES_MAX6675
1564
-        current_temperature_raw[0] = raw_temp_0_value;
1561
+        current_temperature_raw[0] = raw_temp_value[0];
1565
       #endif
1562
       #endif
1566
       #if EXTRUDERS > 1
1563
       #if EXTRUDERS > 1
1567
-        current_temperature_raw[1] = raw_temp_1_value;
1564
+        current_temperature_raw[1] = raw_temp_value[1];
1568
         #if EXTRUDERS > 2
1565
         #if EXTRUDERS > 2
1569
-          current_temperature_raw[2] = raw_temp_2_value;
1566
+          current_temperature_raw[2] = raw_temp_value[2];
1570
           #if EXTRUDERS > 3
1567
           #if EXTRUDERS > 3
1571
-            current_temperature_raw[3] = raw_temp_3_value;
1568
+            current_temperature_raw[3] = raw_temp_value[3];
1572
           #endif
1569
           #endif
1573
         #endif
1570
         #endif
1574
       #endif
1571
       #endif
1575
       #ifdef TEMP_SENSOR_1_AS_REDUNDANT
1572
       #ifdef TEMP_SENSOR_1_AS_REDUNDANT
1576
-        redundant_temperature_raw = raw_temp_1_value;
1573
+        redundant_temperature_raw = raw_temp_value[1];
1577
       #endif
1574
       #endif
1578
       current_temperature_bed_raw = raw_temp_bed_value;
1575
       current_temperature_bed_raw = raw_temp_bed_value;
1579
     } //!temp_meas_ready
1576
     } //!temp_meas_ready
1585
     
1582
     
1586
     temp_meas_ready = true;
1583
     temp_meas_ready = true;
1587
     temp_count = 0;
1584
     temp_count = 0;
1588
-    raw_temp_0_value = 0;
1589
-    raw_temp_1_value = 0;
1590
-    raw_temp_2_value = 0;
1591
-    raw_temp_3_value = 0;
1585
+    for (int i = 0; i < EXTRUDERS; i++) raw_temp_value[i] = 0;
1592
     raw_temp_bed_value = 0;
1586
     raw_temp_bed_value = 0;
1593
 
1587
 
1594
     #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
1588
     #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
1595
-      #define MAXTEST <=
1596
-      #define MINTEST >=
1589
+      #define GE0 <=
1590
+      #define LE0 >=
1597
     #else
1591
     #else
1598
-      #define MAXTEST >=
1599
-      #define MINTEST <=
1592
+      #define GE0 >=
1593
+      #define LE0 <=
1600
     #endif
1594
     #endif
1595
+    if (current_temperature_raw[0] GE0 maxttemp_raw[0]) max_temp_error(0);
1596
+    if (current_temperature_raw[0] LE0 minttemp_raw[0]) min_temp_error(0);
1597
+
1598
+    #if EXTRUDERS > 1
1599
+      #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
1600
+        #define GE1 <=
1601
+        #define LE1 >=
1602
+      #else
1603
+        #define GE1 >=
1604
+        #define LE1 <=
1605
+      #endif
1606
+      if (current_temperature_raw[1] GE1 maxttemp_raw[1]) max_temp_error(1);
1607
+      if (current_temperature_raw[1] LE1 minttemp_raw[1]) min_temp_error(1);
1608
+      #if EXTRUDERS > 2
1609
+        #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
1610
+          #define GE2 <=
1611
+          #define LE2 >=
1612
+        #else
1613
+          #define GE2 >=
1614
+          #define LE2 <=
1615
+        #endif
1616
+        if (current_temperature_raw[2] GE2 maxttemp_raw[2]) max_temp_error(2);
1617
+        if (current_temperature_raw[2] LE2 minttemp_raw[2]) min_temp_error(2);
1618
+        #if EXTRUDERS > 3
1619
+          #if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
1620
+            #define GE3 <=
1621
+            #define LE3 >=
1622
+          #else
1623
+            #define GE3 >=
1624
+            #define LE3 <=
1625
+          #endif
1626
+          if (current_temperature_raw[3] GE3 maxttemp_raw[3]) max_temp_error(3);
1627
+          if (current_temperature_raw[3] LE3 minttemp_raw[3]) min_temp_error(3);
1628
+        #endif // EXTRUDERS > 3
1629
+      #endif // EXTRUDERS > 2
1630
+    #endif // EXTRUDERS > 1
1601
 
1631
 
1602
-    for (int i=0; i<EXTRUDERS; i++) {
1603
-      if (current_temperature_raw[i] MAXTEST maxttemp_raw[i]) max_temp_error(i);
1604
-      else if (current_temperature_raw[i] MINTEST minttemp_raw[i]) min_temp_error(i);
1605
-    }
1606
-    /* No bed MINTEMP error? */
1607
     #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
1632
     #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
1608
-      if (current_temperature_bed_raw MAXTEST bed_maxttemp_raw) {
1609
-          target_temperature_bed = 0;
1610
-          bed_max_temp_error();
1611
-        }
1633
+      #if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
1634
+        #define GEBED <=
1635
+        #define LEBED >=
1636
+      #else
1637
+        #define GEBED >=
1638
+        #define LEBED <=
1639
+      #endif
1640
+      if (current_temperature_bed_raw GEBED bed_maxttemp_raw) {
1641
+        target_temperature_bed = 0;
1642
+        bed_max_temp_error();
1643
+      }
1612
     #endif
1644
     #endif
1645
+
1613
   } // temp_count >= OVERSAMPLENR
1646
   } // temp_count >= OVERSAMPLENR
1614
 
1647
 
1615
   #ifdef BABYSTEPPING
1648
   #ifdef BABYSTEPPING

+ 90
- 3
Marlin/ultralcd.cpp View File

70
 static void lcd_delta_calibrate_menu();
70
 static void lcd_delta_calibrate_menu();
71
 #endif // DELTA_CALIBRATION_MENU
71
 #endif // DELTA_CALIBRATION_MENU
72
 
72
 
73
+#if defined(MANUAL_BED_LEVELING)
74
+#include "mesh_bed_leveling.h"
75
+static void _lcd_level_bed();
76
+static void _lcd_level_bed_homing();
77
+static void lcd_level_bed();
78
+#endif  // MANUAL_BED_LEVELING
79
+
73
 static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
80
 static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
74
 
81
 
75
 /* Different types of actions that can be used in menu items. */
82
 /* Different types of actions that can be used in menu items. */
198
   #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
205
   #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
199
 #endif //!ENCODER_RATE_MULTIPLIER
206
 #endif //!ENCODER_RATE_MULTIPLIER
200
 #define END_MENU() \
207
 #define END_MENU() \
201
-    if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; \
202
-    if ((uint8_t)(encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
208
+    if (encoderLine >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\
209
+    if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
203
     } } while(0)
210
     } } while(0)
204
 
211
 
205
 /** Used variables to keep track of the menu */
212
 /** Used variables to keep track of the menu */
630
     }
637
     }
631
   #endif
638
   #endif
632
   MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu);
639
   MENU_ITEM(submenu, MSG_MOVE_AXIS, lcd_move_menu);
640
+
641
+  #if defined(MANUAL_BED_LEVELING)
642
+    MENU_ITEM(submenu, MSG_LEVEL_BED, lcd_level_bed);
643
+  #endif
633
 	
644
 	
634
   END_MENU();
645
   END_MENU();
635
 }
646
 }
1341
     #endif
1352
     #endif
1342
 
1353
 
1343
     #ifdef ULTIPANEL
1354
     #ifdef ULTIPANEL
1344
-      if (currentMenu != lcd_status_screen && millis() > timeoutToStatus) {
1355
+      if (currentMenu != lcd_status_screen &&
1356
+        #if defined(MANUAL_BED_LEVELING)
1357
+          currentMenu != _lcd_level_bed && 
1358
+          currentMenu != _lcd_level_bed_homing && 
1359
+        #endif  // MANUAL_BED_LEVELING
1360
+          millis() > timeoutToStatus) {
1345
         lcd_return_to_status();
1361
         lcd_return_to_status();
1346
         lcdDrawUpdate = 2;
1362
         lcdDrawUpdate = 2;
1347
       }
1363
       }
1760
   return conv;
1776
   return conv;
1761
 }
1777
 }
1762
 
1778
 
1779
+#if defined(MANUAL_BED_LEVELING)
1780
+static int _lcd_level_bed_position;
1781
+static void _lcd_level_bed()
1782
+{
1783
+  if (encoderPosition != 0) {
1784
+    refresh_cmd_timeout();
1785
+    current_position[Z_AXIS] += float((int)encoderPosition) * 0.05;
1786
+    if (min_software_endstops && current_position[Z_AXIS] < Z_MIN_POS) current_position[Z_AXIS] = Z_MIN_POS;
1787
+    if (max_software_endstops && current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
1788
+    encoderPosition = 0;
1789
+    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);
1790
+    lcdDrawUpdate = 1;
1791
+  }
1792
+  if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR("Z"), ftostr32(current_position[Z_AXIS]));
1793
+  static bool debounce_click = false;
1794
+  if (LCD_CLICKED) {
1795
+    if (!debounce_click) {
1796
+      debounce_click = true;
1797
+      int ix = _lcd_level_bed_position % MESH_NUM_X_POINTS;
1798
+      int iy = _lcd_level_bed_position / MESH_NUM_X_POINTS;
1799
+      mbl.set_z(ix, iy, current_position[Z_AXIS]);
1800
+      _lcd_level_bed_position++;
1801
+      if (_lcd_level_bed_position == MESH_NUM_X_POINTS*MESH_NUM_Y_POINTS) {
1802
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1803
+        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);
1804
+        mbl.active = 1;
1805
+        enquecommands_P(PSTR("G28"));
1806
+        lcd_return_to_status();
1807
+      } else {
1808
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1809
+        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);
1810
+        ix = _lcd_level_bed_position % MESH_NUM_X_POINTS;
1811
+        iy = _lcd_level_bed_position / MESH_NUM_X_POINTS;
1812
+        if (iy&1) { // Zig zag
1813
+          ix = (MESH_NUM_X_POINTS - 1) - ix;
1814
+        }
1815
+        current_position[X_AXIS] = mbl.get_x(ix);
1816
+        current_position[Y_AXIS] = mbl.get_y(iy);
1817
+        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);
1818
+        lcdDrawUpdate = 1;
1819
+      }
1820
+    }
1821
+  } else {
1822
+    debounce_click = false;
1823
+  }
1824
+}
1825
+static void _lcd_level_bed_homing()
1826
+{
1827
+  if (axis_known_position[X_AXIS] &&
1828
+      axis_known_position[Y_AXIS] &&
1829
+      axis_known_position[Z_AXIS]) {
1830
+    current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1831
+    plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1832
+    current_position[X_AXIS] = MESH_MIN_X;
1833
+    current_position[Y_AXIS] = MESH_MIN_Y;
1834
+    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);
1835
+    _lcd_level_bed_position = 0;
1836
+    lcd_goto_menu(_lcd_level_bed);
1837
+  }
1838
+}
1839
+static void lcd_level_bed()
1840
+{
1841
+  axis_known_position[X_AXIS] = false;
1842
+  axis_known_position[Y_AXIS] = false;
1843
+  axis_known_position[Z_AXIS] = false;
1844
+  mbl.reset();
1845
+  enquecommands_P(PSTR("G28"));
1846
+  lcd_goto_menu(_lcd_level_bed_homing);
1847
+}
1848
+#endif  // MANUAL_BED_LEVELING
1849
+
1763
 #endif //ULTRA_LCD
1850
 #endif //ULTRA_LCD

Loading…
Cancel
Save