Переглянути джерело

Merge remote-tracking branch 'upstream/Development' into Development

CONSULitAS 10 роки тому
джерело
коміт
703f3b38c4

+ 19
- 6
Marlin/Configuration.h Переглянути файл

@@ -225,6 +225,8 @@ Here are some standard links for getting your machine calibrated:
225 225
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
226 226
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
227 227
 
228
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
229
+
228 230
 #ifdef PIDTEMPBED
229 231
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
230 232
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -373,6 +375,23 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
373 375
 //#define ENDSTOPPULLUP_FIL_RUNOUT // Uncomment to use internal pullup for filament runout pins if the sensor is defined.
374 376
 
375 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
+//===========================================================================
376 395
 //============================= Bed Auto Leveling ===========================
377 396
 //===========================================================================
378 397
 
@@ -398,12 +417,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
398 417
 
399 418
   #ifdef AUTO_BED_LEVELING_GRID
400 419
 
401
-    // Use one of these defines to specify the origin
402
-    // for a topographical map to be printed for your bed.
403
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
404
-    #define TOPO_ORIGIN OriginFrontLeft
405
-
406
-    // The edges of the rectangle in which to probe
407 420
     #define LEFT_PROBE_BED_POSITION 15
408 421
     #define RIGHT_PROBE_BED_POSITION 170
409 422
     #define FRONT_PROBE_BED_POSITION 20

+ 70
- 9
Marlin/ConfigurationStore.cpp Переглянути файл

@@ -18,7 +18,13 @@
18 18
  *  max_xy_jerk
19 19
  *  max_z_jerk
20 20
  *  max_e_jerk
21
- *  add_homing (x3)
21
+ *  home_offset (x3)
22
+ *
23
+ * Mesh bed leveling:
24
+ *  active
25
+ *  mesh_num_x
26
+ *  mesh_num_y
27
+ *  z_values[][]
22 28
  *
23 29
  * DELTA:
24 30
  *  endstop_adj (x3)
@@ -69,6 +75,10 @@
69 75
 #include "ultralcd.h"
70 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 82
 void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) {
73 83
   uint8_t c;
74 84
   while(size--) {
@@ -105,7 +115,7 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) {
105 115
 // wrong data being written to the variables.
106 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 120
 #ifdef EEPROM_SETTINGS
111 121
 
@@ -126,7 +136,29 @@ void Config_StoreSettings()  {
126 136
   EEPROM_WRITE_VAR(i, max_xy_jerk);
127 137
   EEPROM_WRITE_VAR(i, max_z_jerk);
128 138
   EEPROM_WRITE_VAR(i, max_e_jerk);
129
-  EEPROM_WRITE_VAR(i, add_homing);
139
+  EEPROM_WRITE_VAR(i, home_offset);
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
130 162
 
131 163
   #ifdef DELTA
132 164
     EEPROM_WRITE_VAR(i, endstop_adj);               // 3 floats
@@ -250,7 +282,7 @@ void Config_RetrieveSettings() {
250 282
     EEPROM_READ_VAR(i, max_feedrate);
251 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 286
     reset_acceleration_rates();
255 287
 
256 288
     EEPROM_READ_VAR(i, acceleration);
@@ -262,7 +294,32 @@ void Config_RetrieveSettings() {
262 294
     EEPROM_READ_VAR(i, max_xy_jerk);
263 295
     EEPROM_READ_VAR(i, max_z_jerk);
264 296
     EEPROM_READ_VAR(i, max_e_jerk);
265
-    EEPROM_READ_VAR(i, add_homing);
297
+    EEPROM_READ_VAR(i, home_offset);
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
266 323
 
267 324
     #ifdef DELTA
268 325
       EEPROM_READ_VAR(i, endstop_adj);                // 3 floats
@@ -390,7 +447,11 @@ void Config_ResetDefault() {
390 447
   max_xy_jerk = DEFAULT_XYJERK;
391 448
   max_z_jerk = DEFAULT_ZJERK;
392 449
   max_e_jerk = DEFAULT_EJERK;
393
-  add_homing[X_AXIS] = add_homing[Y_AXIS] = add_homing[Z_AXIS] = 0;
450
+  home_offset[X_AXIS] = home_offset[Y_AXIS] = home_offset[Z_AXIS] = 0;
451
+
452
+  #if defined(MESH_BED_LEVELING)
453
+    mbl.active = 0;
454
+  #endif  // MESH_BED_LEVELING
394 455
 
395 456
   #ifdef DELTA
396 457
     endstop_adj[X_AXIS] = endstop_adj[Y_AXIS] = endstop_adj[Z_AXIS] = 0;
@@ -546,9 +607,9 @@ void Config_PrintSettings(bool forReplay) {
546 607
     SERIAL_ECHOLNPGM("Home offset (mm):");
547 608
     SERIAL_ECHO_START;
548 609
   }
549
-  SERIAL_ECHOPAIR("  M206 X", add_homing[X_AXIS] );
550
-  SERIAL_ECHOPAIR(" Y", add_homing[Y_AXIS] );
551
-  SERIAL_ECHOPAIR(" Z", add_homing[Z_AXIS] );
610
+  SERIAL_ECHOPAIR("  M206 X", home_offset[X_AXIS] );
611
+  SERIAL_ECHOPAIR(" Y", home_offset[Y_AXIS] );
612
+  SERIAL_ECHOPAIR(" Z", home_offset[Z_AXIS] );
552 613
   SERIAL_EOL;
553 614
 
554 615
   #ifdef DELTA

+ 1
- 1
Marlin/Marlin.h Переглянути файл

@@ -240,7 +240,7 @@ extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in per
240 240
 extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
241 241
 extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
242 242
 extern float current_position[NUM_AXIS] ;
243
-extern float add_homing[3];
243
+extern float home_offset[3];
244 244
 #ifdef DELTA
245 245
 extern float endstop_adj[3];
246 246
 extern float delta_radius;

+ 298
- 177
Marlin/Marlin_main.cpp Переглянути файл

@@ -41,6 +41,10 @@
41 41
 
42 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 48
 #include "ultralcd.h"
45 49
 #include "planner.h"
46 50
 #include "stepper.h"
@@ -244,7 +248,7 @@ float volumetric_multiplier[EXTRUDERS] = {1.0
244 248
   #endif
245 249
 };
246 250
 float current_position[NUM_AXIS] = { 0.0, 0.0, 0.0, 0.0 };
247
-float add_homing[3] = { 0, 0, 0 };
251
+float home_offset[3] = { 0, 0, 0 };
248 252
 #ifdef DELTA
249 253
   float endstop_adj[3] = { 0, 0, 0 };
250 254
 #endif
@@ -980,7 +984,7 @@ static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
980 984
 
981 985
 static float x_home_pos(int extruder) {
982 986
   if (extruder == 0)
983
-    return base_home_pos(X_AXIS) + add_homing[X_AXIS];
987
+    return base_home_pos(X_AXIS) + home_offset[X_AXIS];
984 988
   else
985 989
     // In dual carriage mode the extruder offset provides an override of the
986 990
     // second X-carriage offset when homed - otherwise X2_HOME_POS is used.
@@ -1012,9 +1016,9 @@ static void axis_is_at_home(int axis) {
1012 1016
       return;
1013 1017
     }
1014 1018
     else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) {
1015
-      current_position[X_AXIS] = base_home_pos(X_AXIS) + add_homing[X_AXIS];
1016
-      min_pos[X_AXIS] =          base_min_pos(X_AXIS) + add_homing[X_AXIS];
1017
-      max_pos[X_AXIS] =          min(base_max_pos(X_AXIS) + add_homing[X_AXIS],
1019
+      current_position[X_AXIS] = base_home_pos(X_AXIS) + home_offset[X_AXIS];
1020
+      min_pos[X_AXIS] =          base_min_pos(X_AXIS) + home_offset[X_AXIS];
1021
+      max_pos[X_AXIS] =          min(base_max_pos(X_AXIS) + home_offset[X_AXIS],
1018 1022
                                   max(extruder_offset[X_AXIS][1], X2_MAX_POS) - duplicate_extruder_x_offset);
1019 1023
       return;
1020 1024
     }
@@ -1042,11 +1046,11 @@ static void axis_is_at_home(int axis) {
1042 1046
      
1043 1047
      for (i=0; i<2; i++)
1044 1048
      {
1045
-        delta[i] -= add_homing[i];
1049
+        delta[i] -= home_offset[i];
1046 1050
      } 
1047 1051
      
1048
-    // SERIAL_ECHOPGM("addhome X="); SERIAL_ECHO(add_homing[X_AXIS]);
1049
-  // SERIAL_ECHOPGM(" addhome Y="); SERIAL_ECHO(add_homing[Y_AXIS]);
1052
+    // SERIAL_ECHOPGM("addhome X="); SERIAL_ECHO(home_offset[X_AXIS]);
1053
+  // SERIAL_ECHOPGM(" addhome Y="); SERIAL_ECHO(home_offset[Y_AXIS]);
1050 1054
     // SERIAL_ECHOPGM(" addhome Theta="); SERIAL_ECHO(delta[X_AXIS]);
1051 1055
     // SERIAL_ECHOPGM(" addhome Psi+Theta="); SERIAL_ECHOLN(delta[Y_AXIS]);
1052 1056
       
@@ -1064,14 +1068,14 @@ static void axis_is_at_home(int axis) {
1064 1068
    } 
1065 1069
    else
1066 1070
    {
1067
-      current_position[axis] = base_home_pos(axis) + add_homing[axis];
1068
-      min_pos[axis] =          base_min_pos(axis) + add_homing[axis];
1069
-      max_pos[axis] =          base_max_pos(axis) + add_homing[axis];
1071
+      current_position[axis] = base_home_pos(axis) + home_offset[axis];
1072
+      min_pos[axis] =          base_min_pos(axis) + home_offset[axis];
1073
+      max_pos[axis] =          base_max_pos(axis) + home_offset[axis];
1070 1074
    }
1071 1075
 #else
1072
-  current_position[axis] = base_home_pos(axis) + add_homing[axis];
1073
-  min_pos[axis] =          base_min_pos(axis) + add_homing[axis];
1074
-  max_pos[axis] =          base_max_pos(axis) + add_homing[axis];
1076
+  current_position[axis] = base_home_pos(axis) + home_offset[axis];
1077
+  min_pos[axis] =          base_min_pos(axis) + home_offset[axis];
1078
+  max_pos[axis] =          base_max_pos(axis) + home_offset[axis];
1075 1079
 #endif
1076 1080
 }
1077 1081
 
@@ -1305,7 +1309,13 @@ static void engage_z_probe() {
1305 1309
 static void retract_z_probe() {
1306 1310
   // Retract Z Servo endstop if enabled
1307 1311
   #ifdef SERVO_ENDSTOPS
1308
-    if (servo_endstops[Z_AXIS] > -1) {
1312
+    if (servo_endstops[Z_AXIS] > -1)
1313
+    {
1314
+      #if Z_RAISE_AFTER_PROBING > 0
1315
+        do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], Z_RAISE_AFTER_PROBING);
1316
+        st_synchronize();
1317
+      #endif
1318
+    
1309 1319
       #if SERVO_LEVELING
1310 1320
         servos[servo_endstops[Z_AXIS]].attach(0);
1311 1321
       #endif
@@ -1318,7 +1328,7 @@ static void retract_z_probe() {
1318 1328
   #elif defined(Z_PROBE_ALLEN_KEY)
1319 1329
     // Move up for safety
1320 1330
     feedrate = homing_feedrate[X_AXIS];
1321
-    destination[Z_AXIS] = current_position[Z_AXIS] + 20;
1331
+    destination[Z_AXIS] = current_position[Z_AXIS] + Z_RAISE_AFTER_PROBING;
1322 1332
     prepare_move_raw();
1323 1333
 
1324 1334
     // Move to the start position to initiate retraction
@@ -1360,10 +1370,15 @@ static void retract_z_probe() {
1360 1370
 
1361 1371
 }
1362 1372
 
1363
-enum ProbeAction { ProbeStay, ProbeEngage, ProbeRetract, ProbeEngageRetract };
1373
+enum ProbeAction {
1374
+  ProbeStay             = 0,
1375
+  ProbeEngage           = BIT(0),
1376
+  ProbeRetract          = BIT(1),
1377
+  ProbeEngageAndRetract = (ProbeEngage | ProbeRetract)
1378
+};
1364 1379
 
1365 1380
 /// Probe bed height at position (x,y), returns the measured z value
1366
-static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeEngageRetract, int verbose_level=1) {
1381
+static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeEngageAndRetract, int verbose_level=1) {
1367 1382
   // move to right place
1368 1383
   do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
1369 1384
   do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
@@ -1737,6 +1752,11 @@ inline void gcode_G28() {
1737 1752
     #endif
1738 1753
   #endif
1739 1754
 
1755
+  #if defined(MESH_BED_LEVELING)
1756
+    uint8_t mbl_was_active = mbl.active;
1757
+    mbl.active = 0;
1758
+  #endif  // MESH_BED_LEVELING
1759
+
1740 1760
   saved_feedrate = feedrate;
1741 1761
   saved_feedmultiply = feedmultiply;
1742 1762
   feedmultiply = 100;
@@ -1849,7 +1869,7 @@ inline void gcode_G28() {
1849 1869
       if (code_value_long() != 0) {
1850 1870
           current_position[X_AXIS] = code_value()
1851 1871
             #ifndef SCARA
1852
-              + add_homing[X_AXIS]
1872
+              + home_offset[X_AXIS]
1853 1873
             #endif
1854 1874
           ;
1855 1875
       }
@@ -1858,7 +1878,7 @@ inline void gcode_G28() {
1858 1878
     if (code_seen(axis_codes[Y_AXIS]) && code_value_long() != 0) {
1859 1879
       current_position[Y_AXIS] = code_value()
1860 1880
         #ifndef SCARA
1861
-          + add_homing[Y_AXIS]
1881
+          + home_offset[Y_AXIS]
1862 1882
         #endif
1863 1883
       ;
1864 1884
     }
@@ -1932,7 +1952,7 @@ inline void gcode_G28() {
1932 1952
 
1933 1953
 
1934 1954
     if (code_seen(axis_codes[Z_AXIS]) && code_value_long() != 0)
1935
-      current_position[Z_AXIS] = code_value() + add_homing[Z_AXIS];
1955
+      current_position[Z_AXIS] = code_value() + home_offset[Z_AXIS];
1936 1956
 
1937 1957
     #ifdef ENABLE_AUTO_BED_LEVELING
1938 1958
       if (home_all_axis || code_seen(axis_codes[Z_AXIS]))
@@ -1951,12 +1971,112 @@ inline void gcode_G28() {
1951 1971
     enable_endstops(false);
1952 1972
   #endif
1953 1973
 
1974
+  #if defined(MESH_BED_LEVELING)
1975
+    if (mbl_was_active) {
1976
+      current_position[X_AXIS] = mbl.get_x(0);
1977
+      current_position[Y_AXIS] = mbl.get_y(0);
1978
+      destination[X_AXIS] = current_position[X_AXIS];
1979
+      destination[Y_AXIS] = current_position[Y_AXIS];
1980
+      destination[Z_AXIS] = current_position[Z_AXIS];
1981
+      destination[E_AXIS] = current_position[E_AXIS];
1982
+      feedrate = homing_feedrate[X_AXIS];
1983
+      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
1984
+      st_synchronize();
1985
+      current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
1986
+      plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1987
+      mbl.active = 1;
1988
+    }
1989
+  #endif
1990
+
1954 1991
   feedrate = saved_feedrate;
1955 1992
   feedmultiply = saved_feedmultiply;
1956 1993
   previous_millis_cmd = millis();
1957 1994
   endstops_hit_on_purpose();
1958 1995
 }
1959 1996
 
1997
+#if defined(MESH_BED_LEVELING)
1998
+
1999
+  inline void gcode_G29() {
2000
+    static int probe_point = -1;
2001
+    int state = 0;
2002
+    if (code_seen('S') || code_seen('s')) {
2003
+      state = code_value_long();
2004
+      if (state < 0 || state > 2) {
2005
+        SERIAL_PROTOCOLPGM("S out of range (0-2).\n");
2006
+        return;
2007
+      }
2008
+    }
2009
+
2010
+    if (state == 0) { // Dump mesh_bed_leveling
2011
+      if (mbl.active) {
2012
+        SERIAL_PROTOCOLPGM("Num X,Y: ");
2013
+        SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
2014
+        SERIAL_PROTOCOLPGM(",");
2015
+        SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
2016
+        SERIAL_PROTOCOLPGM("\nZ search height: ");
2017
+        SERIAL_PROTOCOL(MESH_HOME_SEARCH_Z);
2018
+        SERIAL_PROTOCOLPGM("\nMeasured points:\n");              
2019
+        for (int y=0; y<MESH_NUM_Y_POINTS; y++) {
2020
+          for (int x=0; x<MESH_NUM_X_POINTS; x++) {
2021
+            SERIAL_PROTOCOLPGM("  ");              
2022
+            SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5);
2023
+          }
2024
+          SERIAL_EOL;
2025
+        }
2026
+      } else {
2027
+        SERIAL_PROTOCOLPGM("Mesh bed leveling not active.\n");
2028
+      }
2029
+
2030
+    } else if (state == 1) { // Begin probing mesh points
2031
+
2032
+      mbl.reset();
2033
+      probe_point = 0;
2034
+      enquecommands_P(PSTR("G28"));
2035
+      enquecommands_P(PSTR("G29 S2"));
2036
+
2037
+    } else if (state == 2) { // Goto next point
2038
+
2039
+      if (probe_point < 0) {
2040
+        SERIAL_PROTOCOLPGM("Mesh probing not started.\n");
2041
+        return;
2042
+      }
2043
+      int ix, iy;
2044
+      if (probe_point == 0) {
2045
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
2046
+        plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2047
+      } else {
2048
+        ix = (probe_point-1) % MESH_NUM_X_POINTS;
2049
+        iy = (probe_point-1) / MESH_NUM_X_POINTS;
2050
+        if (iy&1) { // Zig zag
2051
+          ix = (MESH_NUM_X_POINTS - 1) - ix;
2052
+        }
2053
+        mbl.set_z(ix, iy, current_position[Z_AXIS]);
2054
+        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
2055
+        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);
2056
+        st_synchronize();
2057
+      }
2058
+      if (probe_point == MESH_NUM_X_POINTS*MESH_NUM_Y_POINTS) {
2059
+        SERIAL_PROTOCOLPGM("Mesh done.\n");
2060
+        probe_point = -1;
2061
+        mbl.active = 1;
2062
+        enquecommands_P(PSTR("G28"));
2063
+        return;
2064
+      }
2065
+      ix = probe_point % MESH_NUM_X_POINTS;
2066
+      iy = probe_point / MESH_NUM_X_POINTS;
2067
+      if (iy&1) { // Zig zag
2068
+        ix = (MESH_NUM_X_POINTS - 1) - ix;
2069
+      }
2070
+      current_position[X_AXIS] = mbl.get_x(ix);
2071
+      current_position[Y_AXIS] = mbl.get_y(iy);
2072
+      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);
2073
+      st_synchronize();
2074
+      probe_point++;
2075
+    }
2076
+  }
2077
+
2078
+#endif
2079
+
1960 2080
 #ifdef ENABLE_AUTO_BED_LEVELING
1961 2081
 
1962 2082
   // Define the possible boundaries for probing based on set limits
@@ -2057,7 +2177,7 @@ inline void gcode_G28() {
2057 2177
     #ifdef AUTO_BED_LEVELING_GRID
2058 2178
 
2059 2179
     #ifndef DELTA
2060
-      bool topo_flag = verbose_level > 2 || code_seen('T') || code_seen('t');
2180
+      bool do_topography_map = verbose_level > 2 || code_seen('T') || code_seen('t');
2061 2181
     #endif
2062 2182
 
2063 2183
       if (verbose_level > 0)
@@ -2112,15 +2232,16 @@ inline void gcode_G28() {
2112 2232
 
2113 2233
     #ifdef Z_PROBE_SLED
2114 2234
       dock_sled(false); // engage (un-dock) the probe
2115
-    #elif not defined(SERVO_ENDSTOPS)
2235
+    #elif defined(Z_PROBE_ALLEN_KEY)
2116 2236
       engage_z_probe();
2117 2237
     #endif
2118 2238
 
2119 2239
     st_synchronize();
2120 2240
 
2121
-  #ifdef DELTA
2122
-    reset_bed_level();
2123
-  #else
2241
+    #ifdef DELTA
2242
+      reset_bed_level();
2243
+    #else
2244
+
2124 2245
     // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
2125 2246
     //vector_3 corrected_position = plan_get_position_mm();
2126 2247
     //corrected_position.debug("position before G29");
@@ -2161,42 +2282,36 @@ inline void gcode_G28() {
2161 2282
       delta_grid_spacing[1] = yGridSpacing;
2162 2283
 
2163 2284
       float z_offset = Z_PROBE_OFFSET_FROM_EXTRUDER;
2164
-      if (code_seen(axis_codes[Z_AXIS])) {
2165
-        z_offset += code_value();
2166
-      }
2285
+      if (code_seen(axis_codes[Z_AXIS])) z_offset += code_value();
2167 2286
     #endif
2168 2287
 
2169 2288
       int probePointCounter = 0;
2170 2289
       bool zig = true;
2171 2290
 
2172
-      for (int yCount=0; yCount < auto_bed_leveling_grid_points; yCount++)
2173
-      {
2291
+      for (int yCount = 0; yCount < auto_bed_leveling_grid_points; yCount++) {
2174 2292
         double yProbe = front_probe_bed_position + yGridSpacing * yCount;
2175 2293
         int xStart, xStop, xInc;
2176 2294
 
2177
-        if (zig)
2178
-        {
2295
+        if (zig) {
2179 2296
           xStart = 0;
2180 2297
           xStop = auto_bed_leveling_grid_points;
2181 2298
           xInc = 1;
2182 2299
           zig = false;
2183 2300
         }
2184
-        else
2185
-        {
2301
+        else {
2186 2302
           xStart = auto_bed_leveling_grid_points - 1;
2187 2303
           xStop = -1;
2188 2304
           xInc = -1;
2189 2305
           zig = true;
2190 2306
         }
2191 2307
 
2192
-      #ifndef DELTA
2193
-        // If topo_flag is set then don't zig-zag. Just scan in one direction.
2194
-        // This gets the probe points in more readable order.
2195
-        if (!topo_flag) zig = !zig;
2196
-      #endif
2308
+        #ifndef DELTA
2309
+          // If do_topography_map is set then don't zig-zag. Just scan in one direction.
2310
+          // This gets the probe points in more readable order.
2311
+          if (!do_topography_map) zig = !zig;
2312
+        #endif
2197 2313
 
2198
-        for (int xCount=xStart; xCount != xStop; xCount += xInc)
2199
-        {
2314
+        for (int xCount = xStart; xCount != xStop; xCount += xInc) {
2200 2315
           double xProbe = left_probe_bed_position + xGridSpacing * xCount;
2201 2316
 
2202 2317
           // raise extruder
@@ -2221,7 +2336,7 @@ inline void gcode_G28() {
2221 2336
               act = ProbeStay;
2222 2337
           }
2223 2338
           else
2224
-            act = ProbeEngageRetract;
2339
+            act = ProbeEngageAndRetract;
2225 2340
 
2226 2341
           measured_z = probe_pt(xProbe, yProbe, z_before, act, verbose_level);
2227 2342
 
@@ -2263,49 +2378,31 @@ inline void gcode_G28() {
2263 2378
         }
2264 2379
       }
2265 2380
 
2266
-      if (topo_flag) {
2267
-
2268
-        int xx, yy;
2381
+      // Show the Topography map if enabled
2382
+      if (do_topography_map) {
2269 2383
 
2270 2384
         SERIAL_PROTOCOLPGM(" \nBed Height Topography: \n");
2271
-        #if TOPO_ORIGIN == OriginFrontLeft
2272
-          SERIAL_PROTOCOLPGM("+-----------+\n");
2273
-          SERIAL_PROTOCOLPGM("|...Back....|\n");
2274
-          SERIAL_PROTOCOLPGM("|Left..Right|\n");
2275
-          SERIAL_PROTOCOLPGM("|...Front...|\n");
2276
-          SERIAL_PROTOCOLPGM("+-----------+\n");
2277
-          for (yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--)
2278
-        #else
2279
-          for (yy = 0; yy < auto_bed_leveling_grid_points; yy++)
2280
-        #endif
2281
-          {
2282
-            #if TOPO_ORIGIN == OriginBackRight
2283
-              for (xx = 0; xx < auto_bed_leveling_grid_points; xx++)
2284
-            #else
2285
-              for (xx = auto_bed_leveling_grid_points - 1; xx >= 0; xx--)
2286
-            #endif
2287
-              {
2288
-                int ind =
2289
-                  #if TOPO_ORIGIN == OriginBackRight || TOPO_ORIGIN == OriginFrontLeft
2290
-                    yy * auto_bed_leveling_grid_points + xx
2291
-                  #elif TOPO_ORIGIN == OriginBackLeft
2292
-                    xx * auto_bed_leveling_grid_points + yy
2293
-                  #elif TOPO_ORIGIN == OriginFrontRight
2294
-                    abl2 - xx * auto_bed_leveling_grid_points - yy - 1
2295
-                  #endif
2296
-                ;
2297
-                float diff = eqnBVector[ind] - mean;
2298
-                if (diff >= 0.0)
2299
-                  SERIAL_PROTOCOLPGM(" +");   // Include + for column alignment
2300
-                else
2301
-                  SERIAL_PROTOCOLPGM(" ");
2302
-                SERIAL_PROTOCOL_F(diff, 5);
2303
-              } // xx
2304
-              SERIAL_EOL;
2305
-          } // yy
2385
+        SERIAL_PROTOCOLPGM("+-----------+\n");
2386
+        SERIAL_PROTOCOLPGM("|...Back....|\n");
2387
+        SERIAL_PROTOCOLPGM("|Left..Right|\n");
2388
+        SERIAL_PROTOCOLPGM("|...Front...|\n");
2389
+        SERIAL_PROTOCOLPGM("+-----------+\n");
2390
+
2391
+        for (int yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--) {
2392
+          for (int xx = auto_bed_leveling_grid_points - 1; xx >= 0; xx--) {
2393
+            int ind = yy * auto_bed_leveling_grid_points + xx;
2394
+            float diff = eqnBVector[ind] - mean;
2395
+            if (diff >= 0.0)
2396
+              SERIAL_PROTOCOLPGM(" +");   // Include + for column alignment
2397
+            else
2398
+              SERIAL_PROTOCOLPGM(" ");
2399
+            SERIAL_PROTOCOL_F(diff, 5);
2400
+          } // xx
2306 2401
           SERIAL_EOL;
2402
+        } // yy
2403
+        SERIAL_EOL;
2307 2404
 
2308
-      } //topo_flag
2405
+      } //do_topography_map
2309 2406
 
2310 2407
 
2311 2408
       set_bed_level_equation_lsq(plane_equation_coefficients);
@@ -2327,18 +2424,15 @@ inline void gcode_G28() {
2327 2424
         z_at_pt_3 = probe_pt(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS, ProbeRetract, verbose_level);
2328 2425
       }
2329 2426
       else {
2330
-        z_at_pt_1 = probe_pt(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, Z_RAISE_BEFORE_PROBING, verbose_level=verbose_level);
2331
-        z_at_pt_2 = probe_pt(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS, verbose_level=verbose_level);
2332
-        z_at_pt_3 = probe_pt(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS, verbose_level=verbose_level);
2427
+        z_at_pt_1 = probe_pt(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, Z_RAISE_BEFORE_PROBING, ProbeEngageAndRetract, verbose_level);
2428
+        z_at_pt_2 = probe_pt(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS, ProbeEngageAndRetract, verbose_level);
2429
+        z_at_pt_3 = probe_pt(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS, ProbeEngageAndRetract, verbose_level);
2333 2430
       }
2334 2431
       clean_up_after_endstop_move();
2335 2432
       set_bed_level_equation_3pts(z_at_pt_1, z_at_pt_2, z_at_pt_3);
2336 2433
 
2337 2434
     #endif // !AUTO_BED_LEVELING_GRID
2338 2435
 
2339
-    do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], Z_RAISE_AFTER_PROBING);
2340
-    st_synchronize();
2341
-
2342 2436
   #ifndef DELTA
2343 2437
     if (verbose_level > 0)
2344 2438
       plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
@@ -2358,7 +2452,7 @@ inline void gcode_G28() {
2358 2452
 
2359 2453
   #ifdef Z_PROBE_SLED
2360 2454
     dock_sled(true, -SLED_DOCKING_OFFSET); // dock the probe, correcting for over-travel
2361
-  #elif not defined(SERVO_ENDSTOPS)
2455
+  #elif defined(Z_PROBE_ALLEN_KEY)
2362 2456
     retract_z_probe();
2363 2457
   #endif
2364 2458
     
@@ -2403,22 +2497,13 @@ inline void gcode_G92() {
2403 2497
   if (!code_seen(axis_codes[E_AXIS]))
2404 2498
     st_synchronize();
2405 2499
 
2406
-  for (int i=0;i<NUM_AXIS;i++) {
2500
+  for (int i = 0; i < NUM_AXIS; i++) {
2407 2501
     if (code_seen(axis_codes[i])) {
2408
-      if (i == E_AXIS) {
2409
-        current_position[i] = code_value();
2502
+      current_position[i] = code_value();
2503
+      if (i == E_AXIS)
2410 2504
         plan_set_e_position(current_position[E_AXIS]);
2411
-      }
2412
-      else {
2413
-        current_position[i] = code_value() +
2414
-          #ifdef SCARA
2415
-            ((i != X_AXIS && i != Y_AXIS) ? add_homing[i] : 0)
2416
-          #else
2417
-            add_homing[i]
2418
-          #endif
2419
-        ;
2505
+      else
2420 2506
         plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2421
-      }
2422 2507
     }
2423 2508
   }
2424 2509
 }
@@ -2562,13 +2647,13 @@ inline void gcode_M17() {
2562 2647
    */
2563 2648
   inline void gcode_M28() {
2564 2649
     char* codepos = strchr_pointer + 4;
2565
-    char* starpos = strchr(strchr_pointer + 4, '*');
2650
+    char* starpos = strchr(codepos, '*');
2566 2651
     if (starpos) {
2567 2652
       char* npos = strchr(cmdbuffer[bufindr], 'N');
2568 2653
       strchr_pointer = strchr(npos, ' ') + 1;
2569 2654
       *(starpos) = '\0';
2570 2655
     }
2571
-    card.openFile(strchr_pointer + 4, false);
2656
+    card.openFile(codepos, false);
2572 2657
   }
2573 2658
 
2574 2659
   /**
@@ -3355,9 +3440,9 @@ inline void gcode_M114() {
3355 3440
     SERIAL_PROTOCOLLN("");
3356 3441
     
3357 3442
     SERIAL_PROTOCOLPGM("SCARA Cal - Theta:");
3358
-    SERIAL_PROTOCOL(delta[X_AXIS]+add_homing[X_AXIS]);
3443
+    SERIAL_PROTOCOL(delta[X_AXIS]+home_offset[X_AXIS]);
3359 3444
     SERIAL_PROTOCOLPGM("   Psi+Theta (90):");
3360
-    SERIAL_PROTOCOL(delta[Y_AXIS]-delta[X_AXIS]-90+add_homing[Y_AXIS]);
3445
+    SERIAL_PROTOCOL(delta[Y_AXIS]-delta[X_AXIS]-90+home_offset[Y_AXIS]);
3361 3446
     SERIAL_PROTOCOLLN("");
3362 3447
     
3363 3448
     SERIAL_PROTOCOLPGM("SCARA step Cal - Theta:");
@@ -3575,12 +3660,12 @@ inline void gcode_M205() {
3575 3660
 inline void gcode_M206() {
3576 3661
   for (int8_t i=X_AXIS; i <= Z_AXIS; i++) {
3577 3662
     if (code_seen(axis_codes[i])) {
3578
-      add_homing[i] = code_value();
3663
+      home_offset[i] = code_value();
3579 3664
     }
3580 3665
   }
3581 3666
   #ifdef SCARA
3582
-    if (code_seen('T')) add_homing[X_AXIS] = code_value(); // Theta
3583
-    if (code_seen('P')) add_homing[Y_AXIS] = code_value(); // Psi
3667
+    if (code_seen('T')) home_offset[X_AXIS] = code_value(); // Theta
3668
+    if (code_seen('P')) home_offset[Y_AXIS] = code_value(); // Psi
3584 3669
   #endif
3585 3670
 }
3586 3671
 
@@ -3967,18 +4052,13 @@ inline void gcode_M303() {
3967 4052
 }
3968 4053
 
3969 4054
 #ifdef SCARA
3970
-
3971
-  /**
3972
-   * M360: SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
3973
-   */
3974
-  inline bool gcode_M360() {
3975
-    SERIAL_ECHOLN(" Cal: Theta 0 ");
4055
+  bool SCARA_move_to_cal(uint8_t delta_x, uint8_t delta_y) {
3976 4056
     //SoftEndsEnabled = false;              // Ignore soft endstops during calibration
3977 4057
     //SERIAL_ECHOLN(" Soft endstops disabled ");
3978 4058
     if (! Stopped) {
3979 4059
       //get_coordinates(); // For X Y Z E F
3980
-      delta[X_AXIS] = 0;
3981
-      delta[Y_AXIS] = 120;
4060
+      delta[X_AXIS] = delta_x;
4061
+      delta[Y_AXIS] = delta_y;
3982 4062
       calculate_SCARA_forward_Transform(delta);
3983 4063
       destination[X_AXIS] = delta[X_AXIS]/axis_scaling[X_AXIS];
3984 4064
       destination[Y_AXIS] = delta[Y_AXIS]/axis_scaling[Y_AXIS];
@@ -3990,24 +4070,19 @@ inline void gcode_M303() {
3990 4070
   }
3991 4071
 
3992 4072
   /**
4073
+   * M360: SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
4074
+   */
4075
+  inline bool gcode_M360() {
4076
+    SERIAL_ECHOLN(" Cal: Theta 0 ");
4077
+    return SCARA_move_to_cal(0, 120);
4078
+  }
4079
+
4080
+  /**
3993 4081
    * M361: SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
3994 4082
    */
3995 4083
   inline bool gcode_M361() {
3996 4084
     SERIAL_ECHOLN(" Cal: Theta 90 ");
3997
-    //SoftEndsEnabled = false;              // Ignore soft endstops during calibration
3998
-    //SERIAL_ECHOLN(" Soft endstops disabled ");
3999
-    if (! Stopped) {
4000
-      //get_coordinates(); // For X Y Z E F
4001
-      delta[X_AXIS] = 90;
4002
-      delta[Y_AXIS] = 130;
4003
-      calculate_SCARA_forward_Transform(delta);
4004
-      destination[X_AXIS] = delta[X_AXIS]/axis_scaling[X_AXIS];
4005
-      destination[Y_AXIS] = delta[Y_AXIS]/axis_scaling[Y_AXIS];
4006
-      prepare_move();
4007
-      //ClearToSend();
4008
-      return true;
4009
-    }
4010
-    return false;
4085
+    return SCARA_move_to_cal(90, 130);
4011 4086
   }
4012 4087
 
4013 4088
   /**
@@ -4015,20 +4090,7 @@ inline void gcode_M303() {
4015 4090
    */
4016 4091
   inline bool gcode_M362() {
4017 4092
     SERIAL_ECHOLN(" Cal: Psi 0 ");
4018
-    //SoftEndsEnabled = false;              // Ignore soft endstops during calibration
4019
-    //SERIAL_ECHOLN(" Soft endstops disabled ");
4020
-    if (! Stopped) {
4021
-      //get_coordinates(); // For X Y Z E F
4022
-      delta[X_AXIS] = 60;
4023
-      delta[Y_AXIS] = 180;
4024
-      calculate_SCARA_forward_Transform(delta);
4025
-      destination[X_AXIS] = delta[X_AXIS]/axis_scaling[X_AXIS];
4026
-      destination[Y_AXIS] = delta[Y_AXIS]/axis_scaling[Y_AXIS];
4027
-      prepare_move();
4028
-      //ClearToSend();
4029
-      return true;
4030
-    }
4031
-    return false;
4093
+    return SCARA_move_to_cal(60, 180);
4032 4094
   }
4033 4095
 
4034 4096
   /**
@@ -4036,20 +4098,7 @@ inline void gcode_M303() {
4036 4098
    */
4037 4099
   inline bool gcode_M363() {
4038 4100
     SERIAL_ECHOLN(" Cal: Psi 90 ");
4039
-    //SoftEndsEnabled = false;              // Ignore soft endstops during calibration
4040
-    //SERIAL_ECHOLN(" Soft endstops disabled ");
4041
-    if (! Stopped) {
4042
-      //get_coordinates(); // For X Y Z E F
4043
-      delta[X_AXIS] = 50;
4044
-      delta[Y_AXIS] = 90;
4045
-      calculate_SCARA_forward_Transform(delta);
4046
-      destination[X_AXIS] = delta[X_AXIS]/axis_scaling[X_AXIS];
4047
-      destination[Y_AXIS] = delta[Y_AXIS]/axis_scaling[Y_AXIS];
4048
-      prepare_move();
4049
-      //ClearToSend();
4050
-      return true;
4051
-    }
4052
-    return false;
4101
+    return SCARA_move_to_cal(50, 90);
4053 4102
   }
4054 4103
 
4055 4104
   /**
@@ -4057,20 +4106,7 @@ inline void gcode_M303() {
4057 4106
    */
4058 4107
   inline bool gcode_M364() {
4059 4108
     SERIAL_ECHOLN(" Cal: Theta-Psi 90 ");
4060
-   // SoftEndsEnabled = false;              // Ignore soft endstops during calibration
4061
-    //SERIAL_ECHOLN(" Soft endstops disabled ");
4062
-    if (! Stopped) {
4063
-      //get_coordinates(); // For X Y Z E F
4064
-      delta[X_AXIS] = 45;
4065
-      delta[Y_AXIS] = 135;
4066
-      calculate_SCARA_forward_Transform(delta);
4067
-      destination[X_AXIS] = delta[X_AXIS] / axis_scaling[X_AXIS];
4068
-      destination[Y_AXIS] = delta[Y_AXIS] / axis_scaling[Y_AXIS];
4069
-      prepare_move();
4070
-      //ClearToSend();
4071
-      return true;
4072
-    }
4073
-    return false;
4109
+    return SCARA_move_to_cal(45, 135);
4074 4110
   }
4075 4111
 
4076 4112
   /**
@@ -4661,6 +4697,12 @@ void process_commands() {
4661 4697
       gcode_G28();
4662 4698
       break;
4663 4699
 
4700
+    #if defined(MESH_BED_LEVELING)
4701
+      case 29: // G29 Handle mesh based leveling
4702
+        gcode_G29();
4703
+        break;
4704
+    #endif
4705
+
4664 4706
     #ifdef ENABLE_AUTO_BED_LEVELING
4665 4707
 
4666 4708
       case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
@@ -5172,7 +5214,7 @@ void clamp_to_software_endstops(float target[3])
5172 5214
     float negative_z_offset = 0;
5173 5215
     #ifdef ENABLE_AUTO_BED_LEVELING
5174 5216
       if (Z_PROBE_OFFSET_FROM_EXTRUDER < 0) negative_z_offset = negative_z_offset + Z_PROBE_OFFSET_FROM_EXTRUDER;
5175
-      if (add_homing[Z_AXIS] < 0) negative_z_offset = negative_z_offset + add_homing[Z_AXIS];
5217
+      if (home_offset[Z_AXIS] < 0) negative_z_offset = negative_z_offset + home_offset[Z_AXIS];
5176 5218
     #endif
5177 5219
     
5178 5220
     if (target[Z_AXIS] < min_pos[Z_AXIS]+negative_z_offset) target[Z_AXIS] = min_pos[Z_AXIS]+negative_z_offset;
@@ -5280,6 +5322,81 @@ void prepare_move_raw()
5280 5322
 }
5281 5323
 #endif //DELTA
5282 5324
 
5325
+#if defined(MESH_BED_LEVELING)
5326
+#if !defined(MIN)
5327
+#define MIN(_v1, _v2) (((_v1) < (_v2)) ? (_v1) : (_v2))
5328
+#endif  // ! MIN
5329
+// This function is used to split lines on mesh borders so each segment is only part of one mesh area
5330
+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)
5331
+{
5332
+  if (!mbl.active) {
5333
+    plan_buffer_line(x, y, z, e, feed_rate, extruder);
5334
+    for(int8_t i=0; i < NUM_AXIS; i++) {
5335
+      current_position[i] = destination[i];
5336
+    }
5337
+    return;
5338
+  }
5339
+  int pix = mbl.select_x_index(current_position[X_AXIS]);
5340
+  int piy = mbl.select_y_index(current_position[Y_AXIS]);
5341
+  int ix = mbl.select_x_index(x);
5342
+  int iy = mbl.select_y_index(y);
5343
+  pix = MIN(pix, MESH_NUM_X_POINTS-2);
5344
+  piy = MIN(piy, MESH_NUM_Y_POINTS-2);
5345
+  ix = MIN(ix, MESH_NUM_X_POINTS-2);
5346
+  iy = MIN(iy, MESH_NUM_Y_POINTS-2);
5347
+  if (pix == ix && piy == iy) {
5348
+    // Start and end on same mesh square
5349
+    plan_buffer_line(x, y, z, e, feed_rate, extruder);
5350
+    for(int8_t i=0; i < NUM_AXIS; i++) {
5351
+      current_position[i] = destination[i];
5352
+    }
5353
+    return;
5354
+  }
5355
+  float nx, ny, ne, normalized_dist;
5356
+  if (ix > pix && (x_splits) & BIT(ix)) {
5357
+    nx = mbl.get_x(ix);
5358
+    normalized_dist = (nx - current_position[X_AXIS])/(x - current_position[X_AXIS]);
5359
+    ny = current_position[Y_AXIS] + (y - current_position[Y_AXIS]) * normalized_dist;
5360
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5361
+    x_splits ^= BIT(ix);
5362
+  } else if (ix < pix && (x_splits) & BIT(pix)) {
5363
+    nx = mbl.get_x(pix);
5364
+    normalized_dist = (nx - current_position[X_AXIS])/(x - current_position[X_AXIS]);
5365
+    ny = current_position[Y_AXIS] + (y - current_position[Y_AXIS]) * normalized_dist;
5366
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5367
+    x_splits ^= BIT(pix);
5368
+  } else if (iy > piy && (y_splits) & BIT(iy)) {
5369
+    ny = mbl.get_y(iy);
5370
+    normalized_dist = (ny - current_position[Y_AXIS])/(y - current_position[Y_AXIS]);
5371
+    nx = current_position[X_AXIS] + (x - current_position[X_AXIS]) * normalized_dist;
5372
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5373
+    y_splits ^= BIT(iy);
5374
+  } else if (iy < piy && (y_splits) & BIT(piy)) {
5375
+    ny = mbl.get_y(piy);
5376
+    normalized_dist = (ny - current_position[Y_AXIS])/(y - current_position[Y_AXIS]);
5377
+    nx = current_position[X_AXIS] + (x - current_position[X_AXIS]) * normalized_dist;
5378
+    ne = current_position[E_AXIS] + (e - current_position[E_AXIS]) * normalized_dist;
5379
+    y_splits ^= BIT(piy);
5380
+  } else {
5381
+    // Already split on a border
5382
+    plan_buffer_line(x, y, z, e, feed_rate, extruder);
5383
+    for(int8_t i=0; i < NUM_AXIS; i++) {
5384
+      current_position[i] = destination[i];
5385
+    }
5386
+    return;
5387
+  }
5388
+  // Do the split and look for more borders
5389
+  destination[X_AXIS] = nx;
5390
+  destination[Y_AXIS] = ny;
5391
+  destination[E_AXIS] = ne;
5392
+  mesh_plan_buffer_line(nx, ny, z, ne, feed_rate, extruder, x_splits, y_splits);
5393
+  destination[X_AXIS] = x;
5394
+  destination[Y_AXIS] = y;
5395
+  destination[E_AXIS] = e;
5396
+  mesh_plan_buffer_line(x, y, z, e, feed_rate, extruder, x_splits, y_splits);
5397
+}
5398
+#endif  // MESH_BED_LEVELING
5399
+
5283 5400
 void prepare_move()
5284 5401
 {
5285 5402
   clamp_to_software_endstops(destination);
@@ -5395,10 +5512,14 @@ for (int s = 1; s <= steps; s++) {
5395 5512
 #if ! (defined DELTA || defined SCARA)
5396 5513
   // Do not use feedmultiply for E or Z only moves
5397 5514
   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 {
5515
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
5516
+  } else {
5517
+#if defined(MESH_BED_LEVELING)
5518
+    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
5519
+    return;
5520
+#else
5401 5521
     plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
5522
+#endif  // MESH_BED_LEVELING
5402 5523
   }
5403 5524
 #endif // !(DELTA || SCARA)
5404 5525
 

+ 2
- 2
Marlin/SdBaseFile.h Переглянути файл

@@ -171,9 +171,9 @@ static inline uint8_t FAT_SECOND(uint16_t fatTime) {
171 171
   return 2*(fatTime & 0X1F);
172 172
 }
173 173
 /** Default date for file timestamps is 1 Jan 2000 */
174
-uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | BIT(5) | 1;
174
+uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
175 175
 /** Default time for file timestamp is 1 am */
176
-uint16_t const FAT_DEFAULT_TIME = BIT(11);
176
+uint16_t const FAT_DEFAULT_TIME = (1 << 11);
177 177
 //------------------------------------------------------------------------------
178 178
 /**
179 179
  * \class SdBaseFile

+ 2
- 6
Marlin/configurator/config/Configuration.h Переглянути файл

@@ -234,6 +234,8 @@ Here are some standard links for getting your machine calibrated:
234 234
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
235 235
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
236 236
 
237
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
238
+
237 239
 #ifdef PIDTEMPBED
238 240
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
239 241
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -438,12 +440,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
438 440
 
439 441
   #ifdef AUTO_BED_LEVELING_GRID
440 442
 
441
-    // Use one of these defines to specify the origin
442
-    // for a topographical map to be printed for your bed.
443
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
444
-    #define TOPO_ORIGIN OriginFrontLeft
445
-
446
-    // The edges of the rectangle in which to probe
447 443
     #define LEFT_PROBE_BED_POSITION 15
448 444
     #define RIGHT_PROBE_BED_POSITION 170
449 445
     #define FRONT_PROBE_BED_POSITION 20

+ 71
- 94
Marlin/dogm_lcd_implementation.h Переглянути файл

@@ -139,7 +139,7 @@ static void lcd_implementation_init()
139 139
       u8g.drawStr(txt1X, u8g.getHeight() - DOG_CHAR_HEIGHT*3/2, STRING_SPLASH_LINE1);
140 140
       u8g.drawStr(txt2X, u8g.getHeight() - DOG_CHAR_HEIGHT*1/2, STRING_SPLASH_LINE2);
141 141
     #endif
142
-	} while(u8g.nextPage());
142
+	} while (u8g.nextPage());
143 143
 }
144 144
 
145 145
 static void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
@@ -197,7 +197,7 @@ static void lcd_implementation_status_screen() {
197 197
       u8g.drawBox(55, 50, (unsigned int)(71.f * card.percentDone() / 100.f), 2);
198 198
     }
199 199
 
200
-    u8g.setPrintPos(80,47);
200
+    u8g.setPrintPos(80,48);
201 201
     if (starttime != 0) {
202 202
       uint16_t time = (millis() - starttime) / 60000;
203 203
       u8g.print(itostr2(time/60));
@@ -222,7 +222,7 @@ static void lcd_implementation_status_screen() {
222 222
     int per = ((fanSpeed + 1) * 100) / 256;
223 223
     if (per) {
224 224
       u8g.print(itostr3(per));
225
-      u8g.print("%");
225
+      u8g.print('%');
226 226
     }
227 227
     else
228 228
   #endif
@@ -231,26 +231,27 @@ static void lcd_implementation_status_screen() {
231 231
     }
232 232
 
233 233
   // X, Y, Z-Coordinates
234
+  #define XYZ_BASELINE 38
234 235
   u8g.setFont(FONT_STATUSMENU);
235
-  u8g.drawBox(0,29,128,10);
236
+  u8g.drawBox(0,30,128,9);
236 237
   u8g.setColorIndex(0); // white on black
237
-  u8g.setPrintPos(2,37);
238
-  u8g.print("X");
239
-  u8g.drawPixel(8,33);
240
-  u8g.drawPixel(8,35);
241
-  u8g.setPrintPos(10,37);
238
+  u8g.setPrintPos(2,XYZ_BASELINE);
239
+  u8g.print('X');
240
+  u8g.drawPixel(8,XYZ_BASELINE - 5);
241
+  u8g.drawPixel(8,XYZ_BASELINE - 3);
242
+  u8g.setPrintPos(10,XYZ_BASELINE);
242 243
   u8g.print(ftostr31ns(current_position[X_AXIS]));
243
-  u8g.setPrintPos(43,37);
244
-  lcd_printPGM(PSTR("Y"));
245
-  u8g.drawPixel(49,33);
246
-  u8g.drawPixel(49,35);
247
-  u8g.setPrintPos(51,37);
244
+  u8g.setPrintPos(43,XYZ_BASELINE);
245
+  u8g.print('Y');
246
+  u8g.drawPixel(49,XYZ_BASELINE - 5);
247
+  u8g.drawPixel(49,XYZ_BASELINE - 3);
248
+  u8g.setPrintPos(51,XYZ_BASELINE);
248 249
   u8g.print(ftostr31ns(current_position[Y_AXIS]));
249
-  u8g.setPrintPos(83,37);
250
-  u8g.print("Z");
251
-  u8g.drawPixel(89,33);
252
-  u8g.drawPixel(89,35);
253
-  u8g.setPrintPos(91,37);
250
+  u8g.setPrintPos(83,XYZ_BASELINE);
251
+  u8g.print('Z');
252
+  u8g.drawPixel(89,XYZ_BASELINE - 5);
253
+  u8g.drawPixel(89,XYZ_BASELINE - 3);
254
+  u8g.setPrintPos(91,XYZ_BASELINE);
254 255
   u8g.print(ftostr31(current_position[Z_AXIS]));
255 256
   u8g.setColorIndex(1); // black on white
256 257
  
@@ -259,13 +260,13 @@ static void lcd_implementation_status_screen() {
259 260
   u8g.setPrintPos(3,49);
260 261
   u8g.print(LCD_STR_FEEDRATE[0]);
261 262
   u8g.setFont(FONT_STATUSMENU);
262
-  u8g.setPrintPos(12,48);
263
+  u8g.setPrintPos(12,49);
263 264
   u8g.print(itostr3(feedmultiply));
264 265
   u8g.print('%');
265 266
 
266 267
   // Status line
267 268
   u8g.setFont(FONT_STATUSMENU);
268
-  u8g.setPrintPos(0,61);
269
+  u8g.setPrintPos(0,63);
269 270
   #ifndef FILAMENT_LCD_DISPLAY
270 271
     u8g.print(lcd_status_message);
271 272
   #else
@@ -282,10 +283,10 @@ static void lcd_implementation_status_screen() {
282 283
   #endif
283 284
 }
284 285
 
285
-static void lcd_implementation_mark_as_selected(uint8_t row, char pr_char) {
286
-  if ((pr_char == '>') || (pr_char == LCD_STR_UPLEVEL[0] )) {
286
+static void lcd_implementation_mark_as_selected(uint8_t row, bool isSelected) {
287
+  if (isSelected) {
287 288
     u8g.setColorIndex(1);  // black on white
288
-    u8g.drawBox (0, row*DOG_CHAR_HEIGHT + 3, 128, DOG_CHAR_HEIGHT);
289
+    u8g.drawBox(0, row * DOG_CHAR_HEIGHT + 3, 128, DOG_CHAR_HEIGHT);
289 290
     u8g.setColorIndex(0);  // following text must be white on black
290 291
   }
291 292
   else {
@@ -294,98 +295,80 @@ static void lcd_implementation_mark_as_selected(uint8_t row, char pr_char) {
294 295
   u8g.setPrintPos(START_ROW * DOG_CHAR_WIDTH, (row + 1) * DOG_CHAR_HEIGHT);
295 296
 }
296 297
 
297
-static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char) {
298
+static void lcd_implementation_drawmenu_generic(bool isSelected, uint8_t row, const char* pstr, char pre_char, char post_char) {
298 299
   char c;
299 300
   uint8_t n = LCD_WIDTH - 2;
300 301
 
301
-  lcd_implementation_mark_as_selected(row, pre_char);
302
+  lcd_implementation_mark_as_selected(row, isSelected);
302 303
 
303
-  while((c = pgm_read_byte(pstr))) {
304
+  while ((c = pgm_read_byte(pstr))) {
304 305
     u8g.print(c);
305 306
     pstr++;
306 307
     n--;
307 308
   }
308
-  while(n--) u8g.print(' ');
309
+  while (n--) u8g.print(' ');
309 310
   u8g.print(post_char);
310 311
   u8g.print(' ');
311 312
 }
312 313
 
313
-static void _drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, const char* data, bool pgm) {
314
+static void _drawmenu_setting_edit_generic(bool isSelected, uint8_t row, const char* pstr, const char* data, bool pgm) {
314 315
   char c;
315 316
   uint8_t n = LCD_WIDTH - 2 - (pgm ? lcd_strlen_P(data) : (lcd_strlen((char*)data)));
316 317
 
317
-  lcd_implementation_mark_as_selected(row, pre_char);
318
+  lcd_implementation_mark_as_selected(row, isSelected);
318 319
 
319
-  while( (c = pgm_read_byte(pstr))) {
320
+  while ((c = pgm_read_byte(pstr))) {
320 321
     u8g.print(c);
321 322
     pstr++;
322 323
     n--;
323 324
   }
324 325
   u8g.print(':');
325
-  while(n--) u8g.print(' ');
326
+  while (n--) u8g.print(' ');
326 327
   if (pgm) { lcd_printPGM(data); } else { u8g.print(data); }
327 328
 }
328 329
 
329
-#define lcd_implementation_drawmenu_setting_edit_generic(row, pstr, pre_char, data) _drawmenu_setting_edit_generic(row, pstr, pre_char, data, false)
330
-#define lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, pre_char, data) _drawmenu_setting_edit_generic(row, pstr, pre_char, data, true)
331
-
332
-#define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))
333
-#define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))
334
-#define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))
335
-#define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))
336
-#define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))
337
-#define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))
338
-#define lcd_implementation_drawmenu_setting_edit_float43_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data)))
339
-#define lcd_implementation_drawmenu_setting_edit_float43(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data)))
340
-#define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
341
-#define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
342
-#define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))
343
-#define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))
344
-#define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))
345
-#define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))
346
-#define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
347
-#define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
348
-#define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
349
-#define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
330
+#define lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, false)
331
+#define lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, data) _drawmenu_setting_edit_generic(sel, row, pstr, data, true)
332
+
333
+#define lcd_implementation_drawmenu_setting_edit_int3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data)))
334
+#define lcd_implementation_drawmenu_setting_edit_float3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data)))
335
+#define lcd_implementation_drawmenu_setting_edit_float32(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data)))
336
+#define lcd_implementation_drawmenu_setting_edit_float43(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43(*(data)))
337
+#define lcd_implementation_drawmenu_setting_edit_float5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
338
+#define lcd_implementation_drawmenu_setting_edit_float52(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52(*(data)))
339
+#define lcd_implementation_drawmenu_setting_edit_float51(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51(*(data)))
340
+#define lcd_implementation_drawmenu_setting_edit_long5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
341
+#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
350 342
 
351 343
 //Add version for callback functions
352
-#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))
353
-#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))
354
-#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))
355
-#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))
356
-#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))
357
-#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))
358
-#define lcd_implementation_drawmenu_setting_edit_callback_float43_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data)))
359
-#define lcd_implementation_drawmenu_setting_edit_callback_float43(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data)))
360
-#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
361
-#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
362
-#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))
363
-#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))
364
-#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))
365
-#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))
366
-#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
367
-#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
368
-#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
369
-#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
344
+#define lcd_implementation_drawmenu_setting_edit_callback_int3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, itostr3(*(data)))
345
+#define lcd_implementation_drawmenu_setting_edit_callback_float3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr3(*(data)))
346
+#define lcd_implementation_drawmenu_setting_edit_callback_float32(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr32(*(data)))
347
+#define lcd_implementation_drawmenu_setting_edit_callback_float43(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr43(*(data)))
348
+#define lcd_implementation_drawmenu_setting_edit_callback_float5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
349
+#define lcd_implementation_drawmenu_setting_edit_callback_float52(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr52(*(data)))
350
+#define lcd_implementation_drawmenu_setting_edit_callback_float51(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr51(*(data)))
351
+#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, ftostr5(*(data)))
352
+#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
370 353
 
371 354
 void lcd_implementation_drawedit(const char* pstr, char* value) {
372 355
   uint8_t rows = 1;
373
-  uint8_t lcd_width = LCD_WIDTH;
374
-  uint8_t char_width = DOG_CHAR_WIDTH;
356
+  uint8_t lcd_width = LCD_WIDTH, char_width = DOG_CHAR_WIDTH;
357
+  uint8_t vallen = lcd_strlen(value);
375 358
 
376 359
   #ifdef USE_BIG_EDIT_FONT
377 360
     if (lcd_strlen_P(pstr) <= LCD_WIDTH_EDIT - 1) {
378 361
       u8g.setFont(FONT_MENU_EDIT);
379 362
       lcd_width = LCD_WIDTH_EDIT + 1;
380 363
       char_width = DOG_CHAR_WIDTH_EDIT;
381
-      if (lcd_strlen_P(pstr) >= LCD_WIDTH_EDIT - lcd_strlen(value)) rows = 2;
364
+      if (lcd_strlen_P(pstr) >= LCD_WIDTH_EDIT - vallen) rows = 2;
382 365
     }
383 366
     else {
384 367
       u8g.setFont(FONT_MENU);
385 368
     }
386 369
   #endif
387 370
 
388
-  if (lcd_strlen_P(pstr) > LCD_WIDTH - 2 - lcd_strlen(value)) rows = 2;
371
+  if (lcd_strlen_P(pstr) > LCD_WIDTH - 2 - vallen) rows = 2;
389 372
 
390 373
   const float kHalfChar = DOG_CHAR_HEIGHT_EDIT / 2;
391 374
   float rowHeight = u8g.getHeight() / (rows + 1); // 1/(rows+1) = 1/2 or 1/3
@@ -393,43 +376,37 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
393 376
   u8g.setPrintPos(0, rowHeight + kHalfChar);
394 377
   lcd_printPGM(pstr);
395 378
   u8g.print(':');
396
-  u8g.setPrintPos((lcd_width-1-lcd_strlen(value)) * char_width, rows * rowHeight + kHalfChar);
379
+  u8g.setPrintPos((lcd_width - 1 - vallen) * char_width, rows * rowHeight + kHalfChar);
397 380
   u8g.print(value);
398 381
 }
399 382
 
400
-static void _drawmenu_sd(uint8_t row, const char* pstr, const char* filename, char * const longFilename, bool isDir, bool isSelected) {
383
+static void _drawmenu_sd(bool isSelected, uint8_t row, const char* pstr, const char* filename, char * const longFilename, bool isDir) {
401 384
   char c;
402 385
   uint8_t n = LCD_WIDTH - 1;
403 386
 
404
-  if (longFilename[0] != '\0') {
387
+  if (longFilename[0]) {
405 388
     filename = longFilename;
406 389
     longFilename[n] = '\0';
407 390
   }
408 391
 
409
-  lcd_implementation_mark_as_selected(row, ((isSelected) ? '>' : ' '));
392
+  lcd_implementation_mark_as_selected(row, isSelected);
410 393
 
411 394
   if (isDir) u8g.print(LCD_STR_FOLDER[0]);
412
-  while((c = *filename) != '\0') {
395
+  while ((c = *filename)) {
413 396
     u8g.print(c);
414 397
     filename++;
415 398
     n--;
416 399
   }
417
-  while(n--) u8g.print(' ');
400
+  while (n--) u8g.print(' ');
418 401
 }
419 402
 
420
-#define lcd_implementation_drawmenu_sdfile_selected(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, false, true)
421
-#define lcd_implementation_drawmenu_sdfile(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, false, false)
422
-#define lcd_implementation_drawmenu_sddirectory_selected(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, true, true)
423
-#define lcd_implementation_drawmenu_sddirectory(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, true, false)
424
-
425
-#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
426
-#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0])
427
-#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
428
-#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0])
429
-#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
430
-#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
431
-#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
432
-#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
403
+#define lcd_implementation_drawmenu_sdfile(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, false)
404
+#define lcd_implementation_drawmenu_sddirectory(sel, row, pstr, filename, longFilename) _drawmenu_sd(sel, row, pstr, filename, longFilename, true)
405
+
406
+#define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
407
+#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
408
+#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
409
+#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
433 410
 
434 411
 static void lcd_implementation_quick_feedback() {
435 412
   #if BEEPER > -1

+ 2
- 6
Marlin/example_configurations/Felix/Configuration.h Переглянути файл

@@ -215,6 +215,8 @@ Here are some standard links for getting your machine calibrated:
215 215
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
216 216
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
217 217
 
218
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
219
+
218 220
 #ifdef PIDTEMPBED
219 221
 // Felix Foil Heater
220 222
    #define DEFAULT_bedKp 103.37
@@ -384,12 +386,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
384 386
   // Note: this feature occupies 10'206 byte
385 387
   #ifdef AUTO_BED_LEVELING_GRID
386 388
 
387
-    // Use one of these defines to specify the origin
388
-    // for a topographical map to be printed for your bed.
389
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
390
-    #define TOPO_ORIGIN OriginFrontLeft
391
-
392
-    // set the rectangle in which to probe
393 389
     #define LEFT_PROBE_BED_POSITION 15
394 390
     #define RIGHT_PROBE_BED_POSITION 170
395 391
     #define BACK_PROBE_BED_POSITION 180

+ 2
- 6
Marlin/example_configurations/Felix/Configuration_DUAL.h Переглянути файл

@@ -215,6 +215,8 @@ Here are some standard links for getting your machine calibrated:
215 215
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
216 216
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
217 217
 
218
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
219
+
218 220
 #ifdef PIDTEMPBED
219 221
 // Felix Foil Heater
220 222
    #define DEFAULT_bedKp 103.37
@@ -384,12 +386,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
384 386
   // Note: this feature occupies 10'206 byte
385 387
   #ifdef AUTO_BED_LEVELING_GRID
386 388
 
387
-    // Use one of these defines to specify the origin
388
-    // for a topographical map to be printed for your bed.
389
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
390
-    #define TOPO_ORIGIN OriginFrontLeft
391
-
392
-    // set the rectangle in which to probe
393 389
     #define LEFT_PROBE_BED_POSITION 15
394 390
     #define RIGHT_PROBE_BED_POSITION 170
395 391
     #define BACK_PROBE_BED_POSITION 180

+ 2
- 6
Marlin/example_configurations/Hephestos/Configuration.h Переглянути файл

@@ -231,6 +231,8 @@ Here are some standard links for getting your machine calibrated:
231 231
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
232 232
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
233 233
 
234
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
235
+
234 236
 #ifdef PIDTEMPBED
235 237
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
236 238
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -408,12 +410,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
408 410
 
409 411
   #ifdef AUTO_BED_LEVELING_GRID
410 412
 
411
-    // Use one of these defines to specify the origin
412
-    // for a topographical map to be printed for your bed.
413
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
414
-    #define TOPO_ORIGIN OriginFrontLeft
415
-
416
-    // The edges of the rectangle in which to probe
417 413
     #define LEFT_PROBE_BED_POSITION 15
418 414
     #define RIGHT_PROBE_BED_POSITION 170
419 415
     #define FRONT_PROBE_BED_POSITION 20

+ 2
- 6
Marlin/example_configurations/K8200/Configuration.h Переглянути файл

@@ -230,6 +230,8 @@ Here are some standard links for getting your machine calibrated:
230 230
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
231 231
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
232 232
 
233
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
234
+
233 235
 #ifdef PIDTEMPBED
234 236
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
235 237
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -413,12 +415,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
413 415
 
414 416
   #ifdef AUTO_BED_LEVELING_GRID
415 417
 
416
-    // Use one of these defines to specify the origin
417
-    // for a topographical map to be printed for your bed.
418
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
419
-    #define TOPO_ORIGIN OriginFrontLeft
420
-
421
-    // The edges of the rectangle in which to probe
422 418
     #define LEFT_PROBE_BED_POSITION 15
423 419
     #define RIGHT_PROBE_BED_POSITION 170
424 420
     #define FRONT_PROBE_BED_POSITION 20

+ 2
- 6
Marlin/example_configurations/SCARA/Configuration.h Переглянути файл

@@ -254,6 +254,8 @@ Here are some standard links for getting your machine calibrated:
254 254
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
255 255
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
256 256
 
257
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
258
+
257 259
 #ifdef PIDTEMPBED
258 260
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
259 261
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -437,12 +439,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
437 439
 
438 440
   #ifdef AUTO_BED_LEVELING_GRID
439 441
 
440
-    // Use one of these defines to specify the origin
441
-    // for a topographical map to be printed for your bed.
442
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
443
-    #define TOPO_ORIGIN OriginFrontLeft
444
-
445
-    // The edges of the rectangle in which to probe
446 442
     #define LEFT_PROBE_BED_POSITION 15
447 443
     #define RIGHT_PROBE_BED_POSITION 170
448 444
     #define FRONT_PROBE_BED_POSITION 20

+ 2
- 6
Marlin/example_configurations/WITBOX/Configuration.h Переглянути файл

@@ -230,6 +230,8 @@ Here are some standard links for getting your machine calibrated:
230 230
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
231 231
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
232 232
 
233
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
234
+
233 235
 #ifdef PIDTEMPBED
234 236
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
235 237
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -407,12 +409,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
407 409
 
408 410
   #ifdef AUTO_BED_LEVELING_GRID
409 411
 
410
-    // Use one of these defines to specify the origin
411
-    // for a topographical map to be printed for your bed.
412
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
413
-    #define TOPO_ORIGIN OriginFrontLeft
414
-
415
-    // The edges of the rectangle in which to probe
416 412
     #define LEFT_PROBE_BED_POSITION 15
417 413
     #define RIGHT_PROBE_BED_POSITION 170
418 414
     #define FRONT_PROBE_BED_POSITION 20

+ 2
- 0
Marlin/example_configurations/delta/generic/Configuration.h Переглянути файл

@@ -258,6 +258,8 @@ Here are some standard links for getting your machine calibrated:
258 258
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
259 259
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
260 260
 
261
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
262
+
261 263
 #ifdef PIDTEMPBED
262 264
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
263 265
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)

+ 2
- 0
Marlin/example_configurations/delta/kossel_mini/Configuration.h Переглянути файл

@@ -259,6 +259,8 @@ Here are some standard links for getting your machine calibrated:
259 259
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
260 260
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
261 261
 
262
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
263
+
262 264
 #ifdef PIDTEMPBED
263 265
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
264 266
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)

+ 2
- 6
Marlin/example_configurations/makibox/Configuration.h Переглянути файл

@@ -228,6 +228,8 @@ Here are some standard links for getting your machine calibrated:
228 228
 // to increase the heat up rate. However, if changed, user must be aware of the safety concerns
229 229
 // of drawing too much current from the power supply.
230 230
 
231
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
232
+
231 233
 #ifdef PIDTEMPBED
232 234
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
233 235
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -405,12 +407,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
405 407
 
406 408
   #ifdef AUTO_BED_LEVELING_GRID
407 409
 
408
-    // Use one of these defines to specify the origin
409
-    // for a topographical map to be printed for your bed.
410
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
411
-    #define TOPO_ORIGIN OriginFrontLeft
412
-
413
-    // The edges of the rectangle in which to probe
414 410
     #define LEFT_PROBE_BED_POSITION 15
415 411
     #define RIGHT_PROBE_BED_POSITION 170
416 412
     #define FRONT_PROBE_BED_POSITION 20

+ 2
- 6
Marlin/example_configurations/tvrrug/Round2/Configuration.h Переглянути файл

@@ -230,6 +230,8 @@ Here are some standard links for getting your machine calibrated:
230 230
 // so you shouldn't use it unless you are OK with PWM on your bed.  (see the comment on enabling PIDTEMPBED)
231 231
 #define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
232 232
 
233
+//#define PID_BED_DEBUG // Sends debug data to the serial port.
234
+
233 235
 #ifdef PIDTEMPBED
234 236
 //120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
235 237
 //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
@@ -407,12 +409,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
407 409
 
408 410
   #ifdef AUTO_BED_LEVELING_GRID
409 411
 
410
-    // Use one of these defines to specify the origin
411
-    // for a topographical map to be printed for your bed.
412
-    enum { OriginBackLeft, OriginFrontLeft, OriginBackRight, OriginFrontRight };
413
-    #define TOPO_ORIGIN OriginFrontLeft
414
-
415
-    // The edges of the rectangle in which to probe
416 412
     #define LEFT_PROBE_BED_POSITION 15
417 413
     #define RIGHT_PROBE_BED_POSITION 170
418 414
     #define FRONT_PROBE_BED_POSITION 20

+ 3
- 0
Marlin/language_en.h Переглянути файл

@@ -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

+ 20
- 0
Marlin/mesh_bed_leveling.cpp Переглянути файл

@@ -0,0 +1,20 @@
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 Переглянути файл

@@ -0,0 +1,61 @@
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

+ 20
- 5
Marlin/planner.cpp Переглянути файл

@@ -58,6 +58,10 @@
58 58
 #include "ultralcd.h"
59 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 66
 //============================= public variables ============================
63 67
 //===========================================================================
@@ -530,7 +534,7 @@ float junction_deviation = 0.1;
530 534
 // Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in 
531 535
 // mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
532 536
 // calculation the caller must also provide the physical length of the line in millimeters.
533
-#ifdef ENABLE_AUTO_BED_LEVELING
537
+#if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
534 538
 void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder)
535 539
 #else
536 540
 void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder)
@@ -548,6 +552,12 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
548 552
     lcd_update();
549 553
   }
550 554
 
555
+#if defined(MESH_BED_LEVELING)
556
+  if (mbl.active) {
557
+    z += mbl.get_z(x, y);
558
+  }
559
+#endif  // MESH_BED_LEVELING
560
+
551 561
 #ifdef ENABLE_AUTO_BED_LEVELING
552 562
   apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
553 563
 #endif // ENABLE_AUTO_BED_LEVELING
@@ -1078,14 +1088,19 @@ vector_3 plan_get_position() {
1078 1088
 }
1079 1089
 #endif // ENABLE_AUTO_BED_LEVELING
1080 1090
 
1081
-#ifdef ENABLE_AUTO_BED_LEVELING
1091
+#if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
1082 1092
 void plan_set_position(float x, float y, float z, const float &e)
1083
-{
1084
-  apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
1085 1093
 #else
1086 1094
 void plan_set_position(const float &x, const float &y, const float &z, const float &e)
1095
+#endif  // ENABLE_AUTO_BED_LEVELING || MESH_BED_LEVELING
1087 1096
 {
1088
-#endif // ENABLE_AUTO_BED_LEVELING
1097
+#if defined(ENABLE_AUTO_BED_LEVELING)
1098
+  apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
1099
+#elif defined(MESH_BED_LEVELING)
1100
+  if (mbl.active) {
1101
+    z += mbl.get_z(x, y);
1102
+  }
1103
+#endif  // ENABLE_AUTO_BED_LEVELING
1089 1104
 
1090 1105
   position[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]);
1091 1106
   position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]);

+ 6
- 5
Marlin/planner.h Переглянути файл

@@ -82,23 +82,24 @@ void plan_init();
82 82
 // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in 
83 83
 // millimaters. Feed rate specifies the speed of the motion.
84 84
 
85
-#ifdef ENABLE_AUTO_BED_LEVELING
85
+#if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
86 86
 void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder);
87
-
87
+#if defined(ENABLE_AUTO_BED_LEVELING)
88 88
   #ifndef DELTA
89 89
   // Get the position applying the bed level matrix if enabled
90 90
   vector_3 plan_get_position();
91 91
   #endif
92
+#endif  // ENABLE_AUTO_BED_LEVELING
92 93
 #else
93 94
 void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
94
-#endif // ENABLE_AUTO_BED_LEVELING
95
+#endif  // ENABLE_AUTO_BED_LEVELING || MESH_BED_LEVELING
95 96
 
96 97
 // Set position. Used for G92 instructions.
97
-#ifdef ENABLE_AUTO_BED_LEVELING
98
+#if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
98 99
 void plan_set_position(float x, float y, float z, const float &e);
99 100
 #else
100 101
 void plan_set_position(const float &x, const float &y, const float &z, const float &e);
101
-#endif // ENABLE_AUTO_BED_LEVELING
102
+#endif // ENABLE_AUTO_BED_LEVELING || MESH_BED_LEVELING
102 103
 
103 104
 void plan_set_e_position(const float &e);
104 105
 

+ 8
- 14
Marlin/stepper.cpp Переглянути файл

@@ -89,7 +89,7 @@ static bool old_x_min_endstop = false,
89 89
 static bool check_endstops = true;
90 90
 
91 91
 volatile long count_position[NUM_AXIS] = { 0 };
92
-volatile signed char count_direction[NUM_AXIS] = { 1 };
92
+volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
93 93
 
94 94
 
95 95
 //===========================================================================
@@ -102,11 +102,8 @@ volatile signed char count_direction[NUM_AXIS] = { 1 };
102 102
       X_DIR_WRITE(v); \
103 103
       X2_DIR_WRITE(v); \
104 104
     } \
105
-    else{ \
106
-      if (current_block->active_extruder) \
107
-        X2_DIR_WRITE(v); \
108
-      else \
109
-        X_DIR_WRITE(v); \
105
+    else { \
106
+      if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
110 107
     }
111 108
   #define X_APPLY_STEP(v,ALWAYS) \
112 109
     if (extruder_duplication_enabled || ALWAYS) { \
@@ -114,10 +111,7 @@ volatile signed char count_direction[NUM_AXIS] = { 1 };
114 111
       X2_STEP_WRITE(v); \
115 112
     } \
116 113
     else { \
117
-      if (current_block->active_extruder != 0) \
118
-        X2_STEP_WRITE(v); \
119
-      else \
120
-        X_STEP_WRITE(v); \
114
+      if (current_block->active_extruder != 0) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
121 115
     }
122 116
 #else
123 117
   #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v)
@@ -125,16 +119,16 @@ volatile signed char count_direction[NUM_AXIS] = { 1 };
125 119
 #endif
126 120
 
127 121
 #ifdef Y_DUAL_STEPPER_DRIVERS
128
-  #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v), Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR)
129
-  #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v), Y2_STEP_WRITE(v)
122
+  #define Y_APPLY_DIR(v,Q) { Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }
123
+  #define Y_APPLY_STEP(v,Q) { Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }
130 124
 #else
131 125
   #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v)
132 126
   #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v)
133 127
 #endif
134 128
 
135 129
 #ifdef Z_DUAL_STEPPER_DRIVERS
136
-  #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v), Z2_DIR_WRITE(v)
137
-  #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v), Z2_STEP_WRITE(v)
130
+  #define Z_APPLY_DIR(v,Q) { Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }
131
+  #define Z_APPLY_STEP(v,Q) { Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }
138 132
 #else
139 133
   #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v)
140 134
   #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v)

+ 82
- 34
Marlin/temperature.cpp Переглянути файл

@@ -145,7 +145,7 @@ static volatile bool temp_meas_ready = false;
145 145
   static float temp_iState_min_bed;
146 146
   static float temp_iState_max_bed;
147 147
 #else //PIDTEMPBED
148
-	static unsigned long  previous_millis_bed_heater;
148
+  static unsigned long  previous_millis_bed_heater;
149 149
 #endif //PIDTEMPBED
150 150
   static unsigned char soft_pwm[EXTRUDERS];
151 151
 
@@ -243,7 +243,7 @@ void PID_autotune(float temp, int extruder, int ncycles)
243 243
     SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
244 244
     return;
245 245
   }
246
-	
246
+  
247 247
   SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
248 248
 
249 249
   disable_heater(); // switch off all heaters.
@@ -636,6 +636,21 @@ float get_pid_output(int e) {
636 636
       pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
637 637
     #endif // PID_OPENLOOP
638 638
 
639
+    #ifdef PID_BED_DEBUG
640
+      SERIAL_ECHO_START;
641
+      SERIAL_ECHO(" PID_BED_DEBUG ");
642
+      SERIAL_ECHO(": Input ");
643
+      SERIAL_ECHO(current_temperature_bed);
644
+      SERIAL_ECHO(" Output ");
645
+      SERIAL_ECHO(pid_output);
646
+      SERIAL_ECHO(" pTerm ");
647
+      SERIAL_ECHO(pTerm_bed);
648
+      SERIAL_ECHO(" iTerm ");
649
+      SERIAL_ECHO(iTerm_bed);
650
+      SERIAL_ECHO(" dTerm ");
651
+      SERIAL_ECHOLN(dTerm_bed);
652
+    #endif //PID_BED_DEBUG
653
+
639 654
     return pid_output;
640 655
   }
641 656
 #endif
@@ -740,8 +755,8 @@ void manage_heater() {
740 755
   #ifdef FILAMENT_SENSOR
741 756
     if (filament_sensor) {
742 757
       meas_shift_index = delay_index1 - meas_delay_cm;
743
-		  if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1;  //loop around buffer if needed
744
-		  
758
+      if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1;  //loop around buffer if needed
759
+      
745 760
       // Get the delayed info and add 100 to reconstitute to a percent of
746 761
       // the nominal filament diameter then square it to get an area
747 762
       meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
@@ -1244,10 +1259,7 @@ enum TempState {
1244 1259
 ISR(TIMER0_COMPB_vect) {
1245 1260
   //these variables are only accesible from the ISR, but static, so they don't lose their value
1246 1261
   static unsigned char temp_count = 0;
1247
-  static unsigned long raw_temp_0_value = 0;
1248
-  static unsigned long raw_temp_1_value = 0;
1249
-  static unsigned long raw_temp_2_value = 0;
1250
-  static unsigned long raw_temp_3_value = 0;
1262
+  static unsigned long raw_temp_value[EXTRUDERS] = { 0 };
1251 1263
   static unsigned long raw_temp_bed_value = 0;
1252 1264
   static TempState temp_state = StartupDelay;
1253 1265
   static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
@@ -1459,7 +1471,7 @@ ISR(TIMER0_COMPB_vect) {
1459 1471
       break;
1460 1472
     case MeasureTemp_0:
1461 1473
       #if HAS_TEMP_0
1462
-        raw_temp_0_value += ADC;
1474
+        raw_temp_value[0] += ADC;
1463 1475
       #endif
1464 1476
       temp_state = PrepareTemp_BED;
1465 1477
       break;
@@ -1485,7 +1497,7 @@ ISR(TIMER0_COMPB_vect) {
1485 1497
       break;
1486 1498
     case MeasureTemp_1:
1487 1499
       #if HAS_TEMP_1
1488
-        raw_temp_1_value += ADC;
1500
+        raw_temp_value[1] += ADC;
1489 1501
       #endif
1490 1502
       temp_state = PrepareTemp_2;
1491 1503
       break;
@@ -1498,7 +1510,7 @@ ISR(TIMER0_COMPB_vect) {
1498 1510
       break;
1499 1511
     case MeasureTemp_2:
1500 1512
       #if HAS_TEMP_2
1501
-        raw_temp_2_value += ADC;
1513
+        raw_temp_value[2] += ADC;
1502 1514
       #endif
1503 1515
       temp_state = PrepareTemp_3;
1504 1516
       break;
@@ -1511,7 +1523,7 @@ ISR(TIMER0_COMPB_vect) {
1511 1523
       break;
1512 1524
     case MeasureTemp_3:
1513 1525
       #if HAS_TEMP_3
1514
-        raw_temp_3_value += ADC;
1526
+        raw_temp_value[3] += ADC;
1515 1527
       #endif
1516 1528
       temp_state = Prepare_FILWIDTH;
1517 1529
       break;
@@ -1546,19 +1558,19 @@ ISR(TIMER0_COMPB_vect) {
1546 1558
   if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256)  = 164ms.
1547 1559
     if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading.
1548 1560
       #ifndef HEATER_0_USES_MAX6675
1549
-        current_temperature_raw[0] = raw_temp_0_value;
1561
+        current_temperature_raw[0] = raw_temp_value[0];
1550 1562
       #endif
1551 1563
       #if EXTRUDERS > 1
1552
-        current_temperature_raw[1] = raw_temp_1_value;
1564
+        current_temperature_raw[1] = raw_temp_value[1];
1553 1565
         #if EXTRUDERS > 2
1554
-          current_temperature_raw[2] = raw_temp_2_value;
1566
+          current_temperature_raw[2] = raw_temp_value[2];
1555 1567
           #if EXTRUDERS > 3
1556
-            current_temperature_raw[3] = raw_temp_3_value;
1568
+            current_temperature_raw[3] = raw_temp_value[3];
1557 1569
           #endif
1558 1570
         #endif
1559 1571
       #endif
1560 1572
       #ifdef TEMP_SENSOR_1_AS_REDUNDANT
1561
-        redundant_temperature_raw = raw_temp_1_value;
1573
+        redundant_temperature_raw = raw_temp_value[1];
1562 1574
       #endif
1563 1575
       current_temperature_bed_raw = raw_temp_bed_value;
1564 1576
     } //!temp_meas_ready
@@ -1570,31 +1582,67 @@ ISR(TIMER0_COMPB_vect) {
1570 1582
     
1571 1583
     temp_meas_ready = true;
1572 1584
     temp_count = 0;
1573
-    raw_temp_0_value = 0;
1574
-    raw_temp_1_value = 0;
1575
-    raw_temp_2_value = 0;
1576
-    raw_temp_3_value = 0;
1585
+    for (int i = 0; i < EXTRUDERS; i++) raw_temp_value[i] = 0;
1577 1586
     raw_temp_bed_value = 0;
1578 1587
 
1579 1588
     #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
1580
-      #define MAXTEST <=
1581
-      #define MINTEST >=
1589
+      #define GE0 <=
1590
+      #define LE0 >=
1582 1591
     #else
1583
-      #define MAXTEST >=
1584
-      #define MINTEST <=
1592
+      #define GE0 >=
1593
+      #define LE0 <=
1585 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
1586 1631
 
1587
-    for (int i=0; i<EXTRUDERS; i++) {
1588
-      if (current_temperature_raw[i] MAXTEST maxttemp_raw[i]) max_temp_error(i);
1589
-      else if (current_temperature_raw[i] MINTEST minttemp_raw[i]) min_temp_error(i);
1590
-    }
1591
-    /* No bed MINTEMP error? */
1592 1632
     #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
1593
-      if (current_temperature_bed_raw MAXTEST bed_maxttemp_raw) {
1594
-          target_temperature_bed = 0;
1595
-          bed_max_temp_error();
1596
-        }
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
+      }
1597 1644
     #endif
1645
+
1598 1646
   } // temp_count >= OVERSAMPLENR
1599 1647
 
1600 1648
   #ifdef BABYSTEPPING

+ 155
- 48
Marlin/ultralcd.cpp Переглянути файл

@@ -70,6 +70,13 @@ static void lcd_sdcard_menu();
70 70
 static void lcd_delta_calibrate_menu();
71 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 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 82
 /* Different types of actions that can be used in menu items. */
@@ -118,68 +125,88 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l
118 125
 
119 126
 
120 127
 /* Helper macros for menus */
128
+
129
+/**
130
+ * START_MENU generates the init code for a menu function
131
+ */
121 132
 #define START_MENU() do { \
122
-	encoderRateMultiplierEnabled = false; \
123
-    if (encoderPosition > 0x8000) encoderPosition = 0; \
124
-    if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM < currentMenuViewOffset) currentMenuViewOffset = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\
125
-    uint8_t _lineNr = currentMenuViewOffset, _menuItemNr; \
126
-    bool wasClicked = LCD_CLICKED;\
127
-    for(uint8_t _drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { \
128
-        _menuItemNr = 0;
133
+  encoderRateMultiplierEnabled = false; \
134
+  if (encoderPosition > 0x8000) encoderPosition = 0; \
135
+  uint8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \
136
+  if (encoderLine < currentMenuViewOffset) currentMenuViewOffset = encoderLine; \
137
+  uint8_t _lineNr = currentMenuViewOffset, _menuItemNr; \
138
+  bool wasClicked = LCD_CLICKED, itemSelected; \
139
+  if (wasClicked) lcd_quick_feedback(); \
140
+  for (uint8_t _drawLineNr = 0; _drawLineNr < LCD_HEIGHT; _drawLineNr++, _lineNr++) { \
141
+    _menuItemNr = 0;
142
+
143
+/**
144
+ * MENU_ITEM generates draw & handler code for a menu item, potentially calling:
145
+ *
146
+ *   lcd_implementation_drawmenu_[type](sel, row, label, arg3...)
147
+ *   menu_action_[type](arg3...)
148
+ *
149
+ * Examples:
150
+ *   MENU_ITEM(back, MSG_WATCH, lcd_status_screen)
151
+ *     lcd_implementation_drawmenu_back(sel, row, PSTR(MSG_WATCH), lcd_status_screen)
152
+ *     menu_action_back(lcd_status_screen)
153
+ *
154
+ *   MENU_ITEM(function, MSG_PAUSE_PRINT, lcd_sdcard_pause)
155
+ *     lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause)
156
+ *     menu_action_function(lcd_sdcard_pause)
157
+ *
158
+ *   MENU_ITEM_EDIT(int3, MSG_SPEED, &feedmultiply, 10, 999)
159
+ *   MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedmultiply, 10, 999)
160
+ *     lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedmultiply, 10, 999)
161
+ *     menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedmultiply, 10, 999)
162
+ *
163
+ */
129 164
 #define MENU_ITEM(type, label, args...) do { \
130
-    if (_menuItemNr == _lineNr) { \
131
-        if (lcdDrawUpdate) { \
132
-            const char* _label_pstr = PSTR(label); \
133
-            if ((encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) { \
134
-                lcd_implementation_drawmenu_ ## type ## _selected (_drawLineNr, _label_pstr , ## args ); \
135
-            }else{\
136
-                lcd_implementation_drawmenu_ ## type (_drawLineNr, _label_pstr , ## args ); \
137
-            }\
138
-        }\
139
-        if (wasClicked && (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) {\
140
-            lcd_quick_feedback(); \
141
-            menu_action_ ## type ( args ); \
142
-            return;\
143
-        }\
144
-    }\
145
-    _menuItemNr++;\
165
+  if (_menuItemNr == _lineNr) { \
166
+    itemSelected = encoderLine == _menuItemNr; \
167
+    if (lcdDrawUpdate) \
168
+      lcd_implementation_drawmenu_ ## type(itemSelected, _drawLineNr, PSTR(label), ## args); \
169
+    if (wasClicked && itemSelected) { \
170
+      menu_action_ ## type(args); \
171
+      return; \
172
+    } \
173
+  } \
174
+  _menuItemNr++; \
146 175
 } while(0)
176
+
147 177
 #ifdef ENCODER_RATE_MULTIPLIER
178
+  /**
179
+   * MENU_MULTIPLIER_ITEM generates drawing and handling code for a multiplier menu item
180
+   */
148 181
   #define MENU_MULTIPLIER_ITEM(type, label, args...) do { \
149 182
     if (_menuItemNr == _lineNr) { \
150
-      if (lcdDrawUpdate) { \
151
-        const char* _label_pstr = PSTR(label); \
152
-        if ((encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) { \
153
-          lcd_implementation_drawmenu_ ## type ## _selected (_drawLineNr, _label_pstr , ## args ); \
154
-        } \
155
-        else { \
156
-          lcd_implementation_drawmenu_ ## type (_drawLineNr, _label_pstr , ## args ); \
157
-        } \
158
-      } \
159
-      if (wasClicked && (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) == _menuItemNr) { \
160
-        lcd_quick_feedback(); \
183
+      itemSelected = encoderLine == _menuItemNr; \
184
+      if (lcdDrawUpdate) \
185
+        lcd_implementation_drawmenu_ ## type(itemSelected, _drawLineNr, PSTR(label), ## args); \
186
+      if (wasClicked && itemSelected) { \
161 187
         encoderRateMultiplierEnabled = true; \
162 188
         lastEncoderMovementMillis = 0; \
163
-        menu_action_ ## type ( args ); \
189
+        menu_action_ ## type(args); \
164 190
         return; \
165 191
       } \
166 192
     } \
167 193
     _menuItemNr++; \
168 194
   } while(0)
169 195
 #endif //ENCODER_RATE_MULTIPLIER
196
+
170 197
 #define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0)
171
-#define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args )
172
-#define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args )
198
+#define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label), ## args)
199
+#define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
173 200
 #ifdef ENCODER_RATE_MULTIPLIER
174
-  #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args )
175
-  #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args )
201
+  #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label), ## args)
202
+  #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
176 203
 #else //!ENCODER_RATE_MULTIPLIER
177
-  #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args )
178
-  #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args )
204
+  #define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## 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)
179 206
 #endif //!ENCODER_RATE_MULTIPLIER
180 207
 #define END_MENU() \
181
-    if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; \
182
-    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; } \
183 210
     } } while(0)
184 211
 
185 212
 /** Used variables to keep track of the menu */
@@ -410,7 +437,7 @@ static void lcd_main_menu() {
410 437
 void lcd_set_home_offsets() {
411 438
   for(int8_t i=0; i < NUM_AXIS; i++) {
412 439
     if (i != E_AXIS) {
413
-      add_homing[i] -= current_position[i];
440
+      home_offset[i] -= current_position[i];
414 441
       current_position[i] = 0.0;
415 442
     }
416 443
   }
@@ -458,9 +485,9 @@ static void lcd_tune_menu() {
458 485
   #if TEMP_SENSOR_BED != 0
459 486
     MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
460 487
   #endif
461
-    MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
462
-    MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999);
463
-    MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F0, &extruder_multiply[0], 10, 999);
488
+  MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
489
+  MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999);
490
+  MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F0, &extruder_multiply[0], 10, 999);
464 491
   #if TEMP_SENSOR_1 != 0
465 492
     MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F1, &extruder_multiply[1], 10, 999);
466 493
   #endif
@@ -610,6 +637,10 @@ static void lcd_prepare_menu() {
610 637
     }
611 638
   #endif
612 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
613 644
 	
614 645
   END_MENU();
615 646
 }
@@ -1321,7 +1352,12 @@ void lcd_update() {
1321 1352
     #endif
1322 1353
 
1323 1354
     #ifdef ULTIPANEL
1324
-      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) {
1325 1361
         lcd_return_to_status();
1326 1362
         lcdDrawUpdate = 2;
1327 1363
       }
@@ -1740,4 +1776,75 @@ char *ftostr52(const float &x)
1740 1776
   return conv;
1741 1777
 }
1742 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
+
1743 1850
 #endif //ULTRA_LCD

+ 89
- 199
Marlin/ultralcd_implementation_hitachi_HD44780.h Переглянути файл

@@ -610,214 +610,104 @@ static void lcd_implementation_status_screen()
610 610
 
611 611
   lcd.print(lcd_status_message);
612 612
 }
613
-static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, char pre_char, char post_char)
614
-{
615
-    char c;
616
-    //Use all characters in narrow LCDs
617
-  #if LCD_WIDTH < 20
618
-      uint8_t n = LCD_WIDTH - 1 - 1;
619
-    #else
620
-      uint8_t n = LCD_WIDTH - 1 - 2;
621
-  #endif
622
-    lcd.setCursor(0, row);
623
-    lcd.print(pre_char);
624
-    while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) )
625
-    {
626
-        lcd.print(c);
627
-        pstr++;
628
-        if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--;
629
-    }
630
-    while(n--)
631
-        lcd.print(' ');
632
-    lcd.print(post_char);
633
-    lcd.print(' ');
613
+
614
+static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char post_char) {
615
+  char c;
616
+  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2);
617
+  lcd.setCursor(0, row);
618
+  lcd.print(sel ? pre_char : ' ');
619
+  while ((c = pgm_read_byte(pstr)) && n > 0) {
620
+    lcd.print(c);
621
+    pstr++;
622
+    if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--;
623
+  }
624
+  while(n--) lcd.print(' ');
625
+  lcd.print(post_char);
626
+  lcd.print(' ');
634 627
 }
635
-static void lcd_implementation_drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, char* data)
636
-{
637
-    char c;
638
-    //Use all characters in narrow LCDs
639
-  #if LCD_WIDTH < 20
640
-      uint8_t n = LCD_WIDTH - 1 - 1 - lcd_strlen(data);
641
-    #else
642
-      uint8_t n = LCD_WIDTH - 1 - 2 - lcd_strlen(data);
643
-  #endif
644
-    lcd.setCursor(0, row);
645
-    lcd.print(pre_char);
646
-    while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) )
647
-    {
648
-        lcd.print(c);
649
-        pstr++;
650
-        if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--;
651
-    }
652
-    lcd.print(':');
653
-    while(n--)
654
-        lcd.print(' ');
655
-    lcd.print(data);
628
+static void lcd_implementation_drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char* data) {
629
+  char c;
630
+  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen(data);
631
+  lcd.setCursor(0, row);
632
+  lcd.print(sel ? pre_char : ' ');
633
+  while ((c = pgm_read_byte(pstr)) && n > 0) {
634
+    lcd.print(c);
635
+    pstr++;
636
+    if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--;
637
+  }
638
+  lcd.print(':');
639
+  while (n--) lcd.print(' ');
640
+  lcd.print(data);
656 641
 }
657
-static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, const char* pstr, char pre_char, const char* data)
658
-{
659
-    char c;
660
-    //Use all characters in narrow LCDs
661
-  #if LCD_WIDTH < 20
662
-      uint8_t n = LCD_WIDTH - 1 - 1 - lcd_strlen_P(data);
663
-    #else
664
-      uint8_t n = LCD_WIDTH - 1 - 2 - lcd_strlen_P(data);
665
-  #endif
666
-    lcd.setCursor(0, row);
667
-    lcd.print(pre_char);
668
-    while( ((c = pgm_read_byte(pstr)) != '\0') && (n>0) )
669
-    {
670
-        lcd.print(c);
671
-        pstr++;
672
-        if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--;
673
-    }
674
-    lcd.print(':');
675
-    while(n--)
676
-        lcd.print(' ');
677
-    lcd_printPGM(data);
642
+static void lcd_implementation_drawmenu_setting_edit_generic_P(bool sel, uint8_t row, const char* pstr, char pre_char, const char* data) {
643
+  char c;
644
+  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen_P(data);
645
+  lcd.setCursor(0, row);
646
+  lcd.print(sel ? pre_char : ' ');
647
+  while ((c = pgm_read_byte(pstr)) && n > 0) {
648
+    lcd.print(c);
649
+    pstr++;
650
+    if ((pgm_read_byte(pstr) & 0xc0) != 0x80) n--;
651
+  }
652
+  lcd.print(':');
653
+  while (n--) lcd.print(' ');
654
+  lcd_printPGM(data);
678 655
 }
679
-#define lcd_implementation_drawmenu_setting_edit_int3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))
680
-#define lcd_implementation_drawmenu_setting_edit_int3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))
681
-#define lcd_implementation_drawmenu_setting_edit_float3_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))
682
-#define lcd_implementation_drawmenu_setting_edit_float3(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))
683
-#define lcd_implementation_drawmenu_setting_edit_float32_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))
684
-#define lcd_implementation_drawmenu_setting_edit_float32(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))
685
-#define lcd_implementation_drawmenu_setting_edit_float43_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data)))
686
-#define lcd_implementation_drawmenu_setting_edit_float43(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data)))
687
-#define lcd_implementation_drawmenu_setting_edit_float5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
688
-#define lcd_implementation_drawmenu_setting_edit_float5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
689
-#define lcd_implementation_drawmenu_setting_edit_float52_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))
690
-#define lcd_implementation_drawmenu_setting_edit_float52(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))
691
-#define lcd_implementation_drawmenu_setting_edit_float51_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))
692
-#define lcd_implementation_drawmenu_setting_edit_float51(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))
693
-#define lcd_implementation_drawmenu_setting_edit_long5_selected(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
694
-#define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
695
-#define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
696
-#define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
656
+#define lcd_implementation_drawmenu_setting_edit_int3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', itostr3(*(data)))
657
+#define lcd_implementation_drawmenu_setting_edit_float3(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr3(*(data)))
658
+#define lcd_implementation_drawmenu_setting_edit_float32(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr32(*(data)))
659
+#define lcd_implementation_drawmenu_setting_edit_float43(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr43(*(data)))
660
+#define lcd_implementation_drawmenu_setting_edit_float5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5(*(data)))
661
+#define lcd_implementation_drawmenu_setting_edit_float52(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr52(*(data)))
662
+#define lcd_implementation_drawmenu_setting_edit_float51(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr51(*(data)))
663
+#define lcd_implementation_drawmenu_setting_edit_long5(sel, row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5(*(data)))
664
+#define lcd_implementation_drawmenu_setting_edit_bool(sel, row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
697 665
 
698 666
 //Add version for callback functions
699
-#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data)))
700
-#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data)))
701
-#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data)))
702
-#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data)))
703
-#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data)))
704
-#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data)))
705
-#define lcd_implementation_drawmenu_setting_edit_callback_float43_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr43(*(data)))
706
-#define lcd_implementation_drawmenu_setting_edit_callback_float43(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr43(*(data)))
707
-#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
708
-#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
709
-#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data)))
710
-#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data)))
711
-#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data)))
712
-#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data)))
713
-#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data)))
714
-#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data)))
715
-#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
716
-#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
717
-
718
-
719
-void lcd_implementation_drawedit(const char* pstr, char* value)
720
-{
721
-    lcd.setCursor(1, 1);
722
-    lcd_printPGM(pstr);
723
-    lcd.print(':');
724
-   #if LCD_WIDTH < 20
725
-      lcd.setCursor(LCD_WIDTH - lcd_strlen(value), 1);
726
-    #else
727
-      lcd.setCursor(LCD_WIDTH -1 - lcd_strlen(value), 1);
728
-   #endif
729
-    lcd.print(value);
730
-}
731
-static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename)
732
-{
733
-    char c;
734
-    uint8_t n = LCD_WIDTH - 1;
735
-    lcd.setCursor(0, row);
736
-    lcd.print('>');
737
-    if (longFilename[0] != '\0')
738
-    {
739
-        filename = longFilename;
740
-        longFilename[LCD_WIDTH-1] = '\0';
741
-    }
742
-    while( ((c = *filename) != '\0') && (n>0) )
743
-    {
744
-        lcd.print(c);
745
-        filename++;
746
-        n--;
747
-    }
748
-    while(n--)
749
-        lcd.print(' ');
667
+#define lcd_implementation_drawmenu_setting_edit_callback_int3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', itostr3(*(data)))
668
+#define lcd_implementation_drawmenu_setting_edit_callback_float3(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr3(*(data)))
669
+#define lcd_implementation_drawmenu_setting_edit_callback_float32(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr32(*(data)))
670
+#define lcd_implementation_drawmenu_setting_edit_callback_float43(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr43(*(data)))
671
+#define lcd_implementation_drawmenu_setting_edit_callback_float5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5(*(data)))
672
+#define lcd_implementation_drawmenu_setting_edit_callback_float52(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr52(*(data)))
673
+#define lcd_implementation_drawmenu_setting_edit_callback_float51(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr51(*(data)))
674
+#define lcd_implementation_drawmenu_setting_edit_callback_long5(sel, row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(sel, row, pstr, '>', ftostr5(*(data)))
675
+#define lcd_implementation_drawmenu_setting_edit_callback_bool(sel, row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(sel, row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF))
676
+
677
+void lcd_implementation_drawedit(const char* pstr, char* value) {
678
+  lcd.setCursor(1, 1);
679
+  lcd_printPGM(pstr);
680
+  lcd.print(':');
681
+  lcd.setCursor(LCD_WIDTH - (LCD_WIDTH < 20 ? 0 : 1) - lcd_strlen(value), 1);
682
+  lcd.print(value);
750 683
 }
751
-static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* pstr, const char* filename, char* longFilename)
752
-{
753
-    char c;
754
-    uint8_t n = LCD_WIDTH - 1;
755
-    lcd.setCursor(0, row);
756
-    lcd.print(' ');
757
-    if (longFilename[0] != '\0')
758
-    {
759
-        filename = longFilename;
760
-        longFilename[LCD_WIDTH-1] = '\0';
761
-    }
762
-    while( ((c = *filename) != '\0') && (n>0) )
763
-    {
764
-        lcd.print(c);
765
-        filename++;
766
-        n--;
767
-    }
768
-    while(n--)
769
-        lcd.print(' ');
684
+static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename, uint8_t concat) {
685
+  char c;
686
+  uint8_t n = LCD_WIDTH - concat;
687
+  lcd.setCursor(0, row);
688
+  lcd.print(sel ? '>' : ' ');
689
+  if (longFilename[0]) {
690
+    filename = longFilename;
691
+    longFilename[n] = '\0';
692
+  }
693
+  while ((c = *filename) && n > 0) {
694
+    lcd.print(c);
695
+    filename++;
696
+    n--;
697
+  }
698
+  while (n--) lcd.print(' ');
770 699
 }
771
-static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* pstr, const char* filename, char* longFilename)
772
-{
773
-    char c;
774
-    uint8_t n = LCD_WIDTH - 2;
775
-    lcd.setCursor(0, row);
776
-    lcd.print('>');
777
-    lcd.print(LCD_STR_FOLDER[0]);
778
-    if (longFilename[0] != '\0')
779
-    {
780
-        filename = longFilename;
781
-        longFilename[LCD_WIDTH-2] = '\0';
782
-    }
783
-    while( ((c = *filename) != '\0') && (n>0) )
784
-    {
785
-        lcd.print(c);
786
-        filename++;
787
-        n--;
788
-    }
789
-    while(n--)
790
-        lcd.print(' ');
700
+
701
+static void lcd_implementation_drawmenu_sdfile(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) {
702
+  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 1);
791 703
 }
792
-static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* pstr, const char* filename, char* longFilename)
793
-{
794
-    char c;
795
-    uint8_t n = LCD_WIDTH - 2;
796
-    lcd.setCursor(0, row);
797
-    lcd.print(' ');
798
-    lcd.print(LCD_STR_FOLDER[0]);
799
-    if (longFilename[0] != '\0')
800
-    {
801
-        filename = longFilename;
802
-        longFilename[LCD_WIDTH-2] = '\0';
803
-    }
804
-    while( ((c = *filename) != '\0') && (n>0) )
805
-    {
806
-        lcd.print(c);
807
-        filename++;
808
-        n--;
809
-    }
810
-    while(n--)
811
-        lcd.print(' ');
704
+static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) {
705
+  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2);
812 706
 }
813
-#define lcd_implementation_drawmenu_back_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
814
-#define lcd_implementation_drawmenu_back(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_UPLEVEL[0])
815
-#define lcd_implementation_drawmenu_submenu_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
816
-#define lcd_implementation_drawmenu_submenu(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', LCD_STR_ARROW_RIGHT[0])
817
-#define lcd_implementation_drawmenu_gcode_selected(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
818
-#define lcd_implementation_drawmenu_gcode(row, pstr, gcode) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
819
-#define lcd_implementation_drawmenu_function_selected(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, '>', ' ')
820
-#define lcd_implementation_drawmenu_function(row, pstr, data) lcd_implementation_drawmenu_generic(row, pstr, ' ', ' ')
707
+#define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])
708
+#define lcd_implementation_drawmenu_submenu(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0])
709
+#define lcd_implementation_drawmenu_gcode(sel, row, pstr, gcode) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
710
+#define lcd_implementation_drawmenu_function(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, '>', ' ')
821 711
 
822 712
 static void lcd_implementation_quick_feedback()
823 713
 {

Завантаження…
Відмінити
Зберегти