Browse Source

Merge pull request #6174 from thinkyhead/rc_ubl_continued

UBL additional cleanup
Scott Lahteine 8 years ago
parent
commit
baadb11536
33 changed files with 560 additions and 554 deletions
  1. 1
    1
      .travis.yml
  2. 1
    1
      Marlin/Configuration.h
  3. 58
    73
      Marlin/G26_Mesh_Validation_Tool.cpp
  4. 2
    2
      Marlin/M100_Free_Mem_Chk.cpp
  5. 4
    0
      Marlin/Marlin.h
  6. 65
    43
      Marlin/Marlin_main.cpp
  7. 238
    231
      Marlin/UBL.h
  8. 35
    47
      Marlin/UBL_Bed_Leveling.cpp
  9. 105
    104
      Marlin/UBL_G29.cpp
  10. 21
    21
      Marlin/UBL_line_to_destination.cpp
  11. 2
    2
      Marlin/configuration_store.cpp
  12. 1
    1
      Marlin/example_configurations/Cartesio/Configuration.h
  13. 1
    1
      Marlin/example_configurations/Felix/Configuration.h
  14. 1
    1
      Marlin/example_configurations/Felix/DUAL/Configuration.h
  15. 1
    1
      Marlin/example_configurations/Hephestos/Configuration.h
  16. 1
    1
      Marlin/example_configurations/Hephestos_2/Configuration.h
  17. 1
    1
      Marlin/example_configurations/K8200/Configuration.h
  18. 1
    1
      Marlin/example_configurations/K8400/Configuration.h
  19. 1
    1
      Marlin/example_configurations/K8400/Dual-head/Configuration.h
  20. 1
    1
      Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
  21. 1
    1
      Marlin/example_configurations/RigidBot/Configuration.h
  22. 1
    1
      Marlin/example_configurations/SCARA/Configuration.h
  23. 1
    1
      Marlin/example_configurations/TAZ4/Configuration.h
  24. 1
    1
      Marlin/example_configurations/WITBOX/Configuration.h
  25. 1
    1
      Marlin/example_configurations/adafruit/ST7565/Configuration.h
  26. 1
    1
      Marlin/example_configurations/delta/flsun_kossel_mini/Configuration.h
  27. 1
    1
      Marlin/example_configurations/delta/generic/Configuration.h
  28. 1
    1
      Marlin/example_configurations/delta/kossel_mini/Configuration.h
  29. 1
    1
      Marlin/example_configurations/delta/kossel_pro/Configuration.h
  30. 1
    1
      Marlin/example_configurations/delta/kossel_xl/Configuration.h
  31. 1
    1
      Marlin/example_configurations/makibox/Configuration.h
  32. 1
    1
      Marlin/example_configurations/tvrrug/Round2/Configuration.h
  33. 7
    8
      Marlin/ultralcd.cpp

+ 1
- 1
.travis.yml View File

120
   # Test a simple build of AUTO_BED_LEVELING_UBL
120
   # Test a simple build of AUTO_BED_LEVELING_UBL
121
   #
121
   #
122
   - restore_configs
122
   - restore_configs
123
-  - opt_enable AUTO_BED_LEVELING_UBL FIX_MOUNTED_PROBE EEPROM_SETTINGS G3D_PANEL
123
+  - opt_enable AUTO_BED_LEVELING_UBL UBL_G26_MESH_EDITING FIX_MOUNTED_PROBE EEPROM_SETTINGS G3D_PANEL
124
   - build_marlin
124
   - build_marlin
125
   #
125
   #
126
   # Test a Sled Z Probe
126
   # Test a Sled Z Probe

+ 1
- 1
Marlin/Configuration.h View File

862
   #define UBL_PROBE_PT_2_Y 20
862
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_3_X 180
863
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_Y 20
864
   #define UBL_PROBE_PT_3_Y 20
865
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
865
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
866
 
866
 
867
 #elif ENABLED(MESH_BED_LEVELING)
867
 #elif ENABLED(MESH_BED_LEVELING)
868
 
868
 

+ 58
- 73
Marlin/G26_Mesh_Validation_Tool.cpp View File

26
 
26
 
27
 #include "MarlinConfig.h"
27
 #include "MarlinConfig.h"
28
 
28
 
29
-#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
29
+#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_EDITING)
30
 
30
 
31
   #include "Marlin.h"
31
   #include "Marlin.h"
32
   #include "Configuration.h"
32
   #include "Configuration.h"
38
 
38
 
39
   #define EXTRUSION_MULTIPLIER 1.0    // This is too much clutter for the main Configuration.h file  But
39
   #define EXTRUSION_MULTIPLIER 1.0    // This is too much clutter for the main Configuration.h file  But
40
   #define RETRACTION_MULTIPLIER 1.0   // some user have expressed an interest in being able to customize
40
   #define RETRACTION_MULTIPLIER 1.0   // some user have expressed an interest in being able to customize
41
-  #define NOZZLE 0.3                  // these numbers for thier printer so they don't need to type all
41
+  #define NOZZLE 0.3                  // these numbers for their printer so they don't need to type all
42
   #define FILAMENT 1.75               // the options every time they do a Mesh Validation Print.
42
   #define FILAMENT 1.75               // the options every time they do a Mesh Validation Print.
43
   #define LAYER_HEIGHT 0.2
43
   #define LAYER_HEIGHT 0.2
44
   #define PRIME_LENGTH 10.0           // So, we put these number in an easy to find and change place.
44
   #define PRIME_LENGTH 10.0           // So, we put these number in an easy to find and change place.
113
    *   Y #  Y coordinate  Specify the starting location of the drawing activity.
113
    *   Y #  Y coordinate  Specify the starting location of the drawing activity.
114
    */
114
    */
115
 
115
 
116
-  extern bool ubl_has_control_of_lcd_panel;
117
   extern float feedrate;
116
   extern float feedrate;
118
-  //extern bool relative_mode;
119
   extern Planner planner;
117
   extern Planner planner;
120
   //#if ENABLED(ULTRA_LCD)
118
   //#if ENABLED(ULTRA_LCD)
121
     extern char lcd_status_message[];
119
     extern char lcd_status_message[];
171
 
169
 
172
   int8_t prime_flag = 0;
170
   int8_t prime_flag = 0;
173
 
171
 
174
-  bool keep_heaters_on = false,
175
-       g26_debug_flag = false;
172
+  bool keep_heaters_on = false;
176
 
173
 
177
   /**
174
   /**
178
    * G26: Mesh Validation Pattern generation.
175
    * G26: Mesh Validation Pattern generation.
181
    * nozzle in a problem area and doing a G29 P4 R command.
178
    * nozzle in a problem area and doing a G29 P4 R command.
182
    */
179
    */
183
   void gcode_G26() {
180
   void gcode_G26() {
184
-    float circle_x, circle_y, x, y, xe, ye, tmp,
185
-          start_angle, end_angle;
186
-    int   i, xi, yi, lcd_init_counter = 0;
181
+    float tmp, start_angle, end_angle;
182
+    int   i, xi, yi;
187
     mesh_index_pair location;
183
     mesh_index_pair location;
188
 
184
 
189
-    if (axis_unhomed_error(true, true, true)) // Don't allow Mesh Validation without homing first
190
-      gcode_G28();
191
-
192
-    if (parse_G26_parameters()) return; // If the paramter parsing did not go OK, we abort the command
185
+    // Don't allow Mesh Validation without homing first
186
+    // If the paramter parsing did not go OK, we abort the command
187
+    if (axis_unhomed_error(true, true, true) || parse_G26_parameters()) return;
193
 
188
 
194
     if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
189
     if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
195
       do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
190
       do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
197
       set_current_to_destination();
192
       set_current_to_destination();
198
     }
193
     }
199
 
194
 
200
-    ubl_has_control_of_lcd_panel = true; // Take control of the LCD Panel!
201
-    if (turn_on_heaters())     // Turn on the heaters, leave the command if anything
202
-      goto LEAVE;              // has gone wrong.
195
+    if (turn_on_heaters()) goto LEAVE;
203
 
196
 
204
-    axis_relative_modes[E_AXIS] = false;    // Get things setup so we can take control of the
205
-    //relative_mode = false;                  // planner and stepper motors!
206
     current_position[E_AXIS] = 0.0;
197
     current_position[E_AXIS] = 0.0;
207
     sync_plan_position_e();
198
     sync_plan_position_e();
208
 
199
 
209
-    if (prime_flag && prime_nozzle())       // if prime_nozzle() returns an error, we just bail out.
210
-      goto LEAVE;
200
+    if (prime_flag && prime_nozzle()) goto LEAVE;
211
 
201
 
212
     /**
202
     /**
213
      *  Bed is preheated
203
      *  Bed is preheated
219
      *  It's  "Show Time" !!!
209
      *  It's  "Show Time" !!!
220
      */
210
      */
221
 
211
 
222
-    // Clear all of the flags we need
223
     ZERO(circle_flags);
212
     ZERO(circle_flags);
224
     ZERO(horizontal_mesh_line_flags);
213
     ZERO(horizontal_mesh_line_flags);
225
     ZERO(vertical_mesh_line_flags);
214
     ZERO(vertical_mesh_line_flags);
226
 
215
 
227
-    //
228
     // Move nozzle to the specified height for the first layer
216
     // Move nozzle to the specified height for the first layer
229
-    //
230
     set_destination_to_current();
217
     set_destination_to_current();
231
     destination[Z_AXIS] = layer_height;
218
     destination[Z_AXIS] = layer_height;
232
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
219
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
233
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], ooze_amount);
220
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], ooze_amount);
234
 
221
 
235
-    ubl_has_control_of_lcd_panel = true; // Take control of the LCD Panel!
222
+    ubl.has_control_of_lcd_panel++;
236
     //debug_current_and_destination((char*)"Starting G26 Mesh Validation Pattern.");
223
     //debug_current_and_destination((char*)"Starting G26 Mesh Validation Pattern.");
237
 
224
 
238
     /**
225
     /**
264
         goto LEAVE;
251
         goto LEAVE;
265
       }
252
       }
266
 
253
 
267
-      if (continue_with_closest)
268
-        location = find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS]);
269
-      else
270
-        location = find_closest_circle_to_print(x_pos, y_pos); // Find the closest Mesh Intersection to where we are now.
254
+      location = continue_with_closest
255
+        ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
256
+        : find_closest_circle_to_print(x_pos, y_pos); // Find the closest Mesh Intersection to where we are now.
271
 
257
 
272
       if (location.x_index >= 0 && location.y_index >= 0) {
258
       if (location.x_index >= 0 && location.y_index >= 0) {
273
-        circle_x = ubl.map_x_index_to_bed_location(location.x_index);
274
-        circle_y = ubl.map_y_index_to_bed_location(location.y_index);
259
+        const float circle_x = ubl.mesh_index_to_xpos[location.x_index],
260
+                    circle_y = ubl.mesh_index_to_ypos[location.y_index];
275
 
261
 
276
         // Let's do a couple of quick sanity checks.  We can pull this code out later if we never see it catch a problem
262
         // Let's do a couple of quick sanity checks.  We can pull this code out later if we never see it catch a problem
277
         #ifdef DELTA
263
         #ifdef DELTA
292
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
278
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
293
         yi = location.y_index;
279
         yi = location.y_index;
294
 
280
 
295
-        if (g26_debug_flag) {
281
+        if (ubl.g26_debug_flag) {
296
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
282
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
297
           SERIAL_ECHOPAIR(", yi=", yi);
283
           SERIAL_ECHOPAIR(", yi=", yi);
298
           SERIAL_CHAR(')');
284
           SERIAL_CHAR(')');
329
         for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) {
315
         for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) {
330
           int tmp_div_30 = tmp / 30.0;
316
           int tmp_div_30 = tmp / 30.0;
331
           if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
317
           if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
332
-
333
-          x = circle_x + cos_table[tmp_div_30];    // for speed, these are now a lookup table entry
334
-          y = circle_y + sin_table[tmp_div_30];
335
-
336
           if (tmp_div_30 > 11) tmp_div_30 -= 360 / 30;
318
           if (tmp_div_30 > 11) tmp_div_30 -= 360 / 30;
337
-          xe = circle_x + cos_table[tmp_div_30 + 1]; // for speed, these are now a lookup table entry
338
-          ye = circle_y + sin_table[tmp_div_30 + 1];
319
+
320
+          float x = circle_x + cos_table[tmp_div_30],    // for speed, these are now a lookup table entry
321
+                y = circle_y + sin_table[tmp_div_30],
322
+                xe = circle_x + cos_table[tmp_div_30 + 1],
323
+                ye = circle_y + sin_table[tmp_div_30 + 1];
339
           #ifdef DELTA
324
           #ifdef DELTA
340
             if (HYPOT2(x, y) > sq(DELTA_PRINTABLE_RADIUS))   // Check to make sure this part of
325
             if (HYPOT2(x, y) > sq(DELTA_PRINTABLE_RADIUS))   // Check to make sure this part of
341
               continue;                                      // the 'circle' is on the bed.  If
326
               continue;                                      // the 'circle' is on the bed.  If
342
           #else                                              // not, we need to skip
327
           #else                                              // not, we need to skip
343
-            x  = constrain(x, X_MIN_POS + 1, X_MAX_POS - 1);     // This keeps us from bumping the endstops
328
+            x  = constrain(x, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops
344
             y  = constrain(y, Y_MIN_POS + 1, Y_MAX_POS - 1);
329
             y  = constrain(y, Y_MIN_POS + 1, Y_MAX_POS - 1);
345
             xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1);
330
             xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1);
346
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
331
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
347
           #endif
332
           #endif
348
 
333
 
349
-          //if (g26_debug_flag) {
334
+          //if (ubl.g26_debug_flag) {
350
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
335
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
351
           //  strcpy(seg_msg, "   segment: ");
336
           //  strcpy(seg_msg, "   segment: ");
352
           //  strcpy(seg_num, "    \n");
337
           //  strcpy(seg_num, "    \n");
357
           //  debug_current_and_destination(seg_msg);
342
           //  debug_current_and_destination(seg_msg);
358
           //}
343
           //}
359
 
344
 
360
-          print_line_from_here_to_there(x, y, layer_height, xe, ye, layer_height);
345
+          print_line_from_here_to_there(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), layer_height, LOGICAL_X_POSITION(xe), LOGICAL_Y_POSITION(ye), layer_height);
361
 
346
 
362
         }
347
         }
363
-        //lcd_init_counter++;
364
-        //if (lcd_init_counter > 10) {
365
-        //  lcd_init_counter = 0;
366
-        //  lcd_init(); // Some people's LCD Displays are locking up.  This might help them
367
-        //  ubl_has_control_of_lcd_panel = true;     // Make sure UBL still is controlling the LCD Panel
368
-        //}
369
 
348
 
370
         //debug_current_and_destination((char*)"Looking for lines to connect.");
349
         //debug_current_and_destination((char*)"Looking for lines to connect.");
371
         look_for_lines_to_connect();
350
         look_for_lines_to_connect();
373
       }
352
       }
374
 
353
 
375
       //debug_current_and_destination((char*)"Done with current circle.");
354
       //debug_current_and_destination((char*)"Done with current circle.");
376
-    }
377
-    while (location.x_index >= 0 && location.y_index >= 0);
355
+
356
+    } while (location.x_index >= 0 && location.y_index >= 0);
378
 
357
 
379
     LEAVE:
358
     LEAVE:
380
     lcd_reset_alert_level();
359
     lcd_reset_alert_level();
394
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
373
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
395
     //debug_current_and_destination((char*)"done doing X/Y move.");
374
     //debug_current_and_destination((char*)"done doing X/Y move.");
396
 
375
 
397
-    ubl_has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
376
+    ubl.has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
398
 
377
 
399
     if (!keep_heaters_on) {
378
     if (!keep_heaters_on) {
400
       #if HAS_TEMP_BED
379
       #if HAS_TEMP_BED
420
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
399
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
421
       for (uint8_t j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
400
       for (uint8_t j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
422
         if (!is_bit_set(circle_flags, i, j)) {
401
         if (!is_bit_set(circle_flags, i, j)) {
423
-          mx = ubl.map_x_index_to_bed_location(i);  // We found a circle that needs to be printed
424
-          my = ubl.map_y_index_to_bed_location(j);
402
+          mx = ubl.mesh_index_to_xpos[i];  // We found a circle that needs to be printed
403
+          my = ubl.mesh_index_to_ypos[j];
425
 
404
 
426
           dx = X - mx;        // Get the distance to this intersection
405
           dx = X - mx;        // Get the distance to this intersection
427
           dy = Y - my;
406
           dy = Y - my;
466
               // We found two circles that need a horizontal line to connect them
445
               // We found two circles that need a horizontal line to connect them
467
               // Print it!
446
               // Print it!
468
               //
447
               //
469
-              sx = ubl.map_x_index_to_bed_location(i);
448
+              sx = ubl.mesh_index_to_xpos[i];
470
               sx = sx + SIZE_OF_INTERSECTION_CIRCLES - SIZE_OF_CROSS_HAIRS; // get the right edge of the circle
449
               sx = sx + SIZE_OF_INTERSECTION_CIRCLES - SIZE_OF_CROSS_HAIRS; // get the right edge of the circle
471
-              sy = ubl.map_y_index_to_bed_location(j);
450
+              sy = ubl.mesh_index_to_ypos[j];
472
 
451
 
473
-              ex = ubl.map_x_index_to_bed_location(i + 1);
452
+              ex = ubl.mesh_index_to_xpos[i + 1];
474
               ex = ex - SIZE_OF_INTERSECTION_CIRCLES + SIZE_OF_CROSS_HAIRS; // get the left edge of the circle
453
               ex = ex - SIZE_OF_INTERSECTION_CIRCLES + SIZE_OF_CROSS_HAIRS; // get the left edge of the circle
475
               ey = sy;
454
               ey = sy;
476
 
455
 
479
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
458
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
480
               ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
459
               ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
481
 
460
 
482
-              if (g26_debug_flag) {
461
+              if (ubl.g26_debug_flag) {
483
                 SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
462
                 SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
484
                 SERIAL_ECHOPAIR(", sy=", sy);
463
                 SERIAL_ECHOPAIR(", sy=", sy);
485
                 SERIAL_ECHOPAIR(") -> (ex=", ex);
464
                 SERIAL_ECHOPAIR(") -> (ex=", ex);
503
                 // We found two circles that need a vertical line to connect them
482
                 // We found two circles that need a vertical line to connect them
504
                 // Print it!
483
                 // Print it!
505
                 //
484
                 //
506
-                sx = ubl.map_x_index_to_bed_location(i);
507
-                sy = ubl.map_y_index_to_bed_location(j);
485
+                sx = ubl.mesh_index_to_xpos[i];
486
+                sy = ubl.mesh_index_to_ypos[j];
508
                 sy = sy + SIZE_OF_INTERSECTION_CIRCLES - SIZE_OF_CROSS_HAIRS; // get the top edge of the circle
487
                 sy = sy + SIZE_OF_INTERSECTION_CIRCLES - SIZE_OF_CROSS_HAIRS; // get the top edge of the circle
509
 
488
 
510
                 ex = sx;
489
                 ex = sx;
511
-                ey = ubl.map_y_index_to_bed_location(j + 1);
490
+                ey = ubl.mesh_index_to_ypos[j + 1];
512
                 ey = ey - SIZE_OF_INTERSECTION_CIRCLES + SIZE_OF_CROSS_HAIRS; // get the bottom edge of the circle
491
                 ey = ey - SIZE_OF_INTERSECTION_CIRCLES + SIZE_OF_CROSS_HAIRS; // get the bottom edge of the circle
513
 
492
 
514
                 sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);             // This keeps us from bumping the endstops
493
                 sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);             // This keeps us from bumping the endstops
516
                 ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
495
                 ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
517
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
496
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
518
 
497
 
519
-                if (g26_debug_flag) {
498
+                if (ubl.g26_debug_flag) {
520
                   SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
499
                   SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
521
                   SERIAL_ECHOPAIR(", sy=", sy);
500
                   SERIAL_ECHOPAIR(", sy=", sy);
522
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
501
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
541
 
520
 
542
     bool has_xy_component = (x != current_position[X_AXIS] || y != current_position[Y_AXIS]); // Check if X or Y is involved in the movement.
521
     bool has_xy_component = (x != current_position[X_AXIS] || y != current_position[Y_AXIS]); // Check if X or Y is involved in the movement.
543
 
522
 
544
-    //if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to()  has_xy_component:", (int)has_xy_component);
523
+    //if (ubl.g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to()  has_xy_component:", (int)has_xy_component);
545
 
524
 
546
     if (z != last_z) {
525
     if (z != last_z) {
547
-      //if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to()  changing Z to ", (int)z);
526
+      //if (ubl.g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to()  changing Z to ", (int)z);
548
 
527
 
549
       last_z = z;
528
       last_z = z;
550
       feed_value = planner.max_feedrate_mm_s[Z_AXIS]/(3.0);  // Base the feed rate off of the configured Z_AXIS feed rate
529
       feed_value = planner.max_feedrate_mm_s[Z_AXIS]/(3.0);  // Base the feed rate off of the configured Z_AXIS feed rate
559
       stepper.synchronize();
538
       stepper.synchronize();
560
       set_destination_to_current();
539
       set_destination_to_current();
561
 
540
 
562
-      //if (g26_debug_flag) debug_current_and_destination((char*)" in move_to() done with Z move");
541
+      //if (ubl.g26_debug_flag) debug_current_and_destination((char*)" in move_to() done with Z move");
563
     }
542
     }
564
 
543
 
565
     // Check if X or Y is involved in the movement.
544
     // Check if X or Y is involved in the movement.
566
     // Yes: a 'normal' movement. No: a retract() or un_retract()
545
     // Yes: a 'normal' movement. No: a retract() or un_retract()
567
     feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
546
     feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
568
 
547
 
569
-    if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
548
+    if (ubl.g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
570
 
549
 
571
     destination[X_AXIS] = x;
550
     destination[X_AXIS] = x;
572
     destination[Y_AXIS] = y;
551
     destination[Y_AXIS] = y;
573
     destination[E_AXIS] += e_delta;
552
     destination[E_AXIS] += e_delta;
574
 
553
 
575
-    //if (g26_debug_flag) debug_current_and_destination((char*)" in move_to() doing last move");
554
+    //if (ubl.g26_debug_flag) debug_current_and_destination((char*)" in move_to() doing last move");
576
 
555
 
577
     ubl_line_to_destination(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feed_value, 0);
556
     ubl_line_to_destination(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feed_value, 0);
578
 
557
 
579
-    //if (g26_debug_flag) debug_current_and_destination((char*)" in move_to() after last move");
558
+    //if (ubl.g26_debug_flag) debug_current_and_destination((char*)" in move_to() after last move");
580
 
559
 
581
     stepper.synchronize();
560
     stepper.synchronize();
582
     set_destination_to_current();
561
     set_destination_to_current();
586
   void retract_filament() {
565
   void retract_filament() {
587
     if (!g26_retracted) { // Only retract if we are not already retracted!
566
     if (!g26_retracted) { // Only retract if we are not already retracted!
588
       g26_retracted = true;
567
       g26_retracted = true;
589
-      //if (g26_debug_flag) SERIAL_ECHOLNPGM(" Decided to do retract.");
568
+      //if (ubl.g26_debug_flag) SERIAL_ECHOLNPGM(" Decided to do retract.");
590
       move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], -1.0 * retraction_multiplier);
569
       move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], -1.0 * retraction_multiplier);
591
-      //if (g26_debug_flag) SERIAL_ECHOLNPGM(" Retraction done.");
570
+      //if (ubl.g26_debug_flag) SERIAL_ECHOLNPGM(" Retraction done.");
592
     }
571
     }
593
   }
572
   }
594
 
573
 
596
     if (g26_retracted) { // Only un-retract if we are retracted.
575
     if (g26_retracted) { // Only un-retract if we are retracted.
597
       move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 1.2 * retraction_multiplier);
576
       move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 1.2 * retraction_multiplier);
598
       g26_retracted = false;
577
       g26_retracted = false;
599
-      //if (g26_debug_flag) SERIAL_ECHOLNPGM(" unretract done.");
578
+      //if (ubl.g26_debug_flag) SERIAL_ECHOLNPGM(" unretract done.");
600
     }
579
     }
601
   }
580
   }
602
 
581
 
633
     // On very small lines we don't do the optimization because it just isn't worth it.
612
     // On very small lines we don't do the optimization because it just isn't worth it.
634
     //
613
     //
635
     if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < abs(line_length)) {
614
     if (dist_end < dist_start && (SIZE_OF_INTERSECTION_CIRCLES) < abs(line_length)) {
636
-      //if (g26_debug_flag) SERIAL_ECHOLNPGM("  Reversing start and end of print_line_from_here_to_there()");
615
+      //if (ubl.g26_debug_flag) SERIAL_ECHOLNPGM("  Reversing start and end of print_line_from_here_to_there()");
637
       print_line_from_here_to_there(ex, ey, ez, sx, sy, sz);
616
       print_line_from_here_to_there(ex, ey, ez, sx, sy, sz);
638
       return;
617
       return;
639
     }
618
     }
642
 
621
 
643
     if (dist_start > 2.0) {
622
     if (dist_start > 2.0) {
644
       retract_filament();
623
       retract_filament();
645
-      //if (g26_debug_flag) SERIAL_ECHOLNPGM("  filament retracted.");
624
+      //if (ubl.g26_debug_flag) SERIAL_ECHOLNPGM("  filament retracted.");
646
     }
625
     }
647
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion
626
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion
648
 
627
 
650
 
629
 
651
     un_retract_filament();
630
     un_retract_filament();
652
 
631
 
653
-    //if (g26_debug_flag) {
632
+    //if (ubl.g26_debug_flag) {
654
     //  SERIAL_ECHOLNPGM("  doing printing move.");
633
     //  SERIAL_ECHOLNPGM("  doing printing move.");
655
     //  debug_current_and_destination((char*)"doing final move_to() inside print_line_from_here_to_there()");
634
     //  debug_current_and_destination((char*)"doing final move_to() inside print_line_from_here_to_there()");
656
     //}
635
     //}
810
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
789
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
811
           lcd_quick_feedback();
790
           lcd_quick_feedback();
812
       #endif
791
       #endif
813
-          ubl_has_control_of_lcd_panel = true;
792
+          ubl.has_control_of_lcd_panel++;
814
           thermalManager.setTargetBed(bed_temp);
793
           thermalManager.setTargetBed(bed_temp);
815
           while (abs(thermalManager.degBed() - bed_temp) > 3) {
794
           while (abs(thermalManager.degBed() - bed_temp) > 3) {
816
             if (ubl_lcd_clicked()) return exit_from_g26();
795
             if (ubl_lcd_clicked()) return exit_from_g26();
845
     float Total_Prime = 0.0;
824
     float Total_Prime = 0.0;
846
 
825
 
847
     if (prime_flag == -1) {  // The user wants to control how much filament gets purged
826
     if (prime_flag == -1) {  // The user wants to control how much filament gets purged
827
+
828
+      ubl.has_control_of_lcd_panel++;
829
+
848
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
830
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
849
       chirp_at_user();
831
       chirp_at_user();
850
 
832
 
881
         lcd_setstatuspgm(PSTR("Done Priming"), 99);
863
         lcd_setstatuspgm(PSTR("Done Priming"), 99);
882
         lcd_quick_feedback();
864
         lcd_quick_feedback();
883
       #endif
865
       #endif
866
+
867
+      ubl.has_control_of_lcd_panel = false;
868
+
884
     }
869
     }
885
     else {
870
     else {
886
       #if ENABLED(ULTRA_LCD)
871
       #if ENABLED(ULTRA_LCD)
901
     return UBL_OK;
886
     return UBL_OK;
902
   }
887
   }
903
 
888
 
904
-#endif // AUTO_BED_LEVELING_UBL && UBL_MESH_EDIT_ENABLED
889
+#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_EDITING

+ 2
- 2
Marlin/M100_Free_Mem_Chk.cpp View File

76
       // We want to start and end the dump on a nice 16 byte boundry even though
76
       // We want to start and end the dump on a nice 16 byte boundry even though
77
       // the values we are using are not 16 byte aligned.
77
       // the values we are using are not 16 byte aligned.
78
       //
78
       //
79
-      SERIAL_ECHOPAIR("\nbss_end : ", hex_word((uint16_t)ptr));
79
+      SERIAL_ECHOPAIR("\nbss_end : 0x", hex_word((uint16_t)ptr));
80
       ptr = (char*)((uint32_t)ptr & 0xfff0);
80
       ptr = (char*)((uint32_t)ptr & 0xfff0);
81
       sp = top_of_stack();
81
       sp = top_of_stack();
82
-      SERIAL_ECHOLNPAIR("\nStack Pointer : ", hex_word((uint16_t)sp));
82
+      SERIAL_ECHOLNPAIR("\nStack Pointer : 0x", hex_word((uint16_t)sp));
83
       sp = (char*)((uint32_t)sp | 0x000f);
83
       sp = (char*)((uint32_t)sp | 0x000f);
84
       n = sp - ptr;
84
       n = sp - ptr;
85
       //
85
       //

+ 4
- 0
Marlin/Marlin.h View File

430
 void do_blocking_move_to_z(const float &z, const float &fr_mm_s=0.0);
430
 void do_blocking_move_to_z(const float &z, const float &fr_mm_s=0.0);
431
 void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s=0.0);
431
 void do_blocking_move_to_xy(const float &x, const float &y, const float &fr_mm_s=0.0);
432
 
432
 
433
+#if ENABLED(Z_PROBE_ALLEN_KEY) || ENABLED(Z_PROBE_SLED) || HAS_PROBING_PROCEDURE || HOTENDS > 1 || ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE)
434
+  bool axis_unhomed_error(const bool x, const bool y, const bool z);
435
+#endif
436
+
433
 #endif //MARLIN_H
437
 #endif //MARLIN_H

+ 65
- 43
Marlin/Marlin_main.cpp View File

299
 #if ENABLED(AUTO_BED_LEVELING_UBL)
299
 #if ENABLED(AUTO_BED_LEVELING_UBL)
300
   #include "UBL.h"
300
   #include "UBL.h"
301
   unified_bed_leveling ubl;
301
   unified_bed_leveling ubl;
302
-#define UBL_MESH_VALID !(   z_values[0][0] == z_values[0][1] && z_values[0][1] == z_values[0][2] \
303
-                         && z_values[1][0] == z_values[1][1] && z_values[1][1] == z_values[1][2] \
304
-                         && z_values[2][0] == z_values[2][1] && z_values[2][1] == z_values[2][2] \
305
-                         && z_values[0][0] == 0 && z_values[1][0] == 0 && z_values[2][0] == 0    \
306
-                         || isnan(z_values[0][0]))
302
+  #define UBL_MESH_VALID !( ( ubl.z_values[0][0] == ubl.z_values[0][1] && ubl.z_values[0][1] == ubl.z_values[0][2] \
303
+                           && ubl.z_values[1][0] == ubl.z_values[1][1] && ubl.z_values[1][1] == ubl.z_values[1][2] \
304
+                           && ubl.z_values[2][0] == ubl.z_values[2][1] && ubl.z_values[2][1] == ubl.z_values[2][2] \
305
+                           && ubl.z_values[0][0] == 0 && ubl.z_values[1][0] == 0 && ubl.z_values[2][0] == 0 )  \
306
+                           || isnan(ubl.z_values[0][0]))
307
 #endif
307
 #endif
308
 
308
 
309
 bool Running = true;
309
 bool Running = true;
3221
    */
3221
    */
3222
   inline void gcode_G12() {
3222
   inline void gcode_G12() {
3223
     // Don't allow nozzle cleaning without homing first
3223
     // Don't allow nozzle cleaning without homing first
3224
-    if (axis_unhomed_error(true, true, true)) { return; }
3224
+    if (axis_unhomed_error(true, true, true)) return;
3225
 
3225
 
3226
     const uint8_t pattern = code_seen('P') ? code_value_ushort() : 0,
3226
     const uint8_t pattern = code_seen('P') ? code_value_ushort() : 0,
3227
                   strokes = code_seen('S') ? code_value_ushort() : NOZZLE_CLEAN_STROKES,
3227
                   strokes = code_seen('S') ? code_value_ushort() : NOZZLE_CLEAN_STROKES,
5344
 
5344
 
5345
 #endif // Z_MIN_PROBE_REPEATABILITY_TEST
5345
 #endif // Z_MIN_PROBE_REPEATABILITY_TEST
5346
 
5346
 
5347
-#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
5347
+#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_EDITING)
5348
 
5348
 
5349
   inline void gcode_M49() {
5349
   inline void gcode_M49() {
5350
+    ubl.g26_debug_flag = !ubl.g26_debug_flag;
5350
     SERIAL_PROTOCOLPGM("UBL Debug Flag turned ");
5351
     SERIAL_PROTOCOLPGM("UBL Debug Flag turned ");
5351
-    if ((g26_debug_flag = !g26_debug_flag))
5352
-      SERIAL_PROTOCOLLNPGM("on.");
5353
-    else
5354
-      SERIAL_PROTOCOLLNPGM("off.");
5352
+    serialprintPGM(ubl.g26_debug_flag ? PSTR("on.") : PSTR("off."));
5355
   }
5353
   }
5356
 
5354
 
5357
-#endif // AUTO_BED_LEVELING_UBL && UBL_MESH_EDIT_ENABLED
5355
+#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_EDITING
5358
 
5356
 
5359
 /**
5357
 /**
5360
  * M75: Start print timer
5358
  * M75: Start print timer
7210
   /**
7208
   /**
7211
    * M420: Enable/Disable Bed Leveling and/or set the Z fade height.
7209
    * M420: Enable/Disable Bed Leveling and/or set the Z fade height.
7212
    *
7210
    *
7213
-   *       S[bool]   Turns leveling on or off
7214
-   *       Z[height] Sets the Z fade height (0 or none to disable)
7215
-   *       V[bool]   Verbose - Print the leveling grid
7211
+   *   S[bool]   Turns leveling on or off
7212
+   *   Z[height] Sets the Z fade height (0 or none to disable)
7213
+   *   V[bool]   Verbose - Print the leveling grid
7214
+   *
7215
+   *   With AUTO_BED_LEVELING_UBL only:
7216
+   *
7217
+   *     L[index]  Load UBL mesh from index (0 is default)
7216
    */
7218
    */
7217
   inline void gcode_M420() {
7219
   inline void gcode_M420() {
7218
-    bool to_enable = false;
7219
 
7220
 
7221
+    #if ENABLED(AUTO_BED_LEVELING_UBL)
7222
+      // L to load a mesh from the EEPROM
7223
+      if (code_seen('L')) {
7224
+        const int8_t storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
7225
+        const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(ubl.z_values);
7226
+        if (storage_slot < 0 || storage_slot >= j || ubl.eeprom_start <= 0) {
7227
+          SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
7228
+          return;
7229
+        }
7230
+
7231
+        ubl.load_mesh(storage_slot);
7232
+        if (storage_slot != ubl.state.eeprom_storage_slot) ubl.store_state();
7233
+        ubl.state.eeprom_storage_slot = storage_slot;
7234
+        ubl.display_map(0);  // Right now, we only support one type of map
7235
+        SERIAL_ECHOLNPAIR("UBL_MESH_VALID =  ", UBL_MESH_VALID);
7236
+        SERIAL_ECHOLNPAIR("eeprom_storage_slot = ", ubl.state.eeprom_storage_slot);
7237
+      }
7238
+    #endif // AUTO_BED_LEVELING_UBL
7239
+
7240
+    // V to print the matrix or mesh
7241
+    if (code_seen('V')) {
7242
+      #if ABL_PLANAR
7243
+        planner.bed_level_matrix.debug("Bed Level Correction Matrix:");
7244
+      #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
7245
+        if (bilinear_grid_spacing[X_AXIS]) {
7246
+          print_bilinear_leveling_grid();
7247
+          #if ENABLED(ABL_BILINEAR_SUBDIVISION)
7248
+            bed_level_virt_print();
7249
+          #endif
7250
+        }
7251
+      #elif ENABLED(AUTO_BED_LEVELING_UBL)
7252
+        ubl.display_map(0);  // Currently only supports one map type
7253
+        SERIAL_ECHOLNPAIR("UBL_MESH_VALID =  ", UBL_MESH_VALID);
7254
+        SERIAL_ECHOLNPAIR("eeprom_storage_slot = ", ubl.state.eeprom_storage_slot);
7255
+      #elif ENABLED(MESH_BED_LEVELING)
7256
+        if (mbl.has_mesh()) {
7257
+          SERIAL_ECHOLNPGM("Mesh Bed Level data:");
7258
+          mbl_mesh_report();
7259
+        }
7260
+      #endif
7261
+    }
7262
+
7263
+    bool to_enable = false;
7220
     if (code_seen('S')) {
7264
     if (code_seen('S')) {
7221
       to_enable = code_value_bool();
7265
       to_enable = code_value_bool();
7222
       set_bed_leveling_enabled(to_enable);
7266
       set_bed_leveling_enabled(to_enable);
7243
 
7287
 
7244
     SERIAL_ECHO_START;
7288
     SERIAL_ECHO_START;
7245
     SERIAL_ECHOLNPAIR("Bed Leveling ", new_status ? MSG_ON : MSG_OFF);
7289
     SERIAL_ECHOLNPAIR("Bed Leveling ", new_status ? MSG_ON : MSG_OFF);
7246
-
7247
-    // V to print the matrix or mesh
7248
-    if (code_seen('V')) {
7249
-      #if ABL_PLANAR
7250
-        planner.bed_level_matrix.debug("Bed Level Correction Matrix:");
7251
-      #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
7252
-        if (bilinear_grid_spacing[X_AXIS]) {
7253
-          print_bilinear_leveling_grid();
7254
-          #if ENABLED(ABL_BILINEAR_SUBDIVISION)
7255
-            bed_level_virt_print();
7256
-          #endif
7257
-        }
7258
-      #elif ENABLED(AUTO_BED_LEVELING_UBL)
7259
-        ubl.display_map(0);  // Right now, we only support one type of map
7260
-      #elif ENABLED(MESH_BED_LEVELING)
7261
-        if (mbl.has_mesh()) {
7262
-          SERIAL_ECHOLNPGM("Mesh Bed Level data:");
7263
-          mbl_mesh_report();
7264
-        }
7265
-      #endif
7266
-    }
7267
-
7268
   }
7290
   }
7269
 #endif
7291
 #endif
7270
 
7292
 
8579
           break;
8601
           break;
8580
       #endif // INCH_MODE_SUPPORT
8602
       #endif // INCH_MODE_SUPPORT
8581
 
8603
 
8582
-      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
8604
+      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_EDITING)
8583
         case 26: // G26: Mesh Validation Pattern generation
8605
         case 26: // G26: Mesh Validation Pattern generation
8584
           gcode_G26();
8606
           gcode_G26();
8585
           break;
8607
           break;
8595
         gcode_G28();
8617
         gcode_G28();
8596
         break;
8618
         break;
8597
 
8619
 
8598
-      #if PLANNER_LEVELING
8620
+      #if PLANNER_LEVELING && !ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_EDITING)
8599
         case 29: // G29 Detailed Z probe, probes the bed at 3 or more points,
8621
         case 29: // G29 Detailed Z probe, probes the bed at 3 or more points,
8600
                  // or provides access to the UBL System if enabled.
8622
                  // or provides access to the UBL System if enabled.
8601
           gcode_G29();
8623
           gcode_G29();
8711
           break;
8733
           break;
8712
       #endif // Z_MIN_PROBE_REPEATABILITY_TEST
8734
       #endif // Z_MIN_PROBE_REPEATABILITY_TEST
8713
 
8735
 
8714
-      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_MESH_EDIT_ENABLED)
8715
-        case 49: // M49: Turn on or off g26_debug_flag for verbose output
8736
+      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_EDITING)
8737
+        case 49: // M49: Turn on or off G26 debug flag for verbose output
8716
           gcode_M49();
8738
           gcode_M49();
8717
           break;
8739
           break;
8718
-      #endif // AUTO_BED_LEVELING_UBL && UBL_MESH_EDIT_ENABLED
8740
+      #endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_EDITING
8719
 
8741
 
8720
       case 75: // M75: Start print timer
8742
       case 75: // M75: Start print timer
8721
         gcode_M75(); break;
8743
         gcode_M75(); break;

+ 238
- 231
Marlin/UBL.h View File

39
 
39
 
40
     enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
40
     enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
41
 
41
 
42
-    bool axis_unhomed_error(bool, bool, bool);
43
     void dump(char * const str, const float &f);
42
     void dump(char * const str, const float &f);
44
     bool ubl_lcd_clicked();
43
     bool ubl_lcd_clicked();
45
     void probe_entire_mesh(const float&, const float&, const bool, const bool, const bool);
44
     void probe_entire_mesh(const float&, const float&, const bool, const bool, const bool);
78
 
77
 
79
     enum MBLStatus { MBL_STATUS_NONE = 0, MBL_STATUS_HAS_MESH_BIT = 0, MBL_STATUS_ACTIVE_BIT = 1 };
78
     enum MBLStatus { MBL_STATUS_NONE = 0, MBL_STATUS_HAS_MESH_BIT = 0, MBL_STATUS_ACTIVE_BIT = 1 };
80
 
79
 
81
-    #define MESH_X_DIST ((float(UBL_MESH_MAX_X) - float(UBL_MESH_MIN_X)) / (float(UBL_MESH_NUM_X_POINTS) - 1.0))
82
-    #define MESH_Y_DIST ((float(UBL_MESH_MAX_Y) - float(UBL_MESH_MIN_Y)) / (float(UBL_MESH_NUM_Y_POINTS) - 1.0))
80
+    #define MESH_X_DIST (float(UBL_MESH_MAX_X - (UBL_MESH_MIN_X)) / float(UBL_MESH_NUM_X_POINTS - 1))
81
+    #define MESH_Y_DIST (float(UBL_MESH_MAX_Y - (UBL_MESH_MIN_Y)) / float(UBL_MESH_NUM_Y_POINTS - 1))
83
 
82
 
84
-    #if ENABLED(UBL_MESH_EDIT_ENABLED)
85
-      extern bool g26_debug_flag;
86
-    #else
87
-      constexpr bool g26_debug_flag = false;
88
-    #endif
89
-    extern float last_specified_z;
90
-    extern float fade_scaling_factor_for_current_height;
91
-    extern float z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS];
92
-    extern float mesh_index_to_x_location[UBL_MESH_NUM_X_POINTS + 1]; // +1 just because of paranoia that we might end up on the
93
-    extern float mesh_index_to_y_location[UBL_MESH_NUM_Y_POINTS + 1]; // the last Mesh Line and that is the start of a whole new cell
83
+    typedef struct {
84
+      bool active = false;
85
+      float z_offset = 0.0;
86
+      int8_t eeprom_storage_slot = -1,
87
+             n_x = UBL_MESH_NUM_X_POINTS,
88
+             n_y = UBL_MESH_NUM_Y_POINTS;
89
+
90
+      float mesh_x_min = UBL_MESH_MIN_X,
91
+            mesh_y_min = UBL_MESH_MIN_Y,
92
+            mesh_x_max = UBL_MESH_MAX_X,
93
+            mesh_y_max = UBL_MESH_MAX_Y,
94
+            mesh_x_dist = MESH_X_DIST,
95
+            mesh_y_dist = MESH_Y_DIST;
96
+
97
+      #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
98
+        float g29_correction_fade_height = 10.0,
99
+              g29_fade_height_multiplier = 1.0 / 10.0; // It's cheaper to do a floating point multiply than divide,
100
+                                                       // so keep this value and its reciprocal.
101
+      #else
102
+        const float g29_correction_fade_height = 10.0,
103
+                    g29_fade_height_multiplier = 1.0 / 10.0;
104
+      #endif
105
+
106
+      // If you change this struct, adjust TOTAL_STRUCT_SIZE
107
+
108
+      #define TOTAL_STRUCT_SIZE 40 // Total size of the above fields
109
+
110
+      // padding provides space to add state variables without
111
+      // changing the location of data structures in the EEPROM.
112
+      // This is for compatibility with future versions to keep
113
+      // users from having to regenerate their mesh data.
114
+      unsigned char padding[64 - TOTAL_STRUCT_SIZE];
115
+
116
+    } ubl_state;
94
 
117
 
95
     class unified_bed_leveling {
118
     class unified_bed_leveling {
119
+      private:
120
+
121
+        static float last_specified_z,
122
+                     fade_scaling_factor_for_current_height;
123
+
96
       public:
124
       public:
97
-      struct ubl_state {
98
-        bool active = false;
99
-        float z_offset = 0.0;
100
-        int eeprom_storage_slot = -1,
101
-            n_x = UBL_MESH_NUM_X_POINTS,
102
-            n_y = UBL_MESH_NUM_Y_POINTS;
103
-        float mesh_x_min = UBL_MESH_MIN_X,
104
-              mesh_y_min = UBL_MESH_MIN_Y,
105
-              mesh_x_max = UBL_MESH_MAX_X,
106
-              mesh_y_max = UBL_MESH_MAX_Y,
107
-              mesh_x_dist = MESH_X_DIST,
108
-              mesh_y_dist = MESH_Y_DIST;
109
 
125
 
110
-        #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
111
-          float g29_correction_fade_height = 10.0,
112
-                g29_fade_height_multiplier = 1.0 / 10.0; // It is cheaper to do a floating point multiply than a floating
113
-                                                         // point divide. So, we keep this number in both forms. The first
114
-                                                         // is for the user. The second one is the one that is actually used
115
-                                                         // again and again and again during the correction calculations.
116
-        #endif
126
+        static ubl_state state, pre_initialized;
117
 
127
 
118
-        unsigned char padding[24];  // This is just to allow room to add state variables without
119
-                                    // changing the location of data structures in the EEPROM.
120
-                                    // This is for compatability with future versions to keep
121
-                                    // people from having to regenerate thier mesh data.
122
-                                    //
123
-                                    // If you change the contents of this struct, please adjust
124
-                                    // the padding[] to keep the size the same!
125
-      } state, pre_initialized;
126
-
127
-      unified_bed_leveling();
128
-      //  ~unified_bed_leveling();  // No destructor because this object never goes away!
129
-
130
-      void display_map(const int);
131
-
132
-      void reset();
133
-      void invalidate();
134
-
135
-      void store_state();
136
-      void load_state();
137
-      void store_mesh(const int16_t);
138
-      void load_mesh(const int16_t);
139
-
140
-      bool sanity_check();
141
-
142
-      FORCE_INLINE static float map_x_index_to_bed_location(const int8_t i) { return ((float) UBL_MESH_MIN_X) + (((float) MESH_X_DIST) * (float) i); };
143
-      FORCE_INLINE static float map_y_index_to_bed_location(const int8_t i) { return ((float) UBL_MESH_MIN_Y) + (((float) MESH_Y_DIST) * (float) i); };
144
-
145
-      FORCE_INLINE void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
146
-
147
-      static int8_t get_cell_index_x(const float &x) {
148
-        const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
149
-        return constrain(cx, 0, (UBL_MESH_NUM_X_POINTS) - 1);   // -1 is appropriate if we want all movement to the X_MAX
150
-      }                                                         // position. But with this defined this way, it is possible
151
-                                                                // to extrapolate off of this point even further out. Probably
152
-                                                                // that is OK because something else should be keeping that from
153
-                                                                // happening and should not be worried about at this level.
154
-      static int8_t get_cell_index_y(const float &y) {
155
-        const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
156
-        return constrain(cy, 0, (UBL_MESH_NUM_Y_POINTS) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
157
-      }                                                         // position. But with this defined this way, it is possible
158
-                                                                // to extrapolate off of this point even further out. Probably
159
-                                                                // that is OK because something else should be keeping that from
160
-                                                                // happening and should not be worried about at this level.
161
-
162
-      static int8_t find_closest_x_index(const float &x) {
163
-        const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
164
-        return (px >= 0 && px < (UBL_MESH_NUM_X_POINTS)) ? px : -1;
165
-      }
166
-
167
-      static int8_t find_closest_y_index(const float &y) {
168
-        const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
169
-        return (py >= 0 && py < (UBL_MESH_NUM_Y_POINTS)) ? py : -1;
170
-      }
171
-
172
-      /**
173
-       *                           z2   --|
174
-       *                 z0        |      |
175
-       *                  |        |      + (z2-z1)
176
-       *   z1             |        |      |
177
-       * ---+-------------+--------+--  --|
178
-       *   a1            a0        a2
179
-       *    |<---delta_a---------->|
180
-       *
181
-       *  calc_z0 is the basis for all the Mesh Based correction. It is used to
182
-       *  find the expected Z Height at a position between two known Z-Height locations.
183
-       *
184
-       *  It is fairly expensive with its 4 floating point additions and 2 floating point
185
-       *  multiplications.
186
-       */
187
-      static FORCE_INLINE float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
188
-        const float delta_z = (z2 - z1),
189
-                    delta_a = (a0 - a1) / (a2 - a1);
190
-        return z1 + delta_a * delta_z;
191
-      }
192
-
193
-      /**
194
-       * get_z_correction_at_Y_intercept(float x0, int x1_i, int yi) only takes
195
-       * three parameters. It assumes the x0 point is on a Mesh line denoted by yi. In theory
196
-       * we could use get_cell_index_x(float x) to obtain the 2nd parameter x1_i but any code calling
197
-       * the get_z_correction_along_vertical_mesh_line_at_specific_X routine  will already have
198
-       * the X index of the x0 intersection available and we don't want to perform any extra floating
199
-       * point operations.
200
-       */
201
-      inline float get_z_correction_along_horizontal_mesh_line_at_specific_X(const float &x0, const int x1_i, const int yi) {
202
-        if (x1_i < 0 || yi < 0 || x1_i >= UBL_MESH_NUM_X_POINTS || yi >= UBL_MESH_NUM_Y_POINTS) {
203
-          SERIAL_ECHOPAIR("? in get_z_correction_along_horizontal_mesh_line_at_specific_X(x0=", x0);
204
-          SERIAL_ECHOPAIR(",x1_i=", x1_i);
205
-          SERIAL_ECHOPAIR(",yi=", yi);
206
-          SERIAL_CHAR(')');
207
-          SERIAL_EOL;
208
-          return NAN;
128
+        static float z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS],
129
+                     mesh_index_to_xpos[UBL_MESH_NUM_X_POINTS + 1], // +1 safety margin for now, until determinism prevails
130
+                     mesh_index_to_ypos[UBL_MESH_NUM_Y_POINTS + 1];
131
+
132
+        static bool g26_debug_flag,
133
+                    has_control_of_lcd_panel;
134
+
135
+        static int8_t eeprom_start;
136
+
137
+        static volatile int encoder_diff; // Volatile because it's changed at interrupt time.
138
+
139
+        unified_bed_leveling();
140
+
141
+        static void display_map(const int);
142
+
143
+        static void reset();
144
+        static void invalidate();
145
+
146
+        static void store_state();
147
+        static void load_state();
148
+        static void store_mesh(const int16_t);
149
+        static void load_mesh(const int16_t);
150
+
151
+        static bool sanity_check();
152
+
153
+        static FORCE_INLINE void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
154
+
155
+        static int8_t get_cell_index_x(const float &x) {
156
+          const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
157
+          return constrain(cx, 0, (UBL_MESH_NUM_X_POINTS) - 1);   // -1 is appropriate if we want all movement to the X_MAX
158
+        }                                                         // position. But with this defined this way, it is possible
159
+                                                                  // to extrapolate off of this point even further out. Probably
160
+                                                                  // that is OK because something else should be keeping that from
161
+                                                                  // happening and should not be worried about at this level.
162
+        static int8_t get_cell_index_y(const float &y) {
163
+          const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
164
+          return constrain(cy, 0, (UBL_MESH_NUM_Y_POINTS) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
165
+        }                                                         // position. But with this defined this way, it is possible
166
+                                                                  // to extrapolate off of this point even further out. Probably
167
+                                                                  // that is OK because something else should be keeping that from
168
+                                                                  // happening and should not be worried about at this level.
169
+
170
+        static int8_t find_closest_x_index(const float &x) {
171
+          const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
172
+          return (px >= 0 && px < (UBL_MESH_NUM_X_POINTS)) ? px : -1;
209
         }
173
         }
210
 
174
 
211
-        const float xratio = (RAW_X_POSITION(x0) - mesh_index_to_x_location[x1_i]) * (1.0 / (MESH_X_DIST)),
212
-                    z1 = z_values[x1_i][yi],
213
-                    z2 = z_values[x1_i + 1][yi],
214
-                    dz = (z2 - z1);
215
-
216
-        return z1 + xratio * dz;
217
-      }
218
-
219
-      //
220
-      // See comments above for get_z_correction_along_horizontal_mesh_line_at_specific_X
221
-      //
222
-      inline float get_z_correction_along_vertical_mesh_line_at_specific_Y(const float &y0, const int xi, const int y1_i) {
223
-        if (xi < 0 || y1_i < 0 || xi >= UBL_MESH_NUM_X_POINTS || y1_i >= UBL_MESH_NUM_Y_POINTS) {
224
-          SERIAL_ECHOPAIR("? in get_z_correction_along_vertical_mesh_line_at_specific_X(y0=", y0);
225
-          SERIAL_ECHOPAIR(", x1_i=", xi);
226
-          SERIAL_ECHOPAIR(", yi=", y1_i);
227
-          SERIAL_CHAR(')');
228
-          SERIAL_EOL;
229
-          return NAN;
175
+        static int8_t find_closest_y_index(const float &y) {
176
+          const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
177
+          return (py >= 0 && py < (UBL_MESH_NUM_Y_POINTS)) ? py : -1;
230
         }
178
         }
231
 
179
 
232
-        const float yratio = (RAW_Y_POSITION(y0) - mesh_index_to_y_location[y1_i]) * (1.0 / (MESH_Y_DIST)),
233
-                    z1 = z_values[xi][y1_i],
234
-                    z2 = z_values[xi][y1_i + 1],
235
-                    dz = (z2 - z1);
236
-
237
-        return z1 + yratio * dz;
238
-      }
239
-
240
-      /**
241
-       * This is the generic Z-Correction. It works anywhere within a Mesh Cell. It first
242
-       * does a linear interpolation along both of the bounding X-Mesh-Lines to find the
243
-       * Z-Height at both ends. Then it does a linear interpolation of these heights based
244
-       * on the Y position within the cell.
245
-       */
246
-      float get_z_correction(const float &x0, const float &y0) const {
247
-        const int8_t cx = get_cell_index_x(RAW_X_POSITION(x0)),
248
-                     cy = get_cell_index_y(RAW_Y_POSITION(y0));
249
-
250
-        if (cx < 0 || cy < 0 || cx >= UBL_MESH_NUM_X_POINTS || cy >= UBL_MESH_NUM_Y_POINTS) {
251
-
252
-          SERIAL_ECHOPAIR("? in get_z_correction(x0=", x0);
253
-          SERIAL_ECHOPAIR(", y0=", y0);
254
-          SERIAL_CHAR(')');
255
-          SERIAL_EOL;
256
-
257
-          #if ENABLED(ULTRA_LCD)
258
-            strcpy(lcd_status_message, "get_z_correction() indexes out of range.");
259
-            lcd_quick_feedback();
260
-          #endif
261
-          return 0.0; // this used to return state.z_offset
180
+        /**
181
+         *                           z2   --|
182
+         *                 z0        |      |
183
+         *                  |        |      + (z2-z1)
184
+         *   z1             |        |      |
185
+         * ---+-------------+--------+--  --|
186
+         *   a1            a0        a2
187
+         *    |<---delta_a---------->|
188
+         *
189
+         *  calc_z0 is the basis for all the Mesh Based correction. It is used to
190
+         *  find the expected Z Height at a position between two known Z-Height locations.
191
+         *
192
+         *  It is fairly expensive with its 4 floating point additions and 2 floating point
193
+         *  multiplications.
194
+         */
195
+        static FORCE_INLINE float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
196
+          const float delta_z = (z2 - z1),
197
+                      delta_a = (a0 - a1) / (a2 - a1);
198
+          return z1 + delta_a * delta_z;
262
         }
199
         }
263
 
200
 
264
-        const float z1 = calc_z0(RAW_X_POSITION(x0),
265
-                      map_x_index_to_bed_location(cx), z_values[cx][cy],
266
-                      map_x_index_to_bed_location(cx + 1), z_values[cx + 1][cy]),
267
-                    z2 = calc_z0(RAW_X_POSITION(x0),
268
-                      map_x_index_to_bed_location(cx), z_values[cx][cy + 1],
269
-                      map_x_index_to_bed_location(cx + 1), z_values[cx + 1][cy + 1]);
270
-              float z0 = calc_z0(RAW_Y_POSITION(y0),
271
-                  map_y_index_to_bed_location(cy), z1,
272
-                  map_y_index_to_bed_location(cy + 1), z2);
273
-
274
-        #if ENABLED(DEBUG_LEVELING_FEATURE)
275
-          if (DEBUGGING(MESH_ADJUST)) {
276
-            SERIAL_ECHOPAIR(" raw get_z_correction(", x0);
277
-            SERIAL_ECHOPAIR(",", y0);
278
-            SERIAL_ECHOPGM(")=");
279
-            SERIAL_ECHO_F(z0, 6);
201
+        /**
202
+         * get_z_correction_at_Y_intercept(float x0, int x1_i, int yi) only takes
203
+         * three parameters. It assumes the x0 point is on a Mesh line denoted by yi. In theory
204
+         * we could use get_cell_index_x(float x) to obtain the 2nd parameter x1_i but any code calling
205
+         * the get_z_correction_along_vertical_mesh_line_at_specific_X routine  will already have
206
+         * the X index of the x0 intersection available and we don't want to perform any extra floating
207
+         * point operations.
208
+         */
209
+        static inline float get_z_correction_along_horizontal_mesh_line_at_specific_X(const float &x0, const int x1_i, const int yi) {
210
+          if (x1_i < 0 || yi < 0 || x1_i >= UBL_MESH_NUM_X_POINTS || yi >= UBL_MESH_NUM_Y_POINTS) {
211
+            SERIAL_ECHOPAIR("? in get_z_correction_along_horizontal_mesh_line_at_specific_X(x0=", x0);
212
+            SERIAL_ECHOPAIR(",x1_i=", x1_i);
213
+            SERIAL_ECHOPAIR(",yi=", yi);
214
+            SERIAL_CHAR(')');
215
+            SERIAL_EOL;
216
+            return NAN;
280
           }
217
           }
281
-        #endif
282
 
218
 
283
-        #if ENABLED(DEBUG_LEVELING_FEATURE)
284
-          if (DEBUGGING(MESH_ADJUST)) {
285
-            SERIAL_ECHOPGM(" >>>---> ");
286
-            SERIAL_ECHO_F(z0, 6);
219
+          const float xratio = (RAW_X_POSITION(x0) - mesh_index_to_xpos[x1_i]) * (1.0 / (MESH_X_DIST)),
220
+                      z1 = z_values[x1_i][yi],
221
+                      z2 = z_values[x1_i + 1][yi],
222
+                      dz = (z2 - z1);
223
+
224
+          return z1 + xratio * dz;
225
+        }
226
+
227
+        //
228
+        // See comments above for get_z_correction_along_horizontal_mesh_line_at_specific_X
229
+        //
230
+        static inline float get_z_correction_along_vertical_mesh_line_at_specific_Y(const float &y0, const int xi, const int y1_i) {
231
+          if (xi < 0 || y1_i < 0 || xi >= UBL_MESH_NUM_X_POINTS || y1_i >= UBL_MESH_NUM_Y_POINTS) {
232
+            SERIAL_ECHOPAIR("? in get_z_correction_along_vertical_mesh_line_at_specific_X(y0=", y0);
233
+            SERIAL_ECHOPAIR(", x1_i=", xi);
234
+            SERIAL_ECHOPAIR(", yi=", y1_i);
235
+            SERIAL_CHAR(')');
287
             SERIAL_EOL;
236
             SERIAL_EOL;
237
+            return NAN;
288
           }
238
           }
289
-        #endif
290
 
239
 
291
-        if (isnan(z0)) { // if part of the Mesh is undefined, it will show up as NAN
292
-          z0 = 0.0;      // in ubl.z_values[][] and propagate through the
293
-                         // calculations. If our correction is NAN, we throw it out
294
-                         // because part of the Mesh is undefined and we don't have the
295
-                         // information we need to complete the height correction.
240
+          const float yratio = (RAW_Y_POSITION(y0) - mesh_index_to_ypos[y1_i]) * (1.0 / (MESH_Y_DIST)),
241
+                      z1 = z_values[xi][y1_i],
242
+                      z2 = z_values[xi][y1_i + 1],
243
+                      dz = (z2 - z1);
244
+
245
+          return z1 + yratio * dz;
246
+        }
247
+
248
+        /**
249
+         * This is the generic Z-Correction. It works anywhere within a Mesh Cell. It first
250
+         * does a linear interpolation along both of the bounding X-Mesh-Lines to find the
251
+         * Z-Height at both ends. Then it does a linear interpolation of these heights based
252
+         * on the Y position within the cell.
253
+         */
254
+        static float get_z_correction(const float &x0, const float &y0) {
255
+          const int8_t cx = get_cell_index_x(RAW_X_POSITION(x0)),
256
+                       cy = get_cell_index_y(RAW_Y_POSITION(y0));
257
+
258
+          if (cx < 0 || cy < 0 || cx >= UBL_MESH_NUM_X_POINTS || cy >= UBL_MESH_NUM_Y_POINTS) {
259
+
260
+            SERIAL_ECHOPAIR("? in get_z_correction(x0=", x0);
261
+            SERIAL_ECHOPAIR(", y0=", y0);
262
+            SERIAL_CHAR(')');
263
+            SERIAL_EOL;
264
+
265
+            #if ENABLED(ULTRA_LCD)
266
+              strcpy(lcd_status_message, "get_z_correction() indexes out of range.");
267
+              lcd_quick_feedback();
268
+            #endif
269
+            return 0.0; // this used to return state.z_offset
270
+          }
271
+
272
+          const float z1 = calc_z0(RAW_X_POSITION(x0),
273
+                        mesh_index_to_xpos[cx], z_values[cx][cy],
274
+                        mesh_index_to_xpos[cx + 1], z_values[cx + 1][cy]),
275
+                      z2 = calc_z0(RAW_X_POSITION(x0),
276
+                        mesh_index_to_xpos[cx], z_values[cx][cy + 1],
277
+                        mesh_index_to_xpos[cx + 1], z_values[cx + 1][cy + 1]);
278
+                float z0 = calc_z0(RAW_Y_POSITION(y0),
279
+                    mesh_index_to_ypos[cy], z1,
280
+                    mesh_index_to_ypos[cy + 1], z2);
296
 
281
 
297
           #if ENABLED(DEBUG_LEVELING_FEATURE)
282
           #if ENABLED(DEBUG_LEVELING_FEATURE)
298
             if (DEBUGGING(MESH_ADJUST)) {
283
             if (DEBUGGING(MESH_ADJUST)) {
299
-              SERIAL_ECHOPGM("??? Yikes!  NAN in get_z_correction( ");
300
-              SERIAL_ECHO(x0);
301
-              SERIAL_ECHOPGM(", ");
284
+              SERIAL_ECHOPAIR(" raw get_z_correction(", x0);
285
+              SERIAL_CHAR(',')
302
               SERIAL_ECHO(y0);
286
               SERIAL_ECHO(y0);
303
-              SERIAL_ECHOLNPGM(" )");
287
+              SERIAL_ECHOPGM(") = ");
288
+              SERIAL_ECHO_F(z0, 6);
304
             }
289
             }
305
           #endif
290
           #endif
306
-        }
307
-        return z0; // there used to be a +state.z_offset on this line
308
-      }
309
-
310
-      /**
311
-       * This routine is used to scale the Z correction depending upon the current nozzle height. It is
312
-       * optimized for speed. It avoids floating point operations by checking if the requested scaling
313
-       * factor is going to be the same as the last time the function calculated a value. If so, it just
314
-       * returns it.
315
-       *
316
-       * It returns a scaling factor of 1.0 if UBL is inactive.
317
-       * It returns a scaling factor of 0.0 if Z is past the specified 'Fade Height'
318
-       */
319
-      #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
320
 
291
 
321
-        FORCE_INLINE float fade_scaling_factor_for_z(const float &lz) const {
322
-          const float rz = RAW_Z_POSITION(lz);
323
-          if (last_specified_z != rz) {
324
-            last_specified_z = rz;
325
-            fade_scaling_factor_for_current_height =
326
-              state.active && rz < state.g29_correction_fade_height
327
-                ? 1.0 - (rz * state.g29_fade_height_multiplier)
328
-                : 0.0;
292
+          #if ENABLED(DEBUG_LEVELING_FEATURE)
293
+            if (DEBUGGING(MESH_ADJUST)) {
294
+              SERIAL_ECHOPGM(" >>>---> ");
295
+              SERIAL_ECHO_F(z0, 6);
296
+              SERIAL_EOL;
297
+            }
298
+          #endif
299
+
300
+          if (isnan(z0)) { // if part of the Mesh is undefined, it will show up as NAN
301
+            z0 = 0.0;      // in ubl.z_values[][] and propagate through the
302
+                           // calculations. If our correction is NAN, we throw it out
303
+                           // because part of the Mesh is undefined and we don't have the
304
+                           // information we need to complete the height correction.
305
+
306
+            #if ENABLED(DEBUG_LEVELING_FEATURE)
307
+              if (DEBUGGING(MESH_ADJUST)) {
308
+                SERIAL_ECHOPAIR("??? Yikes!  NAN in get_z_correction(", x0);
309
+                SERIAL_CHAR(',');
310
+                SERIAL_ECHO(y0);
311
+                SERIAL_CHAR(')');
312
+                SERIAL_EOL;
313
+              }
314
+            #endif
329
           }
315
           }
330
-          return fade_scaling_factor_for_current_height;
316
+          return z0; // there used to be a +state.z_offset on this line
331
         }
317
         }
332
 
318
 
333
-      #else
319
+        /**
320
+         * This routine is used to scale the Z correction depending upon the current nozzle height. It is
321
+         * optimized for speed. It avoids floating point operations by checking if the requested scaling
322
+         * factor is going to be the same as the last time the function calculated a value. If so, it just
323
+         * returns it.
324
+         *
325
+         * It returns a scaling factor of 1.0 if UBL is inactive.
326
+         * It returns a scaling factor of 0.0 if Z is past the specified 'Fade Height'
327
+         */
328
+        #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
334
 
329
 
335
-        static constexpr float fade_scaling_factor_for_z(const float &lz) { UNUSED(lz); return 1.0; }
330
+          FORCE_INLINE float fade_scaling_factor_for_z(const float &lz) {
331
+            const float rz = RAW_Z_POSITION(lz);
332
+            if (last_specified_z != rz) {
333
+              last_specified_z = rz;
334
+              fade_scaling_factor_for_current_height =
335
+                state.active && rz < state.g29_correction_fade_height
336
+                  ? 1.0 - (rz * state.g29_fade_height_multiplier)
337
+                  : 0.0;
338
+            }
339
+            return fade_scaling_factor_for_current_height;
340
+          }
336
 
341
 
337
-      #endif
342
+        #else
343
+
344
+          static constexpr float fade_scaling_factor_for_z(const float &lz) { UNUSED(lz); return 1.0; }
345
+
346
+        #endif
338
 
347
 
339
     }; // class unified_bed_leveling
348
     }; // class unified_bed_leveling
340
 
349
 
341
     extern unified_bed_leveling ubl;
350
     extern unified_bed_leveling ubl;
342
-    extern int ubl_eeprom_start;
343
 
351
 
344
     #define UBL_LAST_EEPROM_INDEX (E2END - sizeof(unified_bed_leveling::state))
352
     #define UBL_LAST_EEPROM_INDEX (E2END - sizeof(unified_bed_leveling::state))
345
 
353
 
346
   #endif // AUTO_BED_LEVELING_UBL
354
   #endif // AUTO_BED_LEVELING_UBL
347
-
348
 #endif // UNIFIED_BED_LEVELING_H
355
 #endif // UNIFIED_BED_LEVELING_H

+ 35
- 47
Marlin/UBL_Bed_Leveling.cpp View File

57
     }
57
     }
58
   }
58
   }
59
 
59
 
60
-  /**
61
-   * These variables used to be declared inside the unified_bed_leveling class. We are going to
62
-   * still declare them within the .cpp file for bed leveling. But there is only one instance of
63
-   * the bed leveling object and we can get rid of a level of inderection by not making them
64
-   * 'member data'. So, in the interest of speed, we do it this way. On a 32-bit CPU they can be
65
-   * moved back inside the bed leveling class.
66
-   */
67
-  float last_specified_z,
68
-        fade_scaling_factor_for_current_height,
69
-        z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS],
70
-        mesh_index_to_x_location[UBL_MESH_NUM_X_POINTS + 1], // +1 just because of paranoia that we might end up on the
71
-        mesh_index_to_y_location[UBL_MESH_NUM_Y_POINTS + 1]; // the last Mesh Line and that is the start of a whole new cell
60
+  ubl_state unified_bed_leveling::state, unified_bed_leveling::pre_initialized;
72
 
61
 
73
-  unified_bed_leveling::unified_bed_leveling() {
74
-    for (uint8_t i = 0; i <= UBL_MESH_NUM_X_POINTS; i++)  // We go one past what we expect to ever need for safety
75
-      mesh_index_to_x_location[i] = double(UBL_MESH_MIN_X) + double(MESH_X_DIST) * double(i);
62
+  float unified_bed_leveling::z_values[UBL_MESH_NUM_X_POINTS][UBL_MESH_NUM_Y_POINTS],
63
+        unified_bed_leveling::last_specified_z,
64
+        unified_bed_leveling::fade_scaling_factor_for_current_height,
65
+        unified_bed_leveling::mesh_index_to_xpos[UBL_MESH_NUM_X_POINTS + 1], // +1 safety margin for now, until determinism prevails
66
+        unified_bed_leveling::mesh_index_to_ypos[UBL_MESH_NUM_Y_POINTS + 1];
67
+
68
+  bool unified_bed_leveling::g26_debug_flag = false,
69
+       unified_bed_leveling::has_control_of_lcd_panel = false;
76
 
70
 
77
-    for (uint8_t i = 0; i <= UBL_MESH_NUM_Y_POINTS; i++)  // We go one past what we expect to ever need for safety
78
-      mesh_index_to_y_location[i] = double(UBL_MESH_MIN_Y) + double(MESH_Y_DIST) * double(i);
71
+  int8_t unified_bed_leveling::eeprom_start = -1;
79
 
72
 
73
+  volatile int unified_bed_leveling::encoder_diff;
74
+
75
+  unified_bed_leveling::unified_bed_leveling() {
76
+    for (uint8_t i = 0; i < COUNT(mesh_index_to_xpos); i++)
77
+      mesh_index_to_xpos[i] = UBL_MESH_MIN_X + i * (MESH_X_DIST);
78
+    for (uint8_t i = 0; i < COUNT(mesh_index_to_ypos); i++)
79
+      mesh_index_to_ypos[i] = UBL_MESH_MIN_Y + i * (MESH_Y_DIST);
80
     reset();
80
     reset();
81
   }
81
   }
82
 
82
 
95
     #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
95
     #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
96
       /**
96
       /**
97
        * These lines can go away in a few weeks.  They are just
97
        * These lines can go away in a few weeks.  They are just
98
-       * to make sure people updating thier firmware won't be using
98
+       * to make sure people updating their firmware won't be using
99
        * an incomplete Bed_Leveling.state structure. For speed
99
        * an incomplete Bed_Leveling.state structure. For speed
100
        * we now multiply by the inverse of the Fade Height instead of
100
        * we now multiply by the inverse of the Fade Height instead of
101
        * dividing by it. Soon... all of the old structures will be
101
        * dividing by it. Soon... all of the old structures will be
110
   }
110
   }
111
 
111
 
112
   void unified_bed_leveling::load_mesh(const int16_t m) {
112
   void unified_bed_leveling::load_mesh(const int16_t m) {
113
-    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
113
+    int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
114
 
114
 
115
     if (m == -1) {
115
     if (m == -1) {
116
       SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n");
116
       SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n");
118
       return;
118
       return;
119
     }
119
     }
120
 
120
 
121
-    if (m < 0 || m >= j || ubl_eeprom_start <= 0) {
121
+    if (m < 0 || m >= j || eeprom_start <= 0) {
122
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
122
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
123
       return;
123
       return;
124
     }
124
     }
131
   }
131
   }
132
 
132
 
133
   void unified_bed_leveling::store_mesh(const int16_t m) {
133
   void unified_bed_leveling::store_mesh(const int16_t m) {
134
-    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
134
+    int16_t j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
135
 
135
 
136
-    if (m < 0 || m >= j || ubl_eeprom_start <= 0) {
136
+    if (m < 0 || m >= j || eeprom_start <= 0) {
137
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
137
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
138
       SERIAL_PROTOCOL(m);
138
       SERIAL_PROTOCOL(m);
139
       SERIAL_PROTOCOLLNPGM(" mesh slots available.\n");
139
       SERIAL_PROTOCOLLNPGM(" mesh slots available.\n");
164
   }
164
   }
165
 
165
 
166
   void unified_bed_leveling::invalidate() {
166
   void unified_bed_leveling::invalidate() {
167
-    print_hex_word((uint16_t)this);
168
-    SERIAL_EOL;
169
-
170
     state.active = false;
167
     state.active = false;
171
     state.z_offset = 0;
168
     state.z_offset = 0;
172
     for (int x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
169
     for (int x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
201
       for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
198
       for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
202
         const bool is_current = i == current_xi && j == current_yi;
199
         const bool is_current = i == current_xi && j == current_yi;
203
 
200
 
204
-        // is the nozzle here?  if so, mark the number
205
-        if (map0)
206
-          SERIAL_CHAR(is_current ? '[' : ' ');
201
+        // is the nozzle here? then mark the number
202
+        if (map0) SERIAL_CHAR(is_current ? '[' : ' ');
207
 
203
 
208
         const float f = z_values[i][j];
204
         const float f = z_values[i][j];
209
         if (isnan(f)) {
205
         if (isnan(f)) {
211
         }
207
         }
212
         else {
208
         else {
213
           // if we don't do this, the columns won't line up nicely
209
           // if we don't do this, the columns won't line up nicely
214
-          if (f >= 0.0 && map0) SERIAL_CHAR(' ');
210
+          if (map0 && f >= 0.0) SERIAL_CHAR(' ');
215
           SERIAL_PROTOCOL_F(f, 3);
211
           SERIAL_PROTOCOL_F(f, 3);
216
           idle();
212
           idle();
217
         }
213
         }
218
-        if (!map0 && i < UBL_MESH_NUM_X_POINTS - 1)
219
-         SERIAL_CHAR(',');
214
+        if (!map0 && i < UBL_MESH_NUM_X_POINTS - 1) SERIAL_CHAR(',');
220
 
215
 
221
         #if TX_BUFFER_SIZE > 0
216
         #if TX_BUFFER_SIZE > 0
222
           MYSERIAL.flushTX();
217
           MYSERIAL.flushTX();
251
   bool unified_bed_leveling::sanity_check() {
246
   bool unified_bed_leveling::sanity_check() {
252
     uint8_t error_flag = 0;
247
     uint8_t error_flag = 0;
253
 
248
 
254
-    if (state.n_x !=  UBL_MESH_NUM_X_POINTS) {
249
+    if (state.n_x != UBL_MESH_NUM_X_POINTS) {
255
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_NUM_X_POINTS set wrong\n");
250
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_NUM_X_POINTS set wrong\n");
256
       error_flag++;
251
       error_flag++;
257
     }
252
     }
258
-
259
-    if (state.n_y !=  UBL_MESH_NUM_Y_POINTS) {
253
+    if (state.n_y != UBL_MESH_NUM_Y_POINTS) {
260
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_NUM_Y_POINTS set wrong\n");
254
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_NUM_Y_POINTS set wrong\n");
261
       error_flag++;
255
       error_flag++;
262
     }
256
     }
263
-
264
-    if (state.mesh_x_min !=  UBL_MESH_MIN_X) {
257
+    if (state.mesh_x_min != UBL_MESH_MIN_X) {
265
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_X set wrong\n");
258
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_X set wrong\n");
266
       error_flag++;
259
       error_flag++;
267
     }
260
     }
268
-
269
-    if (state.mesh_y_min !=  UBL_MESH_MIN_Y) {
261
+    if (state.mesh_y_min != UBL_MESH_MIN_Y) {
270
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_Y set wrong\n");
262
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_Y set wrong\n");
271
       error_flag++;
263
       error_flag++;
272
     }
264
     }
273
-
274
-    if (state.mesh_x_max !=  UBL_MESH_MAX_X) {
265
+    if (state.mesh_x_max != UBL_MESH_MAX_X) {
275
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_X set wrong\n");
266
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_X set wrong\n");
276
       error_flag++;
267
       error_flag++;
277
     }
268
     }
278
-
279
-    if (state.mesh_y_max !=  UBL_MESH_MAX_Y) {
269
+    if (state.mesh_y_max != UBL_MESH_MAX_Y) {
280
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_Y set wrong\n");
270
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_Y set wrong\n");
281
       error_flag++;
271
       error_flag++;
282
     }
272
     }
283
-
284
-    if (state.mesh_x_dist !=  MESH_X_DIST) {
273
+    if (state.mesh_x_dist != MESH_X_DIST) {
285
       SERIAL_PROTOCOLLNPGM("?MESH_X_DIST set wrong\n");
274
       SERIAL_PROTOCOLLNPGM("?MESH_X_DIST set wrong\n");
286
       error_flag++;
275
       error_flag++;
287
     }
276
     }
288
-
289
-    if (state.mesh_y_dist !=  MESH_Y_DIST) {
277
+    if (state.mesh_y_dist != MESH_Y_DIST) {
290
       SERIAL_PROTOCOLLNPGM("?MESH_Y_DIST set wrong\n");
278
       SERIAL_PROTOCOLLNPGM("?MESH_Y_DIST set wrong\n");
291
       error_flag++;
279
       error_flag++;
292
     }
280
     }
293
 
281
 
294
-    const int j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
282
+    const int j = (UBL_LAST_EEPROM_INDEX - eeprom_start) / sizeof(z_values);
295
     if (j < 1) {
283
     if (j < 1) {
296
       SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n");
284
       SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n");
297
       error_flag++;
285
       error_flag++;

+ 105
- 104
Marlin/UBL_G29.cpp View File

22
 
22
 
23
 #include "MarlinConfig.h"
23
 #include "MarlinConfig.h"
24
 
24
 
25
-#if ENABLED(AUTO_BED_LEVELING_UBL)
25
+#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_EDITING)
26
   //#include "vector_3.h"
26
   //#include "vector_3.h"
27
   //#include "qr_solve.h"
27
   //#include "qr_solve.h"
28
 
28
 
39
   void lcd_return_to_status();
39
   void lcd_return_to_status();
40
   bool lcd_clicked();
40
   bool lcd_clicked();
41
   void lcd_implementation_clear();
41
   void lcd_implementation_clear();
42
-
42
+  void lcd_mesh_edit_setup(float initial);
43
+  float lcd_mesh_edit();
44
+  void lcd_z_offset_edit_setup(float);
45
+  float lcd_z_offset_edit();
43
   extern float meshedit_done;
46
   extern float meshedit_done;
44
   extern long babysteps_done;
47
   extern long babysteps_done;
45
   extern float code_value_float();
48
   extern float code_value_float();
141
    *   P0    Phase 0    Zero Mesh Data and turn off the Mesh Compensation System. This reverts the
144
    *   P0    Phase 0    Zero Mesh Data and turn off the Mesh Compensation System. This reverts the
142
    *                    3D Printer to the same state it was in before the Unified Bed Leveling Compensation
145
    *                    3D Printer to the same state it was in before the Unified Bed Leveling Compensation
143
    *                    was turned on. Setting the entire Mesh to Zero is a special case that allows
146
    *                    was turned on. Setting the entire Mesh to Zero is a special case that allows
144
-   *                    a subsequent G or T leveling operation for backward compatability.
147
+   *                    a subsequent G or T leveling operation for backward compatibility.
145
    *
148
    *
146
    *   P1    Phase 1    Invalidate entire Mesh and continue with automatic generation of the Mesh data using
149
    *   P1    Phase 1    Invalidate entire Mesh and continue with automatic generation of the Mesh data using
147
    *                    the Z-Probe. Depending upon the values of DELTA_PROBEABLE_RADIUS and
150
    *                    the Z-Probe. Depending upon the values of DELTA_PROBEABLE_RADIUS and
294
    *   this is going to be helpful to the users!)
297
    *   this is going to be helpful to the users!)
295
    *
298
    *
296
    *   The foundation of this Bed Leveling System is built on Epatel's Mesh Bed Leveling code. A big
299
    *   The foundation of this Bed Leveling System is built on Epatel's Mesh Bed Leveling code. A big
297
-   *   'Thanks!' to him and the creators of 3-Point and Grid Based leveling. Combining thier contributions
300
+   *   'Thanks!' to him and the creators of 3-Point and Grid Based leveling. Combining their contributions
298
    *   we now have the functionality and features of all three systems combined.
301
    *   we now have the functionality and features of all three systems combined.
299
    */
302
    */
300
 
303
 
301
-  int ubl_eeprom_start = -1;
302
-  bool ubl_has_control_of_lcd_panel = false;
303
-  volatile int8_t ubl_encoderDiff = 0; // Volatile because it's changed by Temperature ISR button update
304
-
305
   // The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
304
   // The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
306
   static int g29_verbose_level, phase_value = -1, repetition_cnt,
305
   static int g29_verbose_level, phase_value = -1, repetition_cnt,
307
              storage_slot = 0, map_type; //unlevel_value = -1;
306
              storage_slot = 0, map_type; //unlevel_value = -1;
313
   #endif
312
   #endif
314
 
313
 
315
   void gcode_G29() {
314
   void gcode_G29() {
316
-    SERIAL_PROTOCOLLNPAIR("ubl_eeprom_start=", ubl_eeprom_start);
317
-    if (ubl_eeprom_start < 0) {
315
+    SERIAL_PROTOCOLLNPAIR("ubl.eeprom_start=", ubl.eeprom_start);
316
+    if (ubl.eeprom_start < 0) {
318
       SERIAL_PROTOCOLLNPGM("?You need to enable your EEPROM and initialize it");
317
       SERIAL_PROTOCOLLNPGM("?You need to enable your EEPROM and initialize it");
319
       SERIAL_PROTOCOLLNPGM("with M502, M500, M501 in that order.\n");
318
       SERIAL_PROTOCOLLNPGM("with M502, M500, M501 in that order.\n");
320
       return;
319
       return;
335
           SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n");
334
           SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n");
336
           break;            // No more invalid Mesh Points to populate
335
           break;            // No more invalid Mesh Points to populate
337
         }
336
         }
338
-        z_values[location.x_index][location.y_index] = NAN;
337
+        ubl.z_values[location.x_index][location.y_index] = NAN;
339
       }
338
       }
340
       SERIAL_PROTOCOLLNPGM("Locations invalidated.\n");
339
       SERIAL_PROTOCOLLNPGM("Locations invalidated.\n");
341
     }
340
     }
354
             for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++) { // a poorly calibrated Delta.
353
             for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++) { // a poorly calibrated Delta.
355
               const float p1 = 0.5 * (UBL_MESH_NUM_X_POINTS) - x,
354
               const float p1 = 0.5 * (UBL_MESH_NUM_X_POINTS) - x,
356
                           p2 = 0.5 * (UBL_MESH_NUM_Y_POINTS) - y;
355
                           p2 = 0.5 * (UBL_MESH_NUM_Y_POINTS) - y;
357
-              z_values[x][y] += 2.0 * HYPOT(p1, p2);
356
+              ubl.z_values[x][y] += 2.0 * HYPOT(p1, p2);
358
             }
357
             }
359
           }
358
           }
360
           break;
359
           break;
361
         case 1:
360
         case 1:
362
           for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++) {  // Create a diagonal line several Mesh cells thick that is raised
361
           for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++) {  // Create a diagonal line several Mesh cells thick that is raised
363
-            z_values[x][x] += 9.999;
364
-            z_values[x][x + (x < UBL_MESH_NUM_Y_POINTS - 1) ? 1 : -1] += 9.999; // We want the altered line several mesh points thick
362
+            ubl.z_values[x][x] += 9.999;
363
+            ubl.z_values[x][x + (x < UBL_MESH_NUM_Y_POINTS - 1) ? 1 : -1] += 9.999; // We want the altered line several mesh points thick
365
           }
364
           }
366
           break;
365
           break;
367
         case 2:
366
         case 2:
368
           // Allow the user to specify the height because 10mm is a little extreme in some cases.
367
           // Allow the user to specify the height because 10mm is a little extreme in some cases.
369
           for (uint8_t x = (UBL_MESH_NUM_X_POINTS) / 3; x < 2 * (UBL_MESH_NUM_X_POINTS) / 3; x++)   // Create a rectangular raised area in
368
           for (uint8_t x = (UBL_MESH_NUM_X_POINTS) / 3; x < 2 * (UBL_MESH_NUM_X_POINTS) / 3; x++)   // Create a rectangular raised area in
370
             for (uint8_t y = (UBL_MESH_NUM_Y_POINTS) / 3; y < 2 * (UBL_MESH_NUM_Y_POINTS) / 3; y++) // the center of the bed
369
             for (uint8_t y = (UBL_MESH_NUM_Y_POINTS) / 3; y < 2 * (UBL_MESH_NUM_Y_POINTS) / 3; y++) // the center of the bed
371
-              z_values[x][y] += code_seen('C') ? ubl_constant : 9.99;
370
+              ubl.z_values[x][y] += code_seen('C') ? ubl_constant : 9.99;
372
           break;
371
           break;
373
       }
372
       }
374
     }
373
     }
390
         return;
389
         return;
391
       }
390
       }
392
       switch (phase_value) {
391
       switch (phase_value) {
393
-        //
394
-        // Zero Mesh Data
395
-        //
396
         case 0:
392
         case 0:
393
+          //
394
+          // Zero Mesh Data
395
+          //
397
           ubl.reset();
396
           ubl.reset();
398
           SERIAL_PROTOCOLLNPGM("Mesh zeroed.\n");
397
           SERIAL_PROTOCOLLNPGM("Mesh zeroed.\n");
399
           break;
398
           break;
400
-        //
401
-        // Invalidate Entire Mesh and Automatically Probe Mesh in areas that can be reached by the probe
402
-        //
399
+
403
         case 1:
400
         case 1:
401
+          //
402
+          // Invalidate Entire Mesh and Automatically Probe Mesh in areas that can be reached by the probe
403
+          //
404
           if (!code_seen('C') ) {
404
           if (!code_seen('C') ) {
405
             ubl.invalidate();
405
             ubl.invalidate();
406
             SERIAL_PROTOCOLLNPGM("Mesh invalidated. Probing mesh.\n");
406
             SERIAL_PROTOCOLLNPGM("Mesh invalidated. Probing mesh.\n");
414
           probe_entire_mesh(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER,
414
           probe_entire_mesh(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER,
415
                             code_seen('O') || code_seen('M'), code_seen('E'), code_seen('U'));
415
                             code_seen('O') || code_seen('M'), code_seen('E'), code_seen('U'));
416
           break;
416
           break;
417
-        //
418
-        // Manually Probe Mesh in areas that can't be reached by the probe
419
-        //
417
+
420
         case 2: {
418
         case 2: {
419
+          //
420
+          // Manually Probe Mesh in areas that can't be reached by the probe
421
+          //
421
           SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.\n");
422
           SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.\n");
422
           do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
423
           do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
423
           if (!x_flag && !y_flag) {      // use a good default location for the path
424
           if (!x_flag && !y_flag) {      // use a good default location for the path
450
 
451
 
451
         } break;
452
         } break;
452
 
453
 
453
-        //
454
-        // Populate invalid Mesh areas with a constant
455
-        //
456
         case 3: {
454
         case 3: {
455
+          //
456
+          // Populate invalid Mesh areas with a constant
457
+          //
457
           const float height = code_seen('C') ? ubl_constant : 0.0;
458
           const float height = code_seen('C') ? ubl_constant : 0.0;
458
           // If no repetition is specified, do the whole Mesh
459
           // If no repetition is specified, do the whole Mesh
459
           if (!repeat_flag) repetition_cnt = 9999;
460
           if (!repeat_flag) repetition_cnt = 9999;
460
           while (repetition_cnt--) {
461
           while (repetition_cnt--) {
461
             const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 0, NULL, false); // The '0' says we want to use the nozzle's position
462
             const mesh_index_pair location = find_closest_mesh_point_of_type(INVALID, x_pos, y_pos, 0, NULL, false); // The '0' says we want to use the nozzle's position
462
             if (location.x_index < 0) break; // No more invalid Mesh Points to populate
463
             if (location.x_index < 0) break; // No more invalid Mesh Points to populate
463
-            z_values[location.x_index][location.y_index] = height;
464
+            ubl.z_values[location.x_index][location.y_index] = height;
464
           }
465
           }
465
         } break;
466
         } break;
466
 
467
 
467
-        //
468
-        // Fine Tune (Or Edit) the Mesh
469
-        //
470
         case 4:
468
         case 4:
469
+          //
470
+          // Fine Tune (i.e., Edit) the Mesh
471
+          //
471
           fine_tune_mesh(x_pos, y_pos, code_seen('O') || code_seen('M'));
472
           fine_tune_mesh(x_pos, y_pos, code_seen('O') || code_seen('M'));
472
           break;
473
           break;
473
         case 5:
474
         case 5:
482
           SERIAL_ECHO_START;
483
           SERIAL_ECHO_START;
483
           SERIAL_ECHOLNPGM("Checking G29 has control of LCD Panel:");
484
           SERIAL_ECHOLNPGM("Checking G29 has control of LCD Panel:");
484
           KEEPALIVE_STATE(PAUSED_FOR_USER);
485
           KEEPALIVE_STATE(PAUSED_FOR_USER);
485
-          ubl_has_control_of_lcd_panel++;
486
+          ubl.has_control_of_lcd_panel++;
486
           while (!ubl_lcd_clicked()) {
487
           while (!ubl_lcd_clicked()) {
487
             safe_delay(250);
488
             safe_delay(250);
488
-            if (ubl_encoderDiff) {
489
-              SERIAL_ECHOLN((int)ubl_encoderDiff);
490
-              ubl_encoderDiff = 0;
489
+            if (ubl.encoder_diff) {
490
+              SERIAL_ECHOLN((int)ubl.encoder_diff);
491
+              ubl.encoder_diff = 0;
491
             }
492
             }
492
           }
493
           }
493
           SERIAL_ECHOLNPGM("G29 giving back control of LCD Panel.");
494
           SERIAL_ECHOLNPGM("G29 giving back control of LCD Panel.");
494
-          ubl_has_control_of_lcd_panel = false;
495
+          ubl.has_control_of_lcd_panel = false;
495
           KEEPALIVE_STATE(IN_HANDLER);
496
           KEEPALIVE_STATE(IN_HANDLER);
496
           break;
497
           break;
497
 
498
 
503
           wait_for_user = true;
504
           wait_for_user = true;
504
           while (wait_for_user) {
505
           while (wait_for_user) {
505
             safe_delay(250);
506
             safe_delay(250);
506
-            if (ubl_encoderDiff) {
507
-              SERIAL_ECHOLN((int)ubl_encoderDiff);
508
-              ubl_encoderDiff = 0;
507
+            if (ubl.encoder_diff) {
508
+              SERIAL_ECHOLN((int)ubl.encoder_diff);
509
+              ubl.encoder_diff = 0;
509
             }
510
             }
510
           }
511
           }
511
           SERIAL_ECHOLNPGM("G29 giving back control of LCD Panel.");
512
           SERIAL_ECHOLNPGM("G29 giving back control of LCD Panel.");
557
     if (code_seen('L')) {     // Load Current Mesh Data
558
     if (code_seen('L')) {     // Load Current Mesh Data
558
       storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
559
       storage_slot = code_has_value() ? code_value_int() : ubl.state.eeprom_storage_slot;
559
 
560
 
560
-      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
561
+      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(ubl.z_values);
561
 
562
 
562
-      if (storage_slot < 0 || storage_slot >= j || ubl_eeprom_start <= 0) {
563
+      if (storage_slot < 0 || storage_slot >= j || ubl.eeprom_start <= 0) {
563
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
564
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
564
         return;
565
         return;
565
       }
566
       }
581
         SERIAL_ECHOLNPGM("G29 I 999");              // host in a form it can be reconstructed on a different machine
582
         SERIAL_ECHOLNPGM("G29 I 999");              // host in a form it can be reconstructed on a different machine
582
         for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
583
         for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
583
           for (uint8_t y = 0;  y < UBL_MESH_NUM_Y_POINTS; y++)
584
           for (uint8_t y = 0;  y < UBL_MESH_NUM_Y_POINTS; y++)
584
-            if (!isnan(z_values[x][y])) {
585
+            if (!isnan(ubl.z_values[x][y])) {
585
               SERIAL_ECHOPAIR("M421 I ", x);
586
               SERIAL_ECHOPAIR("M421 I ", x);
586
               SERIAL_ECHOPAIR(" J ", y);
587
               SERIAL_ECHOPAIR(" J ", y);
587
               SERIAL_ECHOPGM(" Z ");
588
               SERIAL_ECHOPGM(" Z ");
588
-              SERIAL_ECHO_F(z_values[x][y], 6);
589
+              SERIAL_ECHO_F(ubl.z_values[x][y], 6);
589
               SERIAL_EOL;
590
               SERIAL_EOL;
590
             }
591
             }
591
         return;
592
         return;
592
       }
593
       }
593
 
594
 
594
-      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values);
595
+      const int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(ubl.z_values);
595
 
596
 
596
-      if (storage_slot < 0 || storage_slot >= j || ubl_eeprom_start <= 0) {
597
+      if (storage_slot < 0 || storage_slot >= j || ubl.eeprom_start <= 0) {
597
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
598
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
598
         SERIAL_PROTOCOLLNPAIR("?Use 0 to ", j - 1);
599
         SERIAL_PROTOCOLLNPAIR("?Use 0 to ", j - 1);
599
         goto LEAVE;
600
         goto LEAVE;
617
         save_ubl_active_state_and_disable();
618
         save_ubl_active_state_and_disable();
618
         //measured_z = probe_pt(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, ProbeDeployAndStow, g29_verbose_level);
619
         //measured_z = probe_pt(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER, ProbeDeployAndStow, g29_verbose_level);
619
 
620
 
620
-        ubl_has_control_of_lcd_panel++;     // Grab the LCD Hardware
621
+        ubl.has_control_of_lcd_panel++;     // Grab the LCD Hardware
621
         measured_z = 1.5;
622
         measured_z = 1.5;
622
         do_blocking_move_to_z(measured_z);  // Get close to the bed, but leave some space so we don't damage anything
623
         do_blocking_move_to_z(measured_z);  // Get close to the bed, but leave some space so we don't damage anything
623
                                             // The user is not going to be locking in a new Z-Offset very often so
624
                                             // The user is not going to be locking in a new Z-Offset very often so
633
           do_blocking_move_to_z(measured_z);
634
           do_blocking_move_to_z(measured_z);
634
         } while (!ubl_lcd_clicked());
635
         } while (!ubl_lcd_clicked());
635
 
636
 
636
-        ubl_has_control_of_lcd_panel++;   // There is a race condition for the Encoder Wheel getting clicked.
637
+        ubl.has_control_of_lcd_panel++;   // There is a race condition for the Encoder Wheel getting clicked.
637
                                           // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
638
                                           // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
638
                                           // or here. So, until we are done looking for a long Encoder Wheel Press,
639
                                           // or here. So, until we are done looking for a long Encoder Wheel Press,
639
                                           // we need to take control of the panel
640
                                           // we need to take control of the panel
653
             goto LEAVE;
654
             goto LEAVE;
654
           }
655
           }
655
         }
656
         }
656
-        ubl_has_control_of_lcd_panel = false;
657
+        ubl.has_control_of_lcd_panel = false;
657
         safe_delay(20); // We don't want any switch noise.
658
         safe_delay(20); // We don't want any switch noise.
658
 
659
 
659
         ubl.state.z_offset = measured_z;
660
         ubl.state.z_offset = measured_z;
670
       lcd_quick_feedback();
671
       lcd_quick_feedback();
671
     #endif
672
     #endif
672
 
673
 
673
-    ubl_has_control_of_lcd_panel = false;
674
+    ubl.has_control_of_lcd_panel = false;
674
   }
675
   }
675
 
676
 
676
   void find_mean_mesh_height() {
677
   void find_mean_mesh_height() {
682
     n = 0;
683
     n = 0;
683
     for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
684
     for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
684
       for (y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
685
       for (y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
685
-        if (!isnan(z_values[x][y])) {
686
-          sum += z_values[x][y];
686
+        if (!isnan(ubl.z_values[x][y])) {
687
+          sum += ubl.z_values[x][y];
687
           n++;
688
           n++;
688
         }
689
         }
689
 
690
 
694
     //
695
     //
695
     for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
696
     for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
696
       for (y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
697
       for (y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
697
-        if (!isnan(z_values[x][y])) {
698
-          difference = (z_values[x][y] - mean);
698
+        if (!isnan(ubl.z_values[x][y])) {
699
+          difference = (ubl.z_values[x][y] - mean);
699
           sum_of_diff_squared += difference * difference;
700
           sum_of_diff_squared += difference * difference;
700
         }
701
         }
701
 
702
 
712
     if (c_flag)
713
     if (c_flag)
713
       for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
714
       for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
714
         for (y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
715
         for (y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
715
-          if (!isnan(z_values[x][y]))
716
-            z_values[x][y] -= mean + ubl_constant;
716
+          if (!isnan(ubl.z_values[x][y]))
717
+            ubl.z_values[x][y] -= mean + ubl_constant;
717
   }
718
   }
718
 
719
 
719
   void shift_mesh_height() {
720
   void shift_mesh_height() {
720
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
721
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
721
       for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
722
       for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
722
-        if (!isnan(z_values[x][y]))
723
-          z_values[x][y] += ubl_constant;
723
+        if (!isnan(ubl.z_values[x][y]))
724
+          ubl.z_values[x][y] += ubl_constant;
724
   }
725
   }
725
 
726
 
726
   /**
727
   /**
730
   void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest) {
731
   void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest) {
731
     mesh_index_pair location;
732
     mesh_index_pair location;
732
 
733
 
733
-    ubl_has_control_of_lcd_panel++;
734
+    ubl.has_control_of_lcd_panel++;
734
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
735
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
735
     DEPLOY_PROBE();
736
     DEPLOY_PROBE();
736
 
737
 
740
         lcd_quick_feedback();
741
         lcd_quick_feedback();
741
         STOW_PROBE();
742
         STOW_PROBE();
742
         while (ubl_lcd_clicked()) idle();
743
         while (ubl_lcd_clicked()) idle();
743
-        ubl_has_control_of_lcd_panel = false;
744
+        ubl.has_control_of_lcd_panel = false;
744
         restore_ubl_active_state_and_leave();
745
         restore_ubl_active_state_and_leave();
745
         safe_delay(50);  // Debounce the Encoder wheel
746
         safe_delay(50);  // Debounce the Encoder wheel
746
         return;
747
         return;
749
       location = find_closest_mesh_point_of_type(INVALID, lx, ly, 1, NULL, do_furthest );  // the '1' says we want the location to be relative to the probe
750
       location = find_closest_mesh_point_of_type(INVALID, lx, ly, 1, NULL, do_furthest );  // the '1' says we want the location to be relative to the probe
750
       if (location.x_index >= 0 && location.y_index >= 0) {
751
       if (location.x_index >= 0 && location.y_index >= 0) {
751
 
752
 
752
-        const float rawx = ubl.map_x_index_to_bed_location(location.x_index),
753
-                    rawy = ubl.map_y_index_to_bed_location(location.y_index);
753
+        const float rawx = ubl.mesh_index_to_xpos[location.x_index],
754
+                    rawy = ubl.mesh_index_to_ypos[location.y_index];
754
 
755
 
755
         // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
756
         // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
756
         if (rawx < (MIN_PROBE_X) || rawx > (MAX_PROBE_X) || rawy < (MIN_PROBE_Y) || rawy > (MAX_PROBE_Y)) {
757
         if (rawx < (MIN_PROBE_X) || rawx > (MAX_PROBE_X) || rawy < (MIN_PROBE_Y) || rawy > (MAX_PROBE_Y)) {
757
           SERIAL_ERROR_START;
758
           SERIAL_ERROR_START;
758
           SERIAL_ERRORLNPGM("Attempt to probe off the bed.");
759
           SERIAL_ERRORLNPGM("Attempt to probe off the bed.");
759
-          ubl_has_control_of_lcd_panel = false;
760
+          ubl.has_control_of_lcd_panel = false;
760
           goto LEAVE;
761
           goto LEAVE;
761
         }
762
         }
762
         const float measured_z = probe_pt(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy), stow_probe, g29_verbose_level);
763
         const float measured_z = probe_pt(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy), stow_probe, g29_verbose_level);
763
-        z_values[location.x_index][location.y_index] = measured_z + zprobe_zoffset;
764
+        ubl.z_values[location.x_index][location.y_index] = measured_z + zprobe_zoffset;
764
       }
765
       }
765
 
766
 
766
       if (do_ubl_mesh_map) ubl.display_map(map_type);
767
       if (do_ubl_mesh_map) ubl.display_map(map_type);
837
     for (i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
838
     for (i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
838
       for (j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
839
       for (j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
839
         c = -((normal.x * (UBL_MESH_MIN_X + i * (MESH_X_DIST)) + normal.y * (UBL_MESH_MIN_Y + j * (MESH_Y_DIST))) - d);
840
         c = -((normal.x * (UBL_MESH_MIN_X + i * (MESH_X_DIST)) + normal.y * (UBL_MESH_MIN_Y + j * (MESH_Y_DIST))) - d);
840
-        z_values[i][j] += c;
841
+        ubl.z_values[i][j] += c;
841
       }
842
       }
842
     }
843
     }
843
     return normal;
844
     return normal;
847
     KEEPALIVE_STATE(PAUSED_FOR_USER);
848
     KEEPALIVE_STATE(PAUSED_FOR_USER);
848
     while (!ubl_lcd_clicked()) {     // we need the loop to move the nozzle based on the encoder wheel here!
849
     while (!ubl_lcd_clicked()) {     // we need the loop to move the nozzle based on the encoder wheel here!
849
       idle();
850
       idle();
850
-      if (ubl_encoderDiff) {
851
-        do_blocking_move_to_z(current_position[Z_AXIS] + 0.01 * float(ubl_encoderDiff));
852
-        ubl_encoderDiff = 0;
851
+      if (ubl.encoder_diff) {
852
+        do_blocking_move_to_z(current_position[Z_AXIS] + 0.01 * float(ubl.encoder_diff));
853
+        ubl.encoder_diff = 0;
853
       }
854
       }
854
     }
855
     }
855
     KEEPALIVE_STATE(IN_HANDLER);
856
     KEEPALIVE_STATE(IN_HANDLER);
858
 
859
 
859
   float measure_business_card_thickness(const float &in_height) {
860
   float measure_business_card_thickness(const float &in_height) {
860
 
861
 
861
-    ubl_has_control_of_lcd_panel++;
862
+    ubl.has_control_of_lcd_panel++;
862
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
863
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
863
 
864
 
864
     SERIAL_PROTOCOLLNPGM("Place Shim Under Nozzle and Perform Measurement.");
865
     SERIAL_PROTOCOLLNPGM("Place Shim Under Nozzle and Perform Measurement.");
868
 
869
 
869
     const float z1 = use_encoder_wheel_to_measure_point();
870
     const float z1 = use_encoder_wheel_to_measure_point();
870
     do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE);
871
     do_blocking_move_to_z(current_position[Z_AXIS] + SIZE_OF_LITTLE_RAISE);
871
-    ubl_has_control_of_lcd_panel = false;
872
+    ubl.has_control_of_lcd_panel = false;
872
 
873
 
873
     SERIAL_PROTOCOLLNPGM("Remove Shim and Measure Bed Height.");
874
     SERIAL_PROTOCOLLNPGM("Remove Shim and Measure Bed Height.");
874
     const float z2 = use_encoder_wheel_to_measure_point();
875
     const float z2 = use_encoder_wheel_to_measure_point();
885
 
886
 
886
   void manually_probe_remaining_mesh(const float &lx, const float &ly, const float &z_clearance, const float &card_thickness, const bool do_ubl_mesh_map) {
887
   void manually_probe_remaining_mesh(const float &lx, const float &ly, const float &z_clearance, const float &card_thickness, const bool do_ubl_mesh_map) {
887
 
888
 
888
-    ubl_has_control_of_lcd_panel++;
889
+    ubl.has_control_of_lcd_panel++;
889
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
890
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
890
     do_blocking_move_to_z(z_clearance);
891
     do_blocking_move_to_z(z_clearance);
891
     do_blocking_move_to_xy(lx, ly);
892
     do_blocking_move_to_xy(lx, ly);
899
       // It doesn't matter if the probe can't reach the NAN location. This is a manual probe.
900
       // It doesn't matter if the probe can't reach the NAN location. This is a manual probe.
900
       if (location.x_index < 0 && location.y_index < 0) continue;
901
       if (location.x_index < 0 && location.y_index < 0) continue;
901
 
902
 
902
-      const float rawx = ubl.map_x_index_to_bed_location(location.x_index),
903
-                  rawy = ubl.map_y_index_to_bed_location(location.y_index);
903
+      const float rawx = ubl.mesh_index_to_xpos[location.x_index],
904
+                  rawy = ubl.mesh_index_to_ypos[location.y_index];
904
 
905
 
905
       // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
906
       // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
906
       if (rawx < (X_MIN_POS) || rawx > (X_MAX_POS) || rawy < (Y_MIN_POS) || rawy > (Y_MAX_POS)) {
907
       if (rawx < (X_MIN_POS) || rawx > (X_MAX_POS) || rawy < (Y_MIN_POS) || rawy > (Y_MAX_POS)) {
907
         SERIAL_ERROR_START;
908
         SERIAL_ERROR_START;
908
         SERIAL_ERRORLNPGM("Attempt to probe off the bed.");
909
         SERIAL_ERRORLNPGM("Attempt to probe off the bed.");
909
-        ubl_has_control_of_lcd_panel = false;
910
+        ubl.has_control_of_lcd_panel = false;
910
         goto LEAVE;
911
         goto LEAVE;
911
       }
912
       }
912
 
913
 
926
       last_y = yProbe;
927
       last_y = yProbe;
927
 
928
 
928
       KEEPALIVE_STATE(PAUSED_FOR_USER);
929
       KEEPALIVE_STATE(PAUSED_FOR_USER);
929
-      ubl_has_control_of_lcd_panel = true;
930
+      ubl.has_control_of_lcd_panel = true;
930
 
931
 
931
       while (!ubl_lcd_clicked()) {     // we need the loop to move the nozzle based on the encoder wheel here!
932
       while (!ubl_lcd_clicked()) {     // we need the loop to move the nozzle based on the encoder wheel here!
932
         idle();
933
         idle();
933
-        if (ubl_encoderDiff) {
934
-          do_blocking_move_to_z(current_position[Z_AXIS] + float(ubl_encoderDiff) / 100.0);
935
-          ubl_encoderDiff = 0;
934
+        if (ubl.encoder_diff) {
935
+          do_blocking_move_to_z(current_position[Z_AXIS] + float(ubl.encoder_diff) / 100.0);
936
+          ubl.encoder_diff = 0;
936
         }
937
         }
937
       }
938
       }
938
 
939
 
944
           do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
945
           do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
945
           lcd_quick_feedback();
946
           lcd_quick_feedback();
946
           while (ubl_lcd_clicked()) idle();
947
           while (ubl_lcd_clicked()) idle();
947
-          ubl_has_control_of_lcd_panel = false;
948
+          ubl.has_control_of_lcd_panel = false;
948
           KEEPALIVE_STATE(IN_HANDLER);
949
           KEEPALIVE_STATE(IN_HANDLER);
949
           restore_ubl_active_state_and_leave();
950
           restore_ubl_active_state_and_leave();
950
           return;
951
           return;
951
         }
952
         }
952
       }
953
       }
953
 
954
 
954
-      z_values[location.x_index][location.y_index] = current_position[Z_AXIS] - card_thickness;
955
+      ubl.z_values[location.x_index][location.y_index] = current_position[Z_AXIS] - card_thickness;
955
       if (g29_verbose_level > 2) {
956
       if (g29_verbose_level > 2) {
956
         SERIAL_PROTOCOLPGM("Mesh Point Measured at: ");
957
         SERIAL_PROTOCOLPGM("Mesh Point Measured at: ");
957
-        SERIAL_PROTOCOL_F(z_values[location.x_index][location.y_index], 6);
958
+        SERIAL_PROTOCOL_F(ubl.z_values[location.x_index][location.y_index], 6);
958
         SERIAL_EOL;
959
         SERIAL_EOL;
959
       }
960
       }
960
     } while (location.x_index >= 0 && location.y_index >= 0);
961
     } while (location.x_index >= 0 && location.y_index >= 0);
1105
    * good to have the extra information. Soon... we prune this to just a few items
1106
    * good to have the extra information. Soon... we prune this to just a few items
1106
    */
1107
    */
1107
   void g29_what_command() {
1108
   void g29_what_command() {
1108
-    const uint16_t k = E2END - ubl_eeprom_start;
1109
+    const uint16_t k = E2END - ubl.eeprom_start;
1109
 
1110
 
1110
     SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version 1.00 ");
1111
     SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version 1.00 ");
1111
     if (ubl.state.active)  
1112
     if (ubl.state.active)  
1136
 
1137
 
1137
     SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: ");
1138
     SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: ");
1138
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1139
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1139
-      SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(ubl.map_x_index_to_bed_location(i)), 1);
1140
+      SERIAL_PROTOCOL_F(LOGICAL_X_POSITION(ubl.mesh_index_to_xpos[i]), 1);
1140
       SERIAL_PROTOCOLPGM("  ");
1141
       SERIAL_PROTOCOLPGM("  ");
1141
       safe_delay(50);
1142
       safe_delay(50);
1142
     }
1143
     }
1144
 
1145
 
1145
     SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: ");
1146
     SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: ");
1146
     for (uint8_t i = 0; i < UBL_MESH_NUM_Y_POINTS; i++) {
1147
     for (uint8_t i = 0; i < UBL_MESH_NUM_Y_POINTS; i++) {
1147
-      SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(ubl.map_y_index_to_bed_location(i)), 1);
1148
+      SERIAL_PROTOCOL_F(LOGICAL_Y_POSITION(ubl.mesh_index_to_ypos[i]), 1);
1148
       SERIAL_PROTOCOLPGM("  ");
1149
       SERIAL_PROTOCOLPGM("  ");
1149
       safe_delay(50);
1150
       safe_delay(50);
1150
     }
1151
     }
1162
     SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk);
1163
     SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk);
1163
     SERIAL_EOL;
1164
     SERIAL_EOL;
1164
     safe_delay(50);
1165
     safe_delay(50);
1165
-    SERIAL_PROTOCOLLNPAIR("Free EEPROM space starts at: 0x", hex_word(ubl_eeprom_start));
1166
+    SERIAL_PROTOCOLLNPAIR("Free EEPROM space starts at: 0x", hex_word(ubl.eeprom_start));
1166
 
1167
 
1167
-    SERIAL_PROTOCOLLNPAIR("end of EEPROM              : ", hex_word(E2END));
1168
+    SERIAL_PROTOCOLLNPAIR("end of EEPROM              : 0x", hex_word(E2END));
1168
     safe_delay(50);
1169
     safe_delay(50);
1169
 
1170
 
1170
     SERIAL_PROTOCOLLNPAIR("sizeof(ubl) :  ", (int)sizeof(ubl));
1171
     SERIAL_PROTOCOLLNPAIR("sizeof(ubl) :  ", (int)sizeof(ubl));
1171
     SERIAL_EOL;
1172
     SERIAL_EOL;
1172
-    SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values));
1173
+    SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(ubl.z_values));
1173
     SERIAL_EOL;
1174
     SERIAL_EOL;
1174
     safe_delay(50);
1175
     safe_delay(50);
1175
 
1176
 
1176
     SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: 0x", hex_word(k));
1177
     SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: 0x", hex_word(k));
1177
     safe_delay(50);
1178
     safe_delay(50);
1178
 
1179
 
1179
-    SERIAL_PROTOCOLPAIR("EEPROM can hold ", k / sizeof(z_values));
1180
+    SERIAL_PROTOCOLPAIR("EEPROM can hold ", k / sizeof(ubl.z_values));
1180
     SERIAL_PROTOCOLLNPGM(" meshes.\n");
1181
     SERIAL_PROTOCOLLNPGM(" meshes.\n");
1181
     safe_delay(50);
1182
     safe_delay(50);
1182
 
1183
 
1240
     }
1241
     }
1241
     storage_slot = code_value_int();
1242
     storage_slot = code_value_int();
1242
 
1243
 
1243
-    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(tmp_z_values);
1244
+    int16_t j = (UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(tmp_z_values);
1244
 
1245
 
1245
-    if (storage_slot < 0 || storage_slot > j || ubl_eeprom_start <= 0) {
1246
+    if (storage_slot < 0 || storage_slot > j || ubl.eeprom_start <= 0) {
1246
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
1247
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
1247
       return;
1248
       return;
1248
     }
1249
     }
1251
     eeprom_read_block((void *)&tmp_z_values, (void *)j, sizeof(tmp_z_values));
1252
     eeprom_read_block((void *)&tmp_z_values, (void *)j, sizeof(tmp_z_values));
1252
 
1253
 
1253
     SERIAL_ECHOPAIR("Subtracting Mesh ", storage_slot);
1254
     SERIAL_ECHOPAIR("Subtracting Mesh ", storage_slot);
1254
-    SERIAL_PROTOCOLLNPAIR(" loaded from EEPROM address ", hex_word(j)); // Soon, we can remove the extra clutter of printing
1255
+    SERIAL_PROTOCOLLNPAIR(" loaded from EEPROM address 0x", hex_word(j)); // Soon, we can remove the extra clutter of printing
1255
                                                                         // the address in the EEPROM where the Mesh is stored.
1256
                                                                         // the address in the EEPROM where the Mesh is stored.
1256
 
1257
 
1257
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
1258
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
1258
       for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
1259
       for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++)
1259
-        z_values[x][y] = z_values[x][y] - tmp_z_values[x][y];
1260
+        ubl.z_values[x][y] -= tmp_z_values[x][y];
1260
   }
1261
   }
1261
 
1262
 
1262
   mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16], bool far_flag) {
1263
   mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType type, const float &lx, const float &ly, const bool probe_as_reference, unsigned int bits[16], bool far_flag) {
1275
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1276
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1276
       for (uint8_t j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
1277
       for (uint8_t j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
1277
 
1278
 
1278
-        if ( (type == INVALID && isnan(z_values[i][j]))  // Check to see if this location holds the right thing
1279
-          || (type == REAL && !isnan(z_values[i][j]))
1279
+        if ( (type == INVALID && isnan(ubl.z_values[i][j]))  // Check to see if this location holds the right thing
1280
+          || (type == REAL && !isnan(ubl.z_values[i][j]))
1280
           || (type == SET_IN_BITMAP && is_bit_set(bits, i, j))
1281
           || (type == SET_IN_BITMAP && is_bit_set(bits, i, j))
1281
         ) {
1282
         ) {
1282
 
1283
 
1283
           // We only get here if we found a Mesh Point of the specified type
1284
           // We only get here if we found a Mesh Point of the specified type
1284
 
1285
 
1285
-          const float rawx = ubl.map_x_index_to_bed_location(i), // Check if we can probe this mesh location
1286
-                      rawy = ubl.map_y_index_to_bed_location(j);
1286
+          const float rawx = ubl.mesh_index_to_xpos[i], // Check if we can probe this mesh location
1287
+                      rawy = ubl.mesh_index_to_ypos[j];
1287
 
1288
 
1288
           // If using the probe as the reference there are some unreachable locations.
1289
           // If using the probe as the reference there are some unreachable locations.
1289
           // Prune them from the list and ignore them till the next Phase (manual nozzle probing).
1290
           // Prune them from the list and ignore them till the next Phase (manual nozzle probing).
1303
           if (far_flag) {                                           // If doing the far_flag action, we want to be as far as possible
1304
           if (far_flag) {                                           // If doing the far_flag action, we want to be as far as possible
1304
             for (uint8_t k = 0; k < UBL_MESH_NUM_X_POINTS; k++) {   // from the starting point and from any other probed points.  We
1305
             for (uint8_t k = 0; k < UBL_MESH_NUM_X_POINTS; k++) {   // from the starting point and from any other probed points.  We
1305
               for (uint8_t l = 0; l < UBL_MESH_NUM_Y_POINTS; l++) { // want the next point spread out and filling in any blank spaces
1306
               for (uint8_t l = 0; l < UBL_MESH_NUM_Y_POINTS; l++) { // want the next point spread out and filling in any blank spaces
1306
-                if (!isnan(z_values[k][l])) {                       // in the mesh. So we add in some of the distance to every probed
1307
+                if (!isnan(ubl.z_values[k][l])) {                       // in the mesh. So we add in some of the distance to every probed
1307
                   distance += sq(i - k) * (MESH_X_DIST) * .05       // point we can find.
1308
                   distance += sq(i - k) * (MESH_X_DIST) * .05       // point we can find.
1308
                             + sq(j - l) * (MESH_Y_DIST) * .05;
1309
                             + sq(j - l) * (MESH_Y_DIST) * .05;
1309
                 }
1310
                 }
1349
       bit_clear(not_done, location.x_index, location.y_index);  // Mark this location as 'adjusted' so we will find a
1350
       bit_clear(not_done, location.x_index, location.y_index);  // Mark this location as 'adjusted' so we will find a
1350
                                                                 // different location the next time through the loop
1351
                                                                 // different location the next time through the loop
1351
 
1352
 
1352
-      const float rawx = ubl.map_x_index_to_bed_location(location.x_index),
1353
-                  rawy = ubl.map_y_index_to_bed_location(location.y_index);
1353
+      const float rawx = ubl.mesh_index_to_xpos[location.x_index],
1354
+                  rawy = ubl.mesh_index_to_ypos[location.y_index];
1354
 
1355
 
1355
       // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
1356
       // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
1356
       if (rawx < (X_MIN_POS) || rawx > (X_MAX_POS) || rawy < (Y_MIN_POS) || rawy > (Y_MAX_POS)) { // In theory, we don't need this check.
1357
       if (rawx < (X_MIN_POS) || rawx > (X_MAX_POS) || rawy < (Y_MIN_POS) || rawy > (Y_MAX_POS)) { // In theory, we don't need this check.
1357
         SERIAL_ERROR_START;
1358
         SERIAL_ERROR_START;
1358
         SERIAL_ERRORLNPGM("Attempt to edit off the bed."); // This really can't happen, but do the check for now
1359
         SERIAL_ERRORLNPGM("Attempt to edit off the bed."); // This really can't happen, but do the check for now
1359
-        ubl_has_control_of_lcd_panel = false;
1360
+        ubl.has_control_of_lcd_panel = false;
1360
         goto FINE_TUNE_EXIT;
1361
         goto FINE_TUNE_EXIT;
1361
       }
1362
       }
1362
 
1363
 
1363
       do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);    // Move the nozzle to where we are going to edit
1364
       do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);    // Move the nozzle to where we are going to edit
1364
       do_blocking_move_to_xy(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy));
1365
       do_blocking_move_to_xy(LOGICAL_X_POSITION(rawx), LOGICAL_Y_POSITION(rawy));
1365
-      float new_z = z_values[location.x_index][location.y_index];
1366
+      float new_z = ubl.z_values[location.x_index][location.y_index];
1366
       
1367
       
1367
       round_off = (int32_t)(new_z * 1000.0);    // we chop off the last digits just to be clean. We are rounding to the
1368
       round_off = (int32_t)(new_z * 1000.0);    // we chop off the last digits just to be clean. We are rounding to the
1368
       new_z = float(round_off) / 1000.0;
1369
       new_z = float(round_off) / 1000.0;
1369
 
1370
 
1370
       KEEPALIVE_STATE(PAUSED_FOR_USER);
1371
       KEEPALIVE_STATE(PAUSED_FOR_USER);
1371
-      ubl_has_control_of_lcd_panel = true;
1372
+      ubl.has_control_of_lcd_panel = true;
1372
 
1373
 
1373
       lcd_implementation_clear();
1374
       lcd_implementation_clear();
1374
       lcd_mesh_edit_setup(new_z);
1375
       lcd_mesh_edit_setup(new_z);
1380
 
1381
 
1381
       lcd_return_to_status();
1382
       lcd_return_to_status();
1382
 
1383
 
1383
-      ubl_has_control_of_lcd_panel = true; // There is a race condition for the Encoder Wheel getting clicked.
1384
+      ubl.has_control_of_lcd_panel = true; // There is a race condition for the Encoder Wheel getting clicked.
1384
                                            // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
1385
                                            // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
1385
                                            // or here.
1386
                                            // or here.
1386
 
1387
 
1401
 
1402
 
1402
       safe_delay(20);                       // We don't want any switch noise.
1403
       safe_delay(20);                       // We don't want any switch noise.
1403
 
1404
 
1404
-      z_values[location.x_index][location.y_index] = new_z;
1405
+      ubl.z_values[location.x_index][location.y_index] = new_z;
1405
 
1406
 
1406
       lcd_implementation_clear();
1407
       lcd_implementation_clear();
1407
 
1408
 
1409
 
1410
 
1410
     FINE_TUNE_EXIT:
1411
     FINE_TUNE_EXIT:
1411
 
1412
 
1412
-    ubl_has_control_of_lcd_panel = false;
1413
+    ubl.has_control_of_lcd_panel = false;
1413
     KEEPALIVE_STATE(IN_HANDLER);
1414
     KEEPALIVE_STATE(IN_HANDLER);
1414
 
1415
 
1415
     if (do_ubl_mesh_map) ubl.display_map(map_type);
1416
     if (do_ubl_mesh_map) ubl.display_map(map_type);

+ 21
- 21
Marlin/UBL_line_to_destination.cpp View File

31
 
31
 
32
   extern float destination[XYZE];
32
   extern float destination[XYZE];
33
   extern void set_current_to_destination();
33
   extern void set_current_to_destination();
34
-
34
+  extern float destination[];
35
   void debug_current_and_destination(char *title) {
35
   void debug_current_and_destination(char *title) {
36
 
36
 
37
     // if the title message starts with a '!' it is so important, we are going to
37
     // if the title message starts with a '!' it is so important, we are going to
38
     // ignore the status of the g26_debug_flag
38
     // ignore the status of the g26_debug_flag
39
-    if (*title != '!' && !g26_debug_flag) return;
39
+    if (*title != '!' && !ubl.g26_debug_flag) return;
40
 
40
 
41
     const float de = destination[E_AXIS] - current_position[E_AXIS];
41
     const float de = destination[E_AXIS] - current_position[E_AXIS];
42
 
42
 
121
               cell_dest_xi  = ubl.get_cell_index_x(RAW_X_POSITION(x_end)),
121
               cell_dest_xi  = ubl.get_cell_index_x(RAW_X_POSITION(x_end)),
122
               cell_dest_yi  = ubl.get_cell_index_y(RAW_Y_POSITION(y_end));
122
               cell_dest_yi  = ubl.get_cell_index_y(RAW_Y_POSITION(y_end));
123
 
123
 
124
-    if (g26_debug_flag) {
124
+    if (ubl.g26_debug_flag) {
125
       SERIAL_ECHOPGM(" ubl_line_to_destination(xe=");
125
       SERIAL_ECHOPGM(" ubl_line_to_destination(xe=");
126
       SERIAL_ECHO(x_end);
126
       SERIAL_ECHO(x_end);
127
       SERIAL_ECHOPGM(", ye=");
127
       SERIAL_ECHOPGM(", ye=");
150
         planner.buffer_line(x_end, y_end, z_end + ubl.state.z_offset, e_end, feed_rate, extruder);
150
         planner.buffer_line(x_end, y_end, z_end + ubl.state.z_offset, e_end, feed_rate, extruder);
151
         set_current_to_destination();
151
         set_current_to_destination();
152
 
152
 
153
-        if (g26_debug_flag)
153
+        if (ubl.g26_debug_flag)
154
           debug_current_and_destination((char*)"out of bounds in ubl_line_to_destination()");
154
           debug_current_and_destination((char*)"out of bounds in ubl_line_to_destination()");
155
 
155
 
156
         return;
156
         return;
167
        * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
167
        * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
168
        */
168
        */
169
 
169
 
170
-      const float xratio = (RAW_X_POSITION(x_end) - mesh_index_to_x_location[cell_dest_xi]) * (1.0 / (MESH_X_DIST)),
171
-                  z1 = z_values[cell_dest_xi    ][cell_dest_yi    ] + xratio *
172
-                      (z_values[cell_dest_xi + 1][cell_dest_yi    ] - z_values[cell_dest_xi][cell_dest_yi    ]),
173
-                  z2 = z_values[cell_dest_xi    ][cell_dest_yi + 1] + xratio *
174
-                      (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]);
170
+      const float xratio = (RAW_X_POSITION(x_end) - ubl.mesh_index_to_xpos[cell_dest_xi]) * (1.0 / (MESH_X_DIST)),
171
+                  z1 = ubl.z_values[cell_dest_xi    ][cell_dest_yi    ] + xratio *
172
+                      (ubl.z_values[cell_dest_xi + 1][cell_dest_yi    ] - ubl.z_values[cell_dest_xi][cell_dest_yi    ]),
173
+                  z2 = ubl.z_values[cell_dest_xi    ][cell_dest_yi + 1] + xratio *
174
+                      (ubl.z_values[cell_dest_xi + 1][cell_dest_yi + 1] - ubl.z_values[cell_dest_xi][cell_dest_yi + 1]);
175
 
175
 
176
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
176
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
177
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
177
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
178
 
178
 
179
-      const float yratio = (RAW_Y_POSITION(y_end) - mesh_index_to_y_location[cell_dest_yi]) * (1.0 / (MESH_Y_DIST));
179
+      const float yratio = (RAW_Y_POSITION(y_end) - ubl.mesh_index_to_ypos[cell_dest_yi]) * (1.0 / (MESH_Y_DIST));
180
 
180
 
181
       float z0 = z1 + (z2 - z1) * yratio;
181
       float z0 = z1 + (z2 - z1) * yratio;
182
 
182
 
212
 
212
 
213
       planner.buffer_line(x_end, y_end, z_end + z0 + ubl.state.z_offset, e_end, feed_rate, extruder);
213
       planner.buffer_line(x_end, y_end, z_end + z0 + ubl.state.z_offset, e_end, feed_rate, extruder);
214
 
214
 
215
-      if (g26_debug_flag)
215
+      if (ubl.g26_debug_flag)
216
         debug_current_and_destination((char*)"FINAL_MOVE in ubl_line_to_destination()");
216
         debug_current_and_destination((char*)"FINAL_MOVE in ubl_line_to_destination()");
217
 
217
 
218
       set_current_to_destination();
218
       set_current_to_destination();
274
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
274
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
275
       while (current_yi != cell_dest_yi + down_flag) {
275
       while (current_yi != cell_dest_yi + down_flag) {
276
         current_yi += dyi;
276
         current_yi += dyi;
277
-        const float next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_y_location[current_yi]);
277
+        const float next_mesh_line_y = LOGICAL_Y_POSITION(ubl.mesh_index_to_ypos[current_yi]);
278
 
278
 
279
         /**
279
         /**
280
          * inf_m_flag? the slope of the line is infinite, we won't do the calculations
280
          * inf_m_flag? the slope of the line is infinite, we won't do the calculations
314
          * because part of the Mesh is undefined and we don't have the
314
          * because part of the Mesh is undefined and we don't have the
315
          * information we need to complete the height correction.
315
          * information we need to complete the height correction.
316
          */
316
          */
317
-        if (isnan(z0)) z0 = 0.0;     
317
+        if (isnan(z0)) z0 = 0.0;
318
 
318
 
319
-        const float y = LOGICAL_Y_POSITION(mesh_index_to_y_location[current_yi]);
319
+        const float y = LOGICAL_Y_POSITION(ubl.mesh_index_to_ypos[current_yi]);
320
 
320
 
321
         /**
321
         /**
322
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
322
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
339
         } //else printf("FIRST MOVE PRUNED  ");
339
         } //else printf("FIRST MOVE PRUNED  ");
340
       }
340
       }
341
 
341
 
342
-      if (g26_debug_flag)
342
+      if (ubl.g26_debug_flag)
343
         debug_current_and_destination((char*)"vertical move done in ubl_line_to_destination()");
343
         debug_current_and_destination((char*)"vertical move done in ubl_line_to_destination()");
344
 
344
 
345
       //
345
       //
365
                                 // edge of this cell for the first move.
365
                                 // edge of this cell for the first move.
366
       while (current_xi != cell_dest_xi + left_flag) {
366
       while (current_xi != cell_dest_xi + left_flag) {
367
         current_xi += dxi;
367
         current_xi += dxi;
368
-        const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_x_location[current_xi]),
368
+        const float next_mesh_line_x = LOGICAL_X_POSITION(ubl.mesh_index_to_xpos[current_xi]),
369
                     y = m * next_mesh_line_x + c;   // Calculate X at the next Y mesh line
369
                     y = m * next_mesh_line_x + c;   // Calculate X at the next Y mesh line
370
 
370
 
371
         float z0 = ubl.get_z_correction_along_vertical_mesh_line_at_specific_Y(y, current_xi, current_yi);
371
         float z0 = ubl.get_z_correction_along_vertical_mesh_line_at_specific_Y(y, current_xi, current_yi);
401
          */
401
          */
402
         if (isnan(z0)) z0 = 0.0;
402
         if (isnan(z0)) z0 = 0.0;
403
 
403
 
404
-        const float x = LOGICAL_X_POSITION(mesh_index_to_x_location[current_xi]);
404
+        const float x = LOGICAL_X_POSITION(ubl.mesh_index_to_xpos[current_xi]);
405
 
405
 
406
         /**
406
         /**
407
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
407
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
424
         } //else printf("FIRST MOVE PRUNED  ");
424
         } //else printf("FIRST MOVE PRUNED  ");
425
       }
425
       }
426
 
426
 
427
-      if (g26_debug_flag)
427
+      if (ubl.g26_debug_flag)
428
         debug_current_and_destination((char*)"horizontal move done in ubl_line_to_destination()");
428
         debug_current_and_destination((char*)"horizontal move done in ubl_line_to_destination()");
429
 
429
 
430
       if (current_position[X_AXIS] != x_end || current_position[Y_AXIS] != y_end)
430
       if (current_position[X_AXIS] != x_end || current_position[Y_AXIS] != y_end)
451
 
451
 
452
     while (xi_cnt > 0 || yi_cnt > 0) {
452
     while (xi_cnt > 0 || yi_cnt > 0) {
453
 
453
 
454
-      const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_x_location[current_xi + dxi]),
455
-                  next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_y_location[current_yi + dyi]),
454
+      const float next_mesh_line_x = LOGICAL_X_POSITION(ubl.mesh_index_to_xpos[current_xi + dxi]),
455
+                  next_mesh_line_y = LOGICAL_Y_POSITION(ubl.mesh_index_to_ypos[current_yi + dyi]),
456
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
456
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
457
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line    (we don't have to worry
457
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line    (we don't have to worry
458
                                                   // about m being equal to 0.0  If this was the case, we would have
458
                                                   // about m being equal to 0.0  If this was the case, we would have
563
       }
563
       }
564
     }
564
     }
565
 
565
 
566
-    if (g26_debug_flag)
566
+    if (ubl.g26_debug_flag)
567
       debug_current_and_destination((char*)"generic move done in ubl_line_to_destination()");
567
       debug_current_and_destination((char*)"generic move done in ubl_line_to_destination()");
568
 
568
 
569
     if (current_position[0] != x_end || current_position[1] != y_end)
569
     if (current_position[0] != x_end || current_position[1] != y_end)

+ 2
- 2
Marlin/configuration_store.cpp View File

846
       }
846
       }
847
 
847
 
848
       #if ENABLED(AUTO_BED_LEVELING_UBL)
848
       #if ENABLED(AUTO_BED_LEVELING_UBL)
849
-        ubl_eeprom_start = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it
849
+        ubl.eeprom_start = (eeprom_index + 32) & 0xFFF8; // Pad the end of configuration data so it
850
                                                          // can float up or down a little bit without
850
                                                          // can float up or down a little bit without
851
                                                          // disrupting the Unified Bed Leveling data
851
                                                          // disrupting the Unified Bed Leveling data
852
         ubl.load_state();
852
         ubl.load_state();
1232
         SERIAL_ECHO_F(ubl.state.z_offset, 6);
1232
         SERIAL_ECHO_F(ubl.state.z_offset, 6);
1233
         SERIAL_EOL;
1233
         SERIAL_EOL;
1234
 
1234
 
1235
-        SERIAL_ECHOPAIR("EEPROM can hold ", (int)((UBL_LAST_EEPROM_INDEX - ubl_eeprom_start) / sizeof(z_values)));
1235
+        SERIAL_ECHOPAIR("EEPROM can hold ", (int)((UBL_LAST_EEPROM_INDEX - ubl.eeprom_start) / sizeof(ubl.z_values)));
1236
         SERIAL_ECHOLNPGM(" meshes.\n");
1236
         SERIAL_ECHOLNPGM(" meshes.\n");
1237
 
1237
 
1238
         SERIAL_ECHOLNPGM("UBL_MESH_NUM_X_POINTS  " STRINGIFY(UBL_MESH_NUM_X_POINTS));
1238
         SERIAL_ECHOLNPGM("UBL_MESH_NUM_X_POINTS  " STRINGIFY(UBL_MESH_NUM_X_POINTS));

+ 1
- 1
Marlin/example_configurations/Cartesio/Configuration.h View File

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
867
 
867
 
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
869
 
869
 

+ 1
- 1
Marlin/example_configurations/Felix/Configuration.h View File

846
   #define UBL_PROBE_PT_2_Y 20
846
   #define UBL_PROBE_PT_2_Y 20
847
   #define UBL_PROBE_PT_3_X 180
847
   #define UBL_PROBE_PT_3_X 180
848
   #define UBL_PROBE_PT_3_Y 20
848
   #define UBL_PROBE_PT_3_Y 20
849
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
849
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
850
 
850
 
851
 #elif ENABLED(MESH_BED_LEVELING)
851
 #elif ENABLED(MESH_BED_LEVELING)
852
 
852
 

+ 1
- 1
Marlin/example_configurations/Felix/DUAL/Configuration.h View File

846
   #define UBL_PROBE_PT_2_Y 20
846
   #define UBL_PROBE_PT_2_Y 20
847
   #define UBL_PROBE_PT_3_X 180
847
   #define UBL_PROBE_PT_3_X 180
848
   #define UBL_PROBE_PT_3_Y 20
848
   #define UBL_PROBE_PT_3_Y 20
849
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
849
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
850
 
850
 
851
 #elif ENABLED(MESH_BED_LEVELING)
851
 #elif ENABLED(MESH_BED_LEVELING)
852
 
852
 

+ 1
- 1
Marlin/example_configurations/Hephestos/Configuration.h View File

855
   #define UBL_PROBE_PT_2_Y 20
855
   #define UBL_PROBE_PT_2_Y 20
856
   #define UBL_PROBE_PT_3_X 180
856
   #define UBL_PROBE_PT_3_X 180
857
   #define UBL_PROBE_PT_3_Y 20
857
   #define UBL_PROBE_PT_3_Y 20
858
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
858
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
859
 
859
 
860
 #elif ENABLED(MESH_BED_LEVELING)
860
 #elif ENABLED(MESH_BED_LEVELING)
861
 
861
 

+ 1
- 1
Marlin/example_configurations/Hephestos_2/Configuration.h View File

857
   #define UBL_PROBE_PT_2_Y 20
857
   #define UBL_PROBE_PT_2_Y 20
858
   #define UBL_PROBE_PT_3_X 180
858
   #define UBL_PROBE_PT_3_X 180
859
   #define UBL_PROBE_PT_3_Y 20
859
   #define UBL_PROBE_PT_3_Y 20
860
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
860
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
861
 
861
 
862
 #elif ENABLED(MESH_BED_LEVELING)
862
 #elif ENABLED(MESH_BED_LEVELING)
863
 
863
 

+ 1
- 1
Marlin/example_configurations/K8200/Configuration.h View File

892
   #define UBL_PROBE_PT_2_Y 20
892
   #define UBL_PROBE_PT_2_Y 20
893
   #define UBL_PROBE_PT_3_X 180
893
   #define UBL_PROBE_PT_3_X 180
894
   #define UBL_PROBE_PT_3_Y 20
894
   #define UBL_PROBE_PT_3_Y 20
895
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
895
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
896
 
896
 
897
 #elif ENABLED(MESH_BED_LEVELING)
897
 #elif ENABLED(MESH_BED_LEVELING)
898
 
898
 

+ 1
- 1
Marlin/example_configurations/K8400/Configuration.h View File

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
867
 
867
 
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
869
 
869
 

+ 1
- 1
Marlin/example_configurations/K8400/Dual-head/Configuration.h View File

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
867
 
867
 
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
869
 
869
 

+ 1
- 1
Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h View File

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
867
 
867
 
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
869
 
869
 

+ 1
- 1
Marlin/example_configurations/RigidBot/Configuration.h View File

862
   #define UBL_PROBE_PT_2_Y 20
862
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_3_X 180
863
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_Y 20
864
   #define UBL_PROBE_PT_3_Y 20
865
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
865
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
866
 
866
 
867
 #elif ENABLED(MESH_BED_LEVELING)
867
 #elif ENABLED(MESH_BED_LEVELING)
868
 
868
 

+ 1
- 1
Marlin/example_configurations/SCARA/Configuration.h View File

878
   #define UBL_PROBE_PT_2_Y 20
878
   #define UBL_PROBE_PT_2_Y 20
879
   #define UBL_PROBE_PT_3_X 180
879
   #define UBL_PROBE_PT_3_X 180
880
   #define UBL_PROBE_PT_3_Y 20
880
   #define UBL_PROBE_PT_3_Y 20
881
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
881
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
882
 
882
 
883
 #elif ENABLED(MESH_BED_LEVELING)
883
 #elif ENABLED(MESH_BED_LEVELING)
884
 
884
 

+ 1
- 1
Marlin/example_configurations/TAZ4/Configuration.h View File

884
   #define UBL_PROBE_PT_2_Y 20
884
   #define UBL_PROBE_PT_2_Y 20
885
   #define UBL_PROBE_PT_3_X 180
885
   #define UBL_PROBE_PT_3_X 180
886
   #define UBL_PROBE_PT_3_Y 20
886
   #define UBL_PROBE_PT_3_Y 20
887
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
887
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
888
 
888
 
889
 #elif ENABLED(MESH_BED_LEVELING)
889
 #elif ENABLED(MESH_BED_LEVELING)
890
 
890
 

+ 1
- 1
Marlin/example_configurations/WITBOX/Configuration.h View File

855
   #define UBL_PROBE_PT_2_Y 20
855
   #define UBL_PROBE_PT_2_Y 20
856
   #define UBL_PROBE_PT_3_X 180
856
   #define UBL_PROBE_PT_3_X 180
857
   #define UBL_PROBE_PT_3_Y 20
857
   #define UBL_PROBE_PT_3_Y 20
858
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
858
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
859
 
859
 
860
 #elif ENABLED(MESH_BED_LEVELING)
860
 #elif ENABLED(MESH_BED_LEVELING)
861
 
861
 

+ 1
- 1
Marlin/example_configurations/adafruit/ST7565/Configuration.h View File

863
   #define UBL_PROBE_PT_2_Y 20
863
   #define UBL_PROBE_PT_2_Y 20
864
   #define UBL_PROBE_PT_3_X 180
864
   #define UBL_PROBE_PT_3_X 180
865
   #define UBL_PROBE_PT_3_Y 20
865
   #define UBL_PROBE_PT_3_Y 20
866
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
866
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
867
 
867
 
868
 #elif ENABLED(MESH_BED_LEVELING)
868
 #elif ENABLED(MESH_BED_LEVELING)
869
 
869
 

+ 1
- 1
Marlin/example_configurations/delta/flsun_kossel_mini/Configuration.h View File

968
   #define UBL_PROBE_PT_2_Y 20
968
   #define UBL_PROBE_PT_2_Y 20
969
   #define UBL_PROBE_PT_3_X 180
969
   #define UBL_PROBE_PT_3_X 180
970
   #define UBL_PROBE_PT_3_Y 20
970
   #define UBL_PROBE_PT_3_Y 20
971
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
971
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
972
 
972
 
973
 #elif ENABLED(MESH_BED_LEVELING)
973
 #elif ENABLED(MESH_BED_LEVELING)
974
 
974
 

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

954
   #define UBL_PROBE_PT_2_Y 20
954
   #define UBL_PROBE_PT_2_Y 20
955
   #define UBL_PROBE_PT_3_X 180
955
   #define UBL_PROBE_PT_3_X 180
956
   #define UBL_PROBE_PT_3_Y 20
956
   #define UBL_PROBE_PT_3_Y 20
957
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
957
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
958
 
958
 
959
 #elif ENABLED(MESH_BED_LEVELING)
959
 #elif ENABLED(MESH_BED_LEVELING)
960
 
960
 

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

958
   #define UBL_PROBE_PT_2_Y 20
958
   #define UBL_PROBE_PT_2_Y 20
959
   #define UBL_PROBE_PT_3_X 180
959
   #define UBL_PROBE_PT_3_X 180
960
   #define UBL_PROBE_PT_3_Y 20
960
   #define UBL_PROBE_PT_3_Y 20
961
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
961
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
962
 
962
 
963
 #elif ENABLED(MESH_BED_LEVELING)
963
 #elif ENABLED(MESH_BED_LEVELING)
964
 
964
 

+ 1
- 1
Marlin/example_configurations/delta/kossel_pro/Configuration.h View File

957
   #define UBL_PROBE_PT_2_Y 20
957
   #define UBL_PROBE_PT_2_Y 20
958
   #define UBL_PROBE_PT_3_X 180
958
   #define UBL_PROBE_PT_3_X 180
959
   #define UBL_PROBE_PT_3_Y 20
959
   #define UBL_PROBE_PT_3_Y 20
960
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
960
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
961
 
961
 
962
 #elif ENABLED(MESH_BED_LEVELING)
962
 #elif ENABLED(MESH_BED_LEVELING)
963
 
963
 

+ 1
- 1
Marlin/example_configurations/delta/kossel_xl/Configuration.h View File

967
   #define UBL_PROBE_PT_2_Y 20
967
   #define UBL_PROBE_PT_2_Y 20
968
   #define UBL_PROBE_PT_3_X 180
968
   #define UBL_PROBE_PT_3_X 180
969
   #define UBL_PROBE_PT_3_Y 20
969
   #define UBL_PROBE_PT_3_Y 20
970
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
970
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
971
 
971
 
972
 #elif ENABLED(MESH_BED_LEVELING)
972
 #elif ENABLED(MESH_BED_LEVELING)
973
 
973
 

+ 1
- 1
Marlin/example_configurations/makibox/Configuration.h View File

866
   #define UBL_PROBE_PT_2_Y 20
866
   #define UBL_PROBE_PT_2_Y 20
867
   #define UBL_PROBE_PT_3_X 180
867
   #define UBL_PROBE_PT_3_X 180
868
   #define UBL_PROBE_PT_3_Y 20
868
   #define UBL_PROBE_PT_3_Y 20
869
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
869
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
870
 
870
 
871
 #elif ENABLED(MESH_BED_LEVELING)
871
 #elif ENABLED(MESH_BED_LEVELING)
872
 
872
 

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

859
   #define UBL_PROBE_PT_2_Y 20
859
   #define UBL_PROBE_PT_2_Y 20
860
   #define UBL_PROBE_PT_3_X 180
860
   #define UBL_PROBE_PT_3_X 180
861
   #define UBL_PROBE_PT_3_Y 20
861
   #define UBL_PROBE_PT_3_Y 20
862
-  #define UBL_MESH_EDIT_ENABLED     // Enable G26 mesh editing
862
+  //#define UBL_G26_MESH_EDITING    // Enable G26 mesh editing
863
 
863
 
864
 #elif ENABLED(MESH_BED_LEVELING)
864
 #elif ENABLED(MESH_BED_LEVELING)
865
 
865
 

+ 7
- 8
Marlin/ultralcd.cpp View File

124
   int32_t lastEncoderMovementMillis;
124
   int32_t lastEncoderMovementMillis;
125
 
125
 
126
   #if ENABLED(AUTO_BED_LEVELING_UBL)
126
   #if ENABLED(AUTO_BED_LEVELING_UBL)
127
-    extern bool ubl_has_control_of_lcd_panel;
128
-    extern int8_t ubl_encoderDiff;
127
+    #include "UBL.h"
129
   #endif
128
   #endif
130
 
129
 
131
   #if HAS_POWER_SWITCH
130
   #if HAS_POWER_SWITCH
860
 
859
 
861
     static void _lcd_mesh_fine_tune(const char* msg) {
860
     static void _lcd_mesh_fine_tune(const char* msg) {
862
       defer_return_to_status = true;
861
       defer_return_to_status = true;
863
-      if (ubl_encoderDiff) {
864
-        ubl_encoderPosition = (ubl_encoderDiff > 0) ? 1 : -1;
865
-        ubl_encoderDiff = 0;
862
+      if (ubl.encoder_diff) {
863
+        ubl_encoderPosition = (ubl.encoder_diff > 0) ? 1 : -1;
864
+        ubl.encoder_diff = 0;
866
 
865
 
867
         mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005 / 2.0;
866
         mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005 / 2.0;
868
         mesh_edit_value = mesh_edit_accumulator;
867
         mesh_edit_value = mesh_edit_accumulator;
3206
     lcd_buttons_update();
3205
     lcd_buttons_update();
3207
 
3206
 
3208
     #if ENABLED(AUTO_BED_LEVELING_UBL)
3207
     #if ENABLED(AUTO_BED_LEVELING_UBL)
3209
-      const bool UBL_CONDITION = !ubl_has_control_of_lcd_panel;
3208
+      const bool UBL_CONDITION = !ubl.has_control_of_lcd_panel;
3210
     #else
3209
     #else
3211
       constexpr bool UBL_CONDITION = true;
3210
       constexpr bool UBL_CONDITION = true;
3212
     #endif
3211
     #endif
3622
         case encrot3: ENCODER_SPIN(encrot2, encrot0); break;
3621
         case encrot3: ENCODER_SPIN(encrot2, encrot0); break;
3623
       }
3622
       }
3624
       #if ENABLED(AUTO_BED_LEVELING_UBL)
3623
       #if ENABLED(AUTO_BED_LEVELING_UBL)
3625
-        if (ubl_has_control_of_lcd_panel) {
3626
-          ubl_encoderDiff = encoderDiff;    // Make the encoder's rotation available to G29's Mesh Editor
3624
+        if (ubl.has_control_of_lcd_panel) {
3625
+          ubl.encoder_diff = encoderDiff;    // Make the encoder's rotation available to G29's Mesh Editor
3627
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
3626
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
3628
                                             // wheel has not turned.
3627
                                             // wheel has not turned.
3629
         }
3628
         }

Loading…
Cancel
Save