Browse Source

Merge pull request #6174 from thinkyhead/rc_ubl_continued

UBL additional cleanup
Scott Lahteine 7 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,7 +120,7 @@ script:
120 120
   # Test a simple build of AUTO_BED_LEVELING_UBL
121 121
   #
122 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 124
   - build_marlin
125 125
   #
126 126
   # Test a Sled Z Probe

+ 1
- 1
Marlin/Configuration.h View File

@@ -862,7 +862,7 @@
862 862
   #define UBL_PROBE_PT_2_Y 20
863 863
   #define UBL_PROBE_PT_3_X 180
864 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 867
 #elif ENABLED(MESH_BED_LEVELING)
868 868
 

+ 58
- 73
Marlin/G26_Mesh_Validation_Tool.cpp View File

@@ -26,7 +26,7 @@
26 26
 
27 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 31
   #include "Marlin.h"
32 32
   #include "Configuration.h"
@@ -38,7 +38,7 @@
38 38
 
39 39
   #define EXTRUSION_MULTIPLIER 1.0    // This is too much clutter for the main Configuration.h file  But
40 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 42
   #define FILAMENT 1.75               // the options every time they do a Mesh Validation Print.
43 43
   #define LAYER_HEIGHT 0.2
44 44
   #define PRIME_LENGTH 10.0           // So, we put these number in an easy to find and change place.
@@ -113,9 +113,7 @@
113 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 116
   extern float feedrate;
118
-  //extern bool relative_mode;
119 117
   extern Planner planner;
120 118
   //#if ENABLED(ULTRA_LCD)
121 119
     extern char lcd_status_message[];
@@ -171,8 +169,7 @@
171 169
 
172 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 175
    * G26: Mesh Validation Pattern generation.
@@ -181,15 +178,13 @@
181 178
    * nozzle in a problem area and doing a G29 P4 R command.
182 179
    */
183 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 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 189
     if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
195 190
       do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
@@ -197,17 +192,12 @@
197 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 197
     current_position[E_AXIS] = 0.0;
207 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 203
      *  Bed is preheated
@@ -219,20 +209,17 @@
219 209
      *  It's  "Show Time" !!!
220 210
      */
221 211
 
222
-    // Clear all of the flags we need
223 212
     ZERO(circle_flags);
224 213
     ZERO(horizontal_mesh_line_flags);
225 214
     ZERO(vertical_mesh_line_flags);
226 215
 
227
-    //
228 216
     // Move nozzle to the specified height for the first layer
229
-    //
230 217
     set_destination_to_current();
231 218
     destination[Z_AXIS] = layer_height;
232 219
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
233 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 223
     //debug_current_and_destination((char*)"Starting G26 Mesh Validation Pattern.");
237 224
 
238 225
     /**
@@ -264,14 +251,13 @@
264 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 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 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 263
         #ifdef DELTA
@@ -292,7 +278,7 @@
292 278
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
293 279
         yi = location.y_index;
294 280
 
295
-        if (g26_debug_flag) {
281
+        if (ubl.g26_debug_flag) {
296 282
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
297 283
           SERIAL_ECHOPAIR(", yi=", yi);
298 284
           SERIAL_CHAR(')');
@@ -329,24 +315,23 @@
329 315
         for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) {
330 316
           int tmp_div_30 = tmp / 30.0;
331 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 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 324
           #ifdef DELTA
340 325
             if (HYPOT2(x, y) > sq(DELTA_PRINTABLE_RADIUS))   // Check to make sure this part of
341 326
               continue;                                      // the 'circle' is on the bed.  If
342 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 329
             y  = constrain(y, Y_MIN_POS + 1, Y_MAX_POS - 1);
345 330
             xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1);
346 331
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
347 332
           #endif
348 333
 
349
-          //if (g26_debug_flag) {
334
+          //if (ubl.g26_debug_flag) {
350 335
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
351 336
           //  strcpy(seg_msg, "   segment: ");
352 337
           //  strcpy(seg_num, "    \n");
@@ -357,15 +342,9 @@
357 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 349
         //debug_current_and_destination((char*)"Looking for lines to connect.");
371 350
         look_for_lines_to_connect();
@@ -373,8 +352,8 @@
373 352
       }
374 353
 
375 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 358
     LEAVE:
380 359
     lcd_reset_alert_level();
@@ -394,7 +373,7 @@
394 373
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
395 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 378
     if (!keep_heaters_on) {
400 379
       #if HAS_TEMP_BED
@@ -420,8 +399,8 @@
420 399
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
421 400
       for (uint8_t j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
422 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 405
           dx = X - mx;        // Get the distance to this intersection
427 406
           dy = Y - my;
@@ -466,11 +445,11 @@
466 445
               // We found two circles that need a horizontal line to connect them
467 446
               // Print it!
468 447
               //
469
-              sx = ubl.map_x_index_to_bed_location(i);
448
+              sx = ubl.mesh_index_to_xpos[i];
470 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 453
               ex = ex - SIZE_OF_INTERSECTION_CIRCLES + SIZE_OF_CROSS_HAIRS; // get the left edge of the circle
475 454
               ey = sy;
476 455
 
@@ -479,7 +458,7 @@
479 458
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
480 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 462
                 SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
484 463
                 SERIAL_ECHOPAIR(", sy=", sy);
485 464
                 SERIAL_ECHOPAIR(") -> (ex=", ex);
@@ -503,12 +482,12 @@
503 482
                 // We found two circles that need a vertical line to connect them
504 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 487
                 sy = sy + SIZE_OF_INTERSECTION_CIRCLES - SIZE_OF_CROSS_HAIRS; // get the top edge of the circle
509 488
 
510 489
                 ex = sx;
511
-                ey = ubl.map_y_index_to_bed_location(j + 1);
490
+                ey = ubl.mesh_index_to_ypos[j + 1];
512 491
                 ey = ey - SIZE_OF_INTERSECTION_CIRCLES + SIZE_OF_CROSS_HAIRS; // get the bottom edge of the circle
513 492
 
514 493
                 sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);             // This keeps us from bumping the endstops
@@ -516,7 +495,7 @@
516 495
                 ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
517 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 499
                   SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
521 500
                   SERIAL_ECHOPAIR(", sy=", sy);
522 501
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
@@ -541,10 +520,10 @@
541 520
 
542 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 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 528
       last_z = z;
550 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,24 +538,24 @@
559 538
       stepper.synchronize();
560 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 544
     // Check if X or Y is involved in the movement.
566 545
     // Yes: a 'normal' movement. No: a retract() or un_retract()
567 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 550
     destination[X_AXIS] = x;
572 551
     destination[Y_AXIS] = y;
573 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 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 560
     stepper.synchronize();
582 561
     set_destination_to_current();
@@ -586,9 +565,9 @@
586 565
   void retract_filament() {
587 566
     if (!g26_retracted) { // Only retract if we are not already retracted!
588 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 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,7 +575,7 @@
596 575
     if (g26_retracted) { // Only un-retract if we are retracted.
597 576
       move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 1.2 * retraction_multiplier);
598 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,7 +612,7 @@
633 612
     // On very small lines we don't do the optimization because it just isn't worth it.
634 613
     //
635 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 616
       print_line_from_here_to_there(ex, ey, ez, sx, sy, sz);
638 617
       return;
639 618
     }
@@ -642,7 +621,7 @@
642 621
 
643 622
     if (dist_start > 2.0) {
644 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 626
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion
648 627
 
@@ -650,7 +629,7 @@
650 629
 
651 630
     un_retract_filament();
652 631
 
653
-    //if (g26_debug_flag) {
632
+    //if (ubl.g26_debug_flag) {
654 633
     //  SERIAL_ECHOLNPGM("  doing printing move.");
655 634
     //  debug_current_and_destination((char*)"doing final move_to() inside print_line_from_here_to_there()");
656 635
     //}
@@ -810,7 +789,7 @@
810 789
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
811 790
           lcd_quick_feedback();
812 791
       #endif
813
-          ubl_has_control_of_lcd_panel = true;
792
+          ubl.has_control_of_lcd_panel++;
814 793
           thermalManager.setTargetBed(bed_temp);
815 794
           while (abs(thermalManager.degBed() - bed_temp) > 3) {
816 795
             if (ubl_lcd_clicked()) return exit_from_g26();
@@ -845,6 +824,9 @@
845 824
     float Total_Prime = 0.0;
846 825
 
847 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 830
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
849 831
       chirp_at_user();
850 832
 
@@ -881,6 +863,9 @@
881 863
         lcd_setstatuspgm(PSTR("Done Priming"), 99);
882 864
         lcd_quick_feedback();
883 865
       #endif
866
+
867
+      ubl.has_control_of_lcd_panel = false;
868
+
884 869
     }
885 870
     else {
886 871
       #if ENABLED(ULTRA_LCD)
@@ -901,4 +886,4 @@
901 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,10 +76,10 @@ void gcode_M100() {
76 76
       // We want to start and end the dump on a nice 16 byte boundry even though
77 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 80
       ptr = (char*)((uint32_t)ptr & 0xfff0);
81 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 83
       sp = (char*)((uint32_t)sp | 0x000f);
84 84
       n = sp - ptr;
85 85
       //

+ 4
- 0
Marlin/Marlin.h View File

@@ -430,4 +430,8 @@ void do_blocking_move_to_x(const float &x, const float &fr_mm_s=0.0);
430 430
 void do_blocking_move_to_z(const float &z, const float &fr_mm_s=0.0);
431 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 437
 #endif //MARLIN_H

+ 65
- 43
Marlin/Marlin_main.cpp View File

@@ -299,11 +299,11 @@
299 299
 #if ENABLED(AUTO_BED_LEVELING_UBL)
300 300
   #include "UBL.h"
301 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 307
 #endif
308 308
 
309 309
 bool Running = true;
@@ -3221,7 +3221,7 @@ inline void gcode_G4() {
3221 3221
    */
3222 3222
   inline void gcode_G12() {
3223 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 3226
     const uint8_t pattern = code_seen('P') ? code_value_ushort() : 0,
3227 3227
                   strokes = code_seen('S') ? code_value_ushort() : NOZZLE_CLEAN_STROKES,
@@ -5344,17 +5344,15 @@ inline void gcode_M42() {
5344 5344
 
5345 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 5349
   inline void gcode_M49() {
5350
+    ubl.g26_debug_flag = !ubl.g26_debug_flag;
5350 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 5358
  * M75: Start print timer
@@ -7210,13 +7208,59 @@ void quickstop_stepper() {
7210 7208
   /**
7211 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 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 7264
     if (code_seen('S')) {
7221 7265
       to_enable = code_value_bool();
7222 7266
       set_bed_leveling_enabled(to_enable);
@@ -7243,28 +7287,6 @@ void quickstop_stepper() {
7243 7287
 
7244 7288
     SERIAL_ECHO_START;
7245 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 7291
 #endif
7270 7292
 
@@ -8579,7 +8601,7 @@ void process_next_command() {
8579 8601
           break;
8580 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 8605
         case 26: // G26: Mesh Validation Pattern generation
8584 8606
           gcode_G26();
8585 8607
           break;
@@ -8595,7 +8617,7 @@ void process_next_command() {
8595 8617
         gcode_G28();
8596 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 8621
         case 29: // G29 Detailed Z probe, probes the bed at 3 or more points,
8600 8622
                  // or provides access to the UBL System if enabled.
8601 8623
           gcode_G29();
@@ -8711,11 +8733,11 @@ void process_next_command() {
8711 8733
           break;
8712 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 8738
           gcode_M49();
8717 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 8742
       case 75: // M75: Start print timer
8721 8743
         gcode_M75(); break;

+ 238
- 231
Marlin/UBL.h View File

@@ -39,7 +39,6 @@
39 39
 
40 40
     enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
41 41
 
42
-    bool axis_unhomed_error(bool, bool, bool);
43 42
     void dump(char * const str, const float &f);
44 43
     bool ubl_lcd_clicked();
45 44
     void probe_entire_mesh(const float&, const float&, const bool, const bool, const bool);
@@ -78,271 +77,279 @@
78 77
 
79 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 118
     class unified_bed_leveling {
119
+      private:
120
+
121
+        static float last_specified_z,
122
+                     fade_scaling_factor_for_current_height;
123
+
96 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 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 282
           #if ENABLED(DEBUG_LEVELING_FEATURE)
298 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 286
               SERIAL_ECHO(y0);
303
-              SERIAL_ECHOLNPGM(" )");
287
+              SERIAL_ECHOPGM(") = ");
288
+              SERIAL_ECHO_F(z0, 6);
304 289
             }
305 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 348
     }; // class unified_bed_leveling
340 349
 
341 350
     extern unified_bed_leveling ubl;
342
-    extern int ubl_eeprom_start;
343 351
 
344 352
     #define UBL_LAST_EEPROM_INDEX (E2END - sizeof(unified_bed_leveling::state))
345 353
 
346 354
   #endif // AUTO_BED_LEVELING_UBL
347
-
348 355
 #endif // UNIFIED_BED_LEVELING_H

+ 35
- 47
Marlin/UBL_Bed_Leveling.cpp View File

@@ -57,26 +57,26 @@
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 80
     reset();
81 81
   }
82 82
 
@@ -95,7 +95,7 @@
95 95
     #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
96 96
       /**
97 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 99
        * an incomplete Bed_Leveling.state structure. For speed
100 100
        * we now multiply by the inverse of the Fade Height instead of
101 101
        * dividing by it. Soon... all of the old structures will be
@@ -110,7 +110,7 @@
110 110
   }
111 111
 
112 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 115
     if (m == -1) {
116 116
       SERIAL_PROTOCOLLNPGM("?No mesh saved in EEPROM. Zeroing mesh in memory.\n");
@@ -118,7 +118,7 @@
118 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 122
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
123 123
       return;
124 124
     }
@@ -131,9 +131,9 @@
131 131
   }
132 132
 
133 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 137
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available to load mesh.\n");
138 138
       SERIAL_PROTOCOL(m);
139 139
       SERIAL_PROTOCOLLNPGM(" mesh slots available.\n");
@@ -164,9 +164,6 @@
164 164
   }
165 165
 
166 166
   void unified_bed_leveling::invalidate() {
167
-    print_hex_word((uint16_t)this);
168
-    SERIAL_EOL;
169
-
170 167
     state.active = false;
171 168
     state.z_offset = 0;
172 169
     for (int x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
@@ -201,9 +198,8 @@
201 198
       for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
202 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 204
         const float f = z_values[i][j];
209 205
         if (isnan(f)) {
@@ -211,12 +207,11 @@
211 207
         }
212 208
         else {
213 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 211
           SERIAL_PROTOCOL_F(f, 3);
216 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 216
         #if TX_BUFFER_SIZE > 0
222 217
           MYSERIAL.flushTX();
@@ -251,47 +246,40 @@
251 246
   bool unified_bed_leveling::sanity_check() {
252 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 250
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_NUM_X_POINTS set wrong\n");
256 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 254
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_NUM_Y_POINTS set wrong\n");
261 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 258
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_X set wrong\n");
266 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 262
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MIN_Y set wrong\n");
271 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 266
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_X set wrong\n");
276 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 270
       SERIAL_PROTOCOLLNPGM("?UBL_MESH_MAX_Y set wrong\n");
281 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 274
       SERIAL_PROTOCOLLNPGM("?MESH_X_DIST set wrong\n");
286 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 278
       SERIAL_PROTOCOLLNPGM("?MESH_Y_DIST set wrong\n");
291 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 283
     if (j < 1) {
296 284
       SERIAL_PROTOCOLLNPGM("?No EEPROM storage available for a mesh of this size.\n");
297 285
       error_flag++;

+ 105
- 104
Marlin/UBL_G29.cpp View File

@@ -22,7 +22,7 @@
22 22
 
23 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 26
   //#include "vector_3.h"
27 27
   //#include "qr_solve.h"
28 28
 
@@ -39,7 +39,10 @@
39 39
   void lcd_return_to_status();
40 40
   bool lcd_clicked();
41 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 46
   extern float meshedit_done;
44 47
   extern long babysteps_done;
45 48
   extern float code_value_float();
@@ -141,7 +144,7 @@
141 144
    *   P0    Phase 0    Zero Mesh Data and turn off the Mesh Compensation System. This reverts the
142 145
    *                    3D Printer to the same state it was in before the Unified Bed Leveling Compensation
143 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 149
    *   P1    Phase 1    Invalidate entire Mesh and continue with automatic generation of the Mesh data using
147 150
    *                    the Z-Probe. Depending upon the values of DELTA_PROBEABLE_RADIUS and
@@ -294,14 +297,10 @@
294 297
    *   this is going to be helpful to the users!)
295 298
    *
296 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 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 304
   // The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
306 305
   static int g29_verbose_level, phase_value = -1, repetition_cnt,
307 306
              storage_slot = 0, map_type; //unlevel_value = -1;
@@ -313,8 +312,8 @@
313 312
   #endif
314 313
 
315 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 317
       SERIAL_PROTOCOLLNPGM("?You need to enable your EEPROM and initialize it");
319 318
       SERIAL_PROTOCOLLNPGM("with M502, M500, M501 in that order.\n");
320 319
       return;
@@ -335,7 +334,7 @@
335 334
           SERIAL_PROTOCOLLNPGM("Entire Mesh invalidated.\n");
336 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 339
       SERIAL_PROTOCOLLNPGM("Locations invalidated.\n");
341 340
     }
@@ -354,21 +353,21 @@
354 353
             for (uint8_t y = 0; y < UBL_MESH_NUM_Y_POINTS; y++) { // a poorly calibrated Delta.
355 354
               const float p1 = 0.5 * (UBL_MESH_NUM_X_POINTS) - x,
356 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 359
           break;
361 360
         case 1:
362 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 365
           break;
367 366
         case 2:
368 367
           // Allow the user to specify the height because 10mm is a little extreme in some cases.
369 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 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 371
           break;
373 372
       }
374 373
     }
@@ -390,17 +389,18 @@
390 389
         return;
391 390
       }
392 391
       switch (phase_value) {
393
-        //
394
-        // Zero Mesh Data
395
-        //
396 392
         case 0:
393
+          //
394
+          // Zero Mesh Data
395
+          //
397 396
           ubl.reset();
398 397
           SERIAL_PROTOCOLLNPGM("Mesh zeroed.\n");
399 398
           break;
400
-        //
401
-        // Invalidate Entire Mesh and Automatically Probe Mesh in areas that can be reached by the probe
402
-        //
399
+
403 400
         case 1:
401
+          //
402
+          // Invalidate Entire Mesh and Automatically Probe Mesh in areas that can be reached by the probe
403
+          //
404 404
           if (!code_seen('C') ) {
405 405
             ubl.invalidate();
406 406
             SERIAL_PROTOCOLLNPGM("Mesh invalidated. Probing mesh.\n");
@@ -414,10 +414,11 @@
414 414
           probe_entire_mesh(x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER,
415 415
                             code_seen('O') || code_seen('M'), code_seen('E'), code_seen('U'));
416 416
           break;
417
-        //
418
-        // Manually Probe Mesh in areas that can't be reached by the probe
419
-        //
417
+
420 418
         case 2: {
419
+          //
420
+          // Manually Probe Mesh in areas that can't be reached by the probe
421
+          //
421 422
           SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.\n");
422 423
           do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
423 424
           if (!x_flag && !y_flag) {      // use a good default location for the path
@@ -450,24 +451,24 @@
450 451
 
451 452
         } break;
452 453
 
453
-        //
454
-        // Populate invalid Mesh areas with a constant
455
-        //
456 454
         case 3: {
455
+          //
456
+          // Populate invalid Mesh areas with a constant
457
+          //
457 458
           const float height = code_seen('C') ? ubl_constant : 0.0;
458 459
           // If no repetition is specified, do the whole Mesh
459 460
           if (!repeat_flag) repetition_cnt = 9999;
460 461
           while (repetition_cnt--) {
461 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 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 466
         } break;
466 467
 
467
-        //
468
-        // Fine Tune (Or Edit) the Mesh
469
-        //
470 468
         case 4:
469
+          //
470
+          // Fine Tune (i.e., Edit) the Mesh
471
+          //
471 472
           fine_tune_mesh(x_pos, y_pos, code_seen('O') || code_seen('M'));
472 473
           break;
473 474
         case 5:
@@ -482,16 +483,16 @@
482 483
           SERIAL_ECHO_START;
483 484
           SERIAL_ECHOLNPGM("Checking G29 has control of LCD Panel:");
484 485
           KEEPALIVE_STATE(PAUSED_FOR_USER);
485
-          ubl_has_control_of_lcd_panel++;
486
+          ubl.has_control_of_lcd_panel++;
486 487
           while (!ubl_lcd_clicked()) {
487 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 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 496
           KEEPALIVE_STATE(IN_HANDLER);
496 497
           break;
497 498
 
@@ -503,9 +504,9 @@
503 504
           wait_for_user = true;
504 505
           while (wait_for_user) {
505 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 512
           SERIAL_ECHOLNPGM("G29 giving back control of LCD Panel.");
@@ -557,9 +558,9 @@
557 558
     if (code_seen('L')) {     // Load Current Mesh Data
558 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 564
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
564 565
         return;
565 566
       }
@@ -581,19 +582,19 @@
581 582
         SERIAL_ECHOLNPGM("G29 I 999");              // host in a form it can be reconstructed on a different machine
582 583
         for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
583 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 586
               SERIAL_ECHOPAIR("M421 I ", x);
586 587
               SERIAL_ECHOPAIR(" J ", y);
587 588
               SERIAL_ECHOPGM(" Z ");
588
-              SERIAL_ECHO_F(z_values[x][y], 6);
589
+              SERIAL_ECHO_F(ubl.z_values[x][y], 6);
589 590
               SERIAL_EOL;
590 591
             }
591 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 598
         SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
598 599
         SERIAL_PROTOCOLLNPAIR("?Use 0 to ", j - 1);
599 600
         goto LEAVE;
@@ -617,7 +618,7 @@
617 618
         save_ubl_active_state_and_disable();
618 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 622
         measured_z = 1.5;
622 623
         do_blocking_move_to_z(measured_z);  // Get close to the bed, but leave some space so we don't damage anything
623 624
                                             // The user is not going to be locking in a new Z-Offset very often so
@@ -633,7 +634,7 @@
633 634
           do_blocking_move_to_z(measured_z);
634 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 638
                                           // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
638 639
                                           // or here. So, until we are done looking for a long Encoder Wheel Press,
639 640
                                           // we need to take control of the panel
@@ -653,7 +654,7 @@
653 654
             goto LEAVE;
654 655
           }
655 656
         }
656
-        ubl_has_control_of_lcd_panel = false;
657
+        ubl.has_control_of_lcd_panel = false;
657 658
         safe_delay(20); // We don't want any switch noise.
658 659
 
659 660
         ubl.state.z_offset = measured_z;
@@ -670,7 +671,7 @@
670 671
       lcd_quick_feedback();
671 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 677
   void find_mean_mesh_height() {
@@ -682,8 +683,8 @@
682 683
     n = 0;
683 684
     for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
684 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 688
           n++;
688 689
         }
689 690
 
@@ -694,8 +695,8 @@
694 695
     //
695 696
     for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
696 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 700
           sum_of_diff_squared += difference * difference;
700 701
         }
701 702
 
@@ -712,15 +713,15 @@
712 713
     if (c_flag)
713 714
       for (x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
714 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 720
   void shift_mesh_height() {
720 721
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
721 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,7 +731,7 @@
730 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 732
     mesh_index_pair location;
732 733
 
733
-    ubl_has_control_of_lcd_panel++;
734
+    ubl.has_control_of_lcd_panel++;
734 735
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
735 736
     DEPLOY_PROBE();
736 737
 
@@ -740,7 +741,7 @@
740 741
         lcd_quick_feedback();
741 742
         STOW_PROBE();
742 743
         while (ubl_lcd_clicked()) idle();
743
-        ubl_has_control_of_lcd_panel = false;
744
+        ubl.has_control_of_lcd_panel = false;
744 745
         restore_ubl_active_state_and_leave();
745 746
         safe_delay(50);  // Debounce the Encoder wheel
746 747
         return;
@@ -749,18 +750,18 @@
749 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 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 756
         // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
756 757
         if (rawx < (MIN_PROBE_X) || rawx > (MAX_PROBE_X) || rawy < (MIN_PROBE_Y) || rawy > (MAX_PROBE_Y)) {
757 758
           SERIAL_ERROR_START;
758 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 761
           goto LEAVE;
761 762
         }
762 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 767
       if (do_ubl_mesh_map) ubl.display_map(map_type);
@@ -837,7 +838,7 @@
837 838
     for (i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
838 839
       for (j = 0; j < UBL_MESH_NUM_Y_POINTS; j++) {
839 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 844
     return normal;
@@ -847,9 +848,9 @@
847 848
     KEEPALIVE_STATE(PAUSED_FOR_USER);
848 849
     while (!ubl_lcd_clicked()) {     // we need the loop to move the nozzle based on the encoder wheel here!
849 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 856
     KEEPALIVE_STATE(IN_HANDLER);
@@ -858,7 +859,7 @@
858 859
 
859 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 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 865
     SERIAL_PROTOCOLLNPGM("Place Shim Under Nozzle and Perform Measurement.");
@@ -868,7 +869,7 @@
868 869
 
869 870
     const float z1 = use_encoder_wheel_to_measure_point();
870 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 874
     SERIAL_PROTOCOLLNPGM("Remove Shim and Measure Bed Height.");
874 875
     const float z2 = use_encoder_wheel_to_measure_point();
@@ -885,7 +886,7 @@
885 886
 
886 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 890
     save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
890 891
     do_blocking_move_to_z(z_clearance);
891 892
     do_blocking_move_to_xy(lx, ly);
@@ -899,14 +900,14 @@
899 900
       // It doesn't matter if the probe can't reach the NAN location. This is a manual probe.
900 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 906
       // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
906 907
       if (rawx < (X_MIN_POS) || rawx > (X_MAX_POS) || rawy < (Y_MIN_POS) || rawy > (Y_MAX_POS)) {
907 908
         SERIAL_ERROR_START;
908 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 911
         goto LEAVE;
911 912
       }
912 913
 
@@ -926,13 +927,13 @@
926 927
       last_y = yProbe;
927 928
 
928 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 932
       while (!ubl_lcd_clicked()) {     // we need the loop to move the nozzle based on the encoder wheel here!
932 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,17 +945,17 @@
944 945
           do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);
945 946
           lcd_quick_feedback();
946 947
           while (ubl_lcd_clicked()) idle();
947
-          ubl_has_control_of_lcd_panel = false;
948
+          ubl.has_control_of_lcd_panel = false;
948 949
           KEEPALIVE_STATE(IN_HANDLER);
949 950
           restore_ubl_active_state_and_leave();
950 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 956
       if (g29_verbose_level > 2) {
956 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 959
         SERIAL_EOL;
959 960
       }
960 961
     } while (location.x_index >= 0 && location.y_index >= 0);
@@ -1105,7 +1106,7 @@
1105 1106
    * good to have the extra information. Soon... we prune this to just a few items
1106 1107
    */
1107 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 1111
     SERIAL_PROTOCOLPGM("Unified Bed Leveling System Version 1.00 ");
1111 1112
     if (ubl.state.active)  
@@ -1136,7 +1137,7 @@
1136 1137
 
1137 1138
     SERIAL_PROTOCOLPGM("X-Axis Mesh Points at: ");
1138 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 1141
       SERIAL_PROTOCOLPGM("  ");
1141 1142
       safe_delay(50);
1142 1143
     }
@@ -1144,7 +1145,7 @@
1144 1145
 
1145 1146
     SERIAL_PROTOCOLPGM("Y-Axis Mesh Points at: ");
1146 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 1149
       SERIAL_PROTOCOLPGM("  ");
1149 1150
       safe_delay(50);
1150 1151
     }
@@ -1162,21 +1163,21 @@
1162 1163
     SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk);
1163 1164
     SERIAL_EOL;
1164 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 1169
     safe_delay(50);
1169 1170
 
1170 1171
     SERIAL_PROTOCOLLNPAIR("sizeof(ubl) :  ", (int)sizeof(ubl));
1171 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 1174
     SERIAL_EOL;
1174 1175
     safe_delay(50);
1175 1176
 
1176 1177
     SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: 0x", hex_word(k));
1177 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 1181
     SERIAL_PROTOCOLLNPGM(" meshes.\n");
1181 1182
     safe_delay(50);
1182 1183
 
@@ -1240,9 +1241,9 @@
1240 1241
     }
1241 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 1247
       SERIAL_PROTOCOLLNPGM("?EEPROM storage not available for use.\n");
1247 1248
       return;
1248 1249
     }
@@ -1251,12 +1252,12 @@
1251 1252
     eeprom_read_block((void *)&tmp_z_values, (void *)j, sizeof(tmp_z_values));
1252 1253
 
1253 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 1256
                                                                         // the address in the EEPROM where the Mesh is stored.
1256 1257
 
1257 1258
     for (uint8_t x = 0; x < UBL_MESH_NUM_X_POINTS; x++)
1258 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 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,15 +1276,15 @@
1275 1276
     for (uint8_t i = 0; i < UBL_MESH_NUM_X_POINTS; i++) {
1276 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 1281
           || (type == SET_IN_BITMAP && is_bit_set(bits, i, j))
1281 1282
         ) {
1282 1283
 
1283 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 1289
           // If using the probe as the reference there are some unreachable locations.
1289 1290
           // Prune them from the list and ignore them till the next Phase (manual nozzle probing).
@@ -1303,7 +1304,7 @@
1303 1304
           if (far_flag) {                                           // If doing the far_flag action, we want to be as far as possible
1304 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 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 1308
                   distance += sq(i - k) * (MESH_X_DIST) * .05       // point we can find.
1308 1309
                             + sq(j - l) * (MESH_Y_DIST) * .05;
1309 1310
                 }
@@ -1349,26 +1350,26 @@
1349 1350
       bit_clear(not_done, location.x_index, location.y_index);  // Mark this location as 'adjusted' so we will find a
1350 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 1356
       // TODO: Change to use `position_is_reachable` (for SCARA-compatibility)
1356 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 1358
         SERIAL_ERROR_START;
1358 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 1361
         goto FINE_TUNE_EXIT;
1361 1362
       }
1362 1363
 
1363 1364
       do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE);    // Move the nozzle to where we are going to edit
1364 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 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 1369
       new_z = float(round_off) / 1000.0;
1369 1370
 
1370 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 1374
       lcd_implementation_clear();
1374 1375
       lcd_mesh_edit_setup(new_z);
@@ -1380,7 +1381,7 @@
1380 1381
 
1381 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 1385
                                            // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune)
1385 1386
                                            // or here.
1386 1387
 
@@ -1401,7 +1402,7 @@
1401 1402
 
1402 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 1407
       lcd_implementation_clear();
1407 1408
 
@@ -1409,7 +1410,7 @@
1409 1410
 
1410 1411
     FINE_TUNE_EXIT:
1411 1412
 
1412
-    ubl_has_control_of_lcd_panel = false;
1413
+    ubl.has_control_of_lcd_panel = false;
1413 1414
     KEEPALIVE_STATE(IN_HANDLER);
1414 1415
 
1415 1416
     if (do_ubl_mesh_map) ubl.display_map(map_type);

+ 21
- 21
Marlin/UBL_line_to_destination.cpp View File

@@ -31,12 +31,12 @@
31 31
 
32 32
   extern float destination[XYZE];
33 33
   extern void set_current_to_destination();
34
-
34
+  extern float destination[];
35 35
   void debug_current_and_destination(char *title) {
36 36
 
37 37
     // if the title message starts with a '!' it is so important, we are going to
38 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 41
     const float de = destination[E_AXIS] - current_position[E_AXIS];
42 42
 
@@ -121,7 +121,7 @@
121 121
               cell_dest_xi  = ubl.get_cell_index_x(RAW_X_POSITION(x_end)),
122 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 125
       SERIAL_ECHOPGM(" ubl_line_to_destination(xe=");
126 126
       SERIAL_ECHO(x_end);
127 127
       SERIAL_ECHOPGM(", ye=");
@@ -150,7 +150,7 @@
150 150
         planner.buffer_line(x_end, y_end, z_end + ubl.state.z_offset, e_end, feed_rate, extruder);
151 151
         set_current_to_destination();
152 152
 
153
-        if (g26_debug_flag)
153
+        if (ubl.g26_debug_flag)
154 154
           debug_current_and_destination((char*)"out of bounds in ubl_line_to_destination()");
155 155
 
156 156
         return;
@@ -167,16 +167,16 @@
167 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 176
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
177 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 181
       float z0 = z1 + (z2 - z1) * yratio;
182 182
 
@@ -212,7 +212,7 @@
212 212
 
213 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 216
         debug_current_and_destination((char*)"FINAL_MOVE in ubl_line_to_destination()");
217 217
 
218 218
       set_current_to_destination();
@@ -274,7 +274,7 @@
274 274
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
275 275
       while (current_yi != cell_dest_yi + down_flag) {
276 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 280
          * inf_m_flag? the slope of the line is infinite, we won't do the calculations
@@ -314,9 +314,9 @@
314 314
          * because part of the Mesh is undefined and we don't have the
315 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 322
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
@@ -339,7 +339,7 @@
339 339
         } //else printf("FIRST MOVE PRUNED  ");
340 340
       }
341 341
 
342
-      if (g26_debug_flag)
342
+      if (ubl.g26_debug_flag)
343 343
         debug_current_and_destination((char*)"vertical move done in ubl_line_to_destination()");
344 344
 
345 345
       //
@@ -365,7 +365,7 @@
365 365
                                 // edge of this cell for the first move.
366 366
       while (current_xi != cell_dest_xi + left_flag) {
367 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 369
                     y = m * next_mesh_line_x + c;   // Calculate X at the next Y mesh line
370 370
 
371 371
         float z0 = ubl.get_z_correction_along_vertical_mesh_line_at_specific_Y(y, current_xi, current_yi);
@@ -401,7 +401,7 @@
401 401
          */
402 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 407
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
@@ -424,7 +424,7 @@
424 424
         } //else printf("FIRST MOVE PRUNED  ");
425 425
       }
426 426
 
427
-      if (g26_debug_flag)
427
+      if (ubl.g26_debug_flag)
428 428
         debug_current_and_destination((char*)"horizontal move done in ubl_line_to_destination()");
429 429
 
430 430
       if (current_position[X_AXIS] != x_end || current_position[Y_AXIS] != y_end)
@@ -451,8 +451,8 @@
451 451
 
452 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 456
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
457 457
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line    (we don't have to worry
458 458
                                                   // about m being equal to 0.0  If this was the case, we would have
@@ -563,7 +563,7 @@
563 563
       }
564 564
     }
565 565
 
566
-    if (g26_debug_flag)
566
+    if (ubl.g26_debug_flag)
567 567
       debug_current_and_destination((char*)"generic move done in ubl_line_to_destination()");
568 568
 
569 569
     if (current_position[0] != x_end || current_position[1] != y_end)

+ 2
- 2
Marlin/configuration_store.cpp View File

@@ -846,7 +846,7 @@ void Config_Postprocess() {
846 846
       }
847 847
 
848 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 850
                                                          // can float up or down a little bit without
851 851
                                                          // disrupting the Unified Bed Leveling data
852 852
         ubl.load_state();
@@ -1232,7 +1232,7 @@ void Config_ResetDefault() {
1232 1232
         SERIAL_ECHO_F(ubl.state.z_offset, 6);
1233 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 1236
         SERIAL_ECHOLNPGM(" meshes.\n");
1237 1237
 
1238 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,7 +863,7 @@
863 863
   #define UBL_PROBE_PT_2_Y 20
864 864
   #define UBL_PROBE_PT_3_X 180
865 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 868
 #elif ENABLED(MESH_BED_LEVELING)
869 869
 

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

@@ -846,7 +846,7 @@
846 846
   #define UBL_PROBE_PT_2_Y 20
847 847
   #define UBL_PROBE_PT_3_X 180
848 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 851
 #elif ENABLED(MESH_BED_LEVELING)
852 852
 

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

@@ -846,7 +846,7 @@
846 846
   #define UBL_PROBE_PT_2_Y 20
847 847
   #define UBL_PROBE_PT_3_X 180
848 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 851
 #elif ENABLED(MESH_BED_LEVELING)
852 852
 

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

@@ -855,7 +855,7 @@
855 855
   #define UBL_PROBE_PT_2_Y 20
856 856
   #define UBL_PROBE_PT_3_X 180
857 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 860
 #elif ENABLED(MESH_BED_LEVELING)
861 861
 

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

@@ -857,7 +857,7 @@
857 857
   #define UBL_PROBE_PT_2_Y 20
858 858
   #define UBL_PROBE_PT_3_X 180
859 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 862
 #elif ENABLED(MESH_BED_LEVELING)
863 863
 

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

@@ -892,7 +892,7 @@
892 892
   #define UBL_PROBE_PT_2_Y 20
893 893
   #define UBL_PROBE_PT_3_X 180
894 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 897
 #elif ENABLED(MESH_BED_LEVELING)
898 898
 

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

@@ -863,7 +863,7 @@
863 863
   #define UBL_PROBE_PT_2_Y 20
864 864
   #define UBL_PROBE_PT_3_X 180
865 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 868
 #elif ENABLED(MESH_BED_LEVELING)
869 869
 

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

@@ -863,7 +863,7 @@
863 863
   #define UBL_PROBE_PT_2_Y 20
864 864
   #define UBL_PROBE_PT_3_X 180
865 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 868
 #elif ENABLED(MESH_BED_LEVELING)
869 869
 

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

@@ -863,7 +863,7 @@
863 863
   #define UBL_PROBE_PT_2_Y 20
864 864
   #define UBL_PROBE_PT_3_X 180
865 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 868
 #elif ENABLED(MESH_BED_LEVELING)
869 869
 

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

@@ -862,7 +862,7 @@
862 862
   #define UBL_PROBE_PT_2_Y 20
863 863
   #define UBL_PROBE_PT_3_X 180
864 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 867
 #elif ENABLED(MESH_BED_LEVELING)
868 868
 

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

@@ -878,7 +878,7 @@
878 878
   #define UBL_PROBE_PT_2_Y 20
879 879
   #define UBL_PROBE_PT_3_X 180
880 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 883
 #elif ENABLED(MESH_BED_LEVELING)
884 884
 

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

@@ -884,7 +884,7 @@
884 884
   #define UBL_PROBE_PT_2_Y 20
885 885
   #define UBL_PROBE_PT_3_X 180
886 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 889
 #elif ENABLED(MESH_BED_LEVELING)
890 890
 

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

@@ -855,7 +855,7 @@
855 855
   #define UBL_PROBE_PT_2_Y 20
856 856
   #define UBL_PROBE_PT_3_X 180
857 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 860
 #elif ENABLED(MESH_BED_LEVELING)
861 861
 

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

@@ -863,7 +863,7 @@
863 863
   #define UBL_PROBE_PT_2_Y 20
864 864
   #define UBL_PROBE_PT_3_X 180
865 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 868
 #elif ENABLED(MESH_BED_LEVELING)
869 869
 

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

@@ -968,7 +968,7 @@
968 968
   #define UBL_PROBE_PT_2_Y 20
969 969
   #define UBL_PROBE_PT_3_X 180
970 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 973
 #elif ENABLED(MESH_BED_LEVELING)
974 974
 

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

@@ -954,7 +954,7 @@
954 954
   #define UBL_PROBE_PT_2_Y 20
955 955
   #define UBL_PROBE_PT_3_X 180
956 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 959
 #elif ENABLED(MESH_BED_LEVELING)
960 960
 

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

@@ -958,7 +958,7 @@
958 958
   #define UBL_PROBE_PT_2_Y 20
959 959
   #define UBL_PROBE_PT_3_X 180
960 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 963
 #elif ENABLED(MESH_BED_LEVELING)
964 964
 

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

@@ -957,7 +957,7 @@
957 957
   #define UBL_PROBE_PT_2_Y 20
958 958
   #define UBL_PROBE_PT_3_X 180
959 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 962
 #elif ENABLED(MESH_BED_LEVELING)
963 963
 

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

@@ -967,7 +967,7 @@
967 967
   #define UBL_PROBE_PT_2_Y 20
968 968
   #define UBL_PROBE_PT_3_X 180
969 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 972
 #elif ENABLED(MESH_BED_LEVELING)
973 973
 

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

@@ -866,7 +866,7 @@
866 866
   #define UBL_PROBE_PT_2_Y 20
867 867
   #define UBL_PROBE_PT_3_X 180
868 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 871
 #elif ENABLED(MESH_BED_LEVELING)
872 872
 

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

@@ -859,7 +859,7 @@
859 859
   #define UBL_PROBE_PT_2_Y 20
860 860
   #define UBL_PROBE_PT_3_X 180
861 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 864
 #elif ENABLED(MESH_BED_LEVELING)
865 865
 

+ 7
- 8
Marlin/ultralcd.cpp View File

@@ -124,8 +124,7 @@ uint16_t max_display_update_time = 0;
124 124
   int32_t lastEncoderMovementMillis;
125 125
 
126 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 128
   #endif
130 129
 
131 130
   #if HAS_POWER_SWITCH
@@ -860,9 +859,9 @@ void kill_screen(const char* lcd_msg) {
860 859
 
861 860
     static void _lcd_mesh_fine_tune(const char* msg) {
862 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 866
         mesh_edit_accumulator += float(ubl_encoderPosition) * 0.005 / 2.0;
868 867
         mesh_edit_value = mesh_edit_accumulator;
@@ -3206,7 +3205,7 @@ void lcd_update() {
3206 3205
     lcd_buttons_update();
3207 3206
 
3208 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 3209
     #else
3211 3210
       constexpr bool UBL_CONDITION = true;
3212 3211
     #endif
@@ -3622,8 +3621,8 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; }
3622 3621
         case encrot3: ENCODER_SPIN(encrot2, encrot0); break;
3623 3622
       }
3624 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 3626
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
3628 3627
                                             // wheel has not turned.
3629 3628
         }

Loading…
Cancel
Save