Browse Source

Merge pull request #6827 from thinkyhead/bf_day_ending_in_y

Make UBL a complete singleton
Scott Lahteine 8 years ago
parent
commit
62d8e35adc

+ 137
- 160
Marlin/G26_Mesh_Validation_Tool.cpp View File

135
   float code_value_axis_units(const AxisEnum axis);
135
   float code_value_axis_units(const AxisEnum axis);
136
   bool code_value_bool();
136
   bool code_value_bool();
137
   bool code_has_value();
137
   bool code_has_value();
138
-  void lcd_init();
139
-  void lcd_setstatuspgm(const char* const message, const uint8_t level);
140
   void sync_plan_position_e();
138
   void sync_plan_position_e();
141
   void chirp_at_user();
139
   void chirp_at_user();
142
 
140
 
143
   // Private functions
141
   // Private functions
144
 
142
 
145
-  void un_retract_filament(float where[XYZE]);
146
-  void retract_filament(float where[XYZE]);
147
-  bool look_for_lines_to_connect();
148
-  bool parse_G26_parameters();
149
-  void move_to(const float&, const float&, const float&, const float&) ;
150
-  void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&);
151
-  bool turn_on_heaters();
152
-  bool prime_nozzle();
153
-
154
   static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
143
   static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
155
   float g26_e_axis_feedrate = 0.020,
144
   float g26_e_axis_feedrate = 0.020,
156
-        random_deviation = 0.0,
157
-        layer_height = LAYER_HEIGHT;
145
+        random_deviation = 0.0;
158
 
146
 
159
   static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
147
   static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
160
                                      // retracts/recovers won't result in a bad state.
148
                                      // retracts/recovers won't result in a bad state.
161
 
149
 
162
   float valid_trig_angle(float);
150
   float valid_trig_angle(float);
163
-  mesh_index_pair find_closest_circle_to_print(const float&, const float&);
164
 
151
 
165
-  static float extrusion_multiplier = EXTRUSION_MULTIPLIER,
166
-               retraction_multiplier = RETRACTION_MULTIPLIER,
167
-               nozzle = NOZZLE,
168
-               filament_diameter = FILAMENT,
169
-               prime_length = PRIME_LENGTH,
170
-               x_pos, y_pos,
171
-               ooze_amount = OOZE_AMOUNT;
152
+  float unified_bed_leveling::g26_extrusion_multiplier,
153
+        unified_bed_leveling::g26_retraction_multiplier,
154
+        unified_bed_leveling::g26_nozzle,
155
+        unified_bed_leveling::g26_filament_diameter,
156
+        unified_bed_leveling::g26_layer_height,
157
+        unified_bed_leveling::g26_prime_length,
158
+        unified_bed_leveling::g26_x_pos,
159
+        unified_bed_leveling::g26_y_pos,
160
+        unified_bed_leveling::g26_ooze_amount;
172
 
161
 
173
-  static int16_t bed_temp = BED_TEMP,
174
-                 hotend_temp = HOTEND_TEMP;
162
+  int16_t unified_bed_leveling::g26_bed_temp,
163
+          unified_bed_leveling::g26_hotend_temp;
175
 
164
 
176
-  static int8_t prime_flag = 0;
165
+  int8_t unified_bed_leveling::g26_prime_flag;
177
 
166
 
178
-  static bool continue_with_closest, keep_heaters_on;
167
+  bool unified_bed_leveling::g26_continue_with_closest,
168
+       unified_bed_leveling::g26_keep_heaters_on;
179
 
169
 
180
-  static int16_t g26_repeats;
170
+  int16_t unified_bed_leveling::g26_repeats;
181
 
171
 
182
-  void G26_line_to_destination(const float &feed_rate) {
172
+  void unified_bed_leveling::G26_line_to_destination(const float &feed_rate) {
183
     const float save_feedrate = feedrate_mm_s;
173
     const float save_feedrate = feedrate_mm_s;
184
     feedrate_mm_s = feed_rate;      // use specified feed rate
174
     feedrate_mm_s = feed_rate;      // use specified feed rate
185
-    prepare_move_to_destination();  // will ultimately call ubl_line_to_destination_cartesian or ubl_prepare_linear_move_to for UBL_DELTA
175
+    prepare_move_to_destination();  // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_DELTA
186
     feedrate_mm_s = save_feedrate;  // restore global feed rate
176
     feedrate_mm_s = save_feedrate;  // restore global feed rate
187
   }
177
   }
188
 
178
 
189
   /**
179
   /**
180
+   * Detect ubl_lcd_clicked, debounce it, and return true for cancel
181
+   */
182
+  bool user_canceled() {
183
+    if (!ubl_lcd_clicked()) return false;
184
+    safe_delay(10);                       // Wait for click to settle
185
+
186
+    #if ENABLED(ULTRA_LCD)
187
+      lcd_setstatuspgm(PSTR("Mesh Validation Stopped."), 99);
188
+      lcd_quick_feedback();
189
+    #endif
190
+    lcd_reset_alert_level();
191
+
192
+    while (!ubl_lcd_clicked()) idle();    // Wait for button release
193
+
194
+    // If the button is suddenly pressed again,
195
+    // ask the user to resolve the issue
196
+    lcd_setstatuspgm(PSTR("Release button"), 99); // will never appear...
197
+    while (ubl_lcd_clicked()) idle();             // unless this loop happens
198
+    lcd_setstatuspgm(PSTR(""));
199
+
200
+    return true;
201
+  }
202
+
203
+  /**
190
    * G26: Mesh Validation Pattern generation.
204
    * G26: Mesh Validation Pattern generation.
191
    *
205
    *
192
    * Used to interactively edit UBL's Mesh by placing the
206
    * Used to interactively edit UBL's Mesh by placing the
193
    * nozzle in a problem area and doing a G29 P4 R command.
207
    * nozzle in a problem area and doing a G29 P4 R command.
194
    */
208
    */
195
-  void gcode_G26() {
209
+  void unified_bed_leveling::G26() {
196
     SERIAL_ECHOLNPGM("G26 command started.  Waiting for heater(s).");
210
     SERIAL_ECHOLNPGM("G26 command started.  Waiting for heater(s).");
197
     float tmp, start_angle, end_angle;
211
     float tmp, start_angle, end_angle;
198
     int   i, xi, yi;
212
     int   i, xi, yi;
213
     current_position[E_AXIS] = 0.0;
227
     current_position[E_AXIS] = 0.0;
214
     sync_plan_position_e();
228
     sync_plan_position_e();
215
 
229
 
216
-    if (prime_flag && prime_nozzle()) goto LEAVE;
230
+    if (g26_prime_flag && prime_nozzle()) goto LEAVE;
217
 
231
 
218
     /**
232
     /**
219
      *  Bed is preheated
233
      *  Bed is preheated
231
 
245
 
232
     // Move nozzle to the specified height for the first layer
246
     // Move nozzle to the specified height for the first layer
233
     set_destination_to_current();
247
     set_destination_to_current();
234
-    destination[Z_AXIS] = layer_height;
248
+    destination[Z_AXIS] = g26_layer_height;
235
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
249
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0.0);
236
-    move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], ooze_amount);
250
+    move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], g26_ooze_amount);
237
 
251
 
238
-    ubl.has_control_of_lcd_panel = true;
252
+    has_control_of_lcd_panel = true;
239
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
253
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
240
 
254
 
241
     /**
255
     /**
249
     }
263
     }
250
 
264
 
251
     do {
265
     do {
252
-      location = continue_with_closest
266
+      location = g26_continue_with_closest
253
         ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
267
         ? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
254
-        : find_closest_circle_to_print(x_pos, y_pos); // Find the closest Mesh Intersection to where we are now.
268
+        : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now.
255
 
269
 
256
       if (location.x_index >= 0 && location.y_index >= 0) {
270
       if (location.x_index >= 0 && location.y_index >= 0) {
257
-        const float circle_x = pgm_read_float(&ubl.mesh_index_to_xpos[location.x_index]),
258
-                    circle_y = pgm_read_float(&ubl.mesh_index_to_ypos[location.y_index]);
271
+        const float circle_x = mesh_index_to_xpos(location.x_index),
272
+                    circle_y = mesh_index_to_ypos(location.y_index);
259
 
273
 
260
         // If this mesh location is outside the printable_radius, skip it.
274
         // If this mesh location is outside the printable_radius, skip it.
261
 
275
 
264
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
278
         xi = location.x_index;  // Just to shrink the next few lines and make them easier to understand
265
         yi = location.y_index;
279
         yi = location.y_index;
266
 
280
 
267
-        if (ubl.g26_debug_flag) {
281
+        if (g26_debug_flag) {
268
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
282
           SERIAL_ECHOPAIR("   Doing circle at: (xi=", xi);
269
           SERIAL_ECHOPAIR(", yi=", yi);
283
           SERIAL_ECHOPAIR(", yi=", yi);
270
           SERIAL_CHAR(')');
284
           SERIAL_CHAR(')');
300
 
314
 
301
         for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) {
315
         for (tmp = start_angle; tmp < end_angle - 0.1; tmp += 30.0) {
302
 
316
 
303
-          // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is
304
-          // a Press and Hold is repeated in a lot of places (including ubl_G29.cpp).   This
305
-          // should be redone and compressed.
306
-          if (ubl_lcd_clicked()) {              // Check if the user wants to stop the Mesh Validation
307
-            #if ENABLED(ULTRA_LCD)
308
-              lcd_setstatuspgm(PSTR("Mesh Validation Stopped."), 99);
309
-              lcd_quick_feedback();
310
-            #endif
311
-            while (!ubl_lcd_clicked()) {         // Wait until the user is done pressing the
312
-              idle();                            // Encoder Wheel if that is why we are leaving
313
-              lcd_reset_alert_level();
314
-              lcd_setstatuspgm(PSTR(""));
315
-            }
316
-            while (ubl_lcd_clicked()) {          // Wait until the user is done pressing the
317
-              idle();                            // Encoder Wheel if that is why we are leaving
318
-              lcd_setstatuspgm(PSTR("Unpress Wheel"), 99);
319
-            }
320
-            goto LEAVE;
321
-          }
317
+          if (user_canceled()) goto LEAVE;              // Check if the user wants to stop the Mesh Validation
322
 
318
 
323
           int tmp_div_30 = tmp / 30.0;
319
           int tmp_div_30 = tmp / 30.0;
324
           if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
320
           if (tmp_div_30 < 0) tmp_div_30 += 360 / 30;
338
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
334
             ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
339
           #endif
335
           #endif
340
 
336
 
341
-          //if (ubl.g26_debug_flag) {
337
+          //if (g26_debug_flag) {
342
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
338
           //  char ccc, *cptr, seg_msg[50], seg_num[10];
343
           //  strcpy(seg_msg, "   segment: ");
339
           //  strcpy(seg_msg, "   segment: ");
344
           //  strcpy(seg_num, "    \n");
340
           //  strcpy(seg_num, "    \n");
349
           //  debug_current_and_destination(seg_msg);
345
           //  debug_current_and_destination(seg_msg);
350
           //}
346
           //}
351
 
347
 
352
-          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);
348
+          print_line_from_here_to_there(LOGICAL_X_POSITION(x), LOGICAL_Y_POSITION(y), g26_layer_height, LOGICAL_X_POSITION(xe), LOGICAL_Y_POSITION(ye), g26_layer_height);
353
 
349
 
354
         }
350
         }
355
         if (look_for_lines_to_connect())
351
         if (look_for_lines_to_connect())
368
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Raise the nozzle
364
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Raise the nozzle
369
     //debug_current_and_destination(PSTR("done doing Z-Raise."));
365
     //debug_current_and_destination(PSTR("done doing Z-Raise."));
370
 
366
 
371
-    destination[X_AXIS] = x_pos;                                               // Move back to the starting position
372
-    destination[Y_AXIS] = y_pos;
367
+    destination[X_AXIS] = g26_x_pos;                                               // Move back to the starting position
368
+    destination[Y_AXIS] = g26_y_pos;
373
     //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;                        // Keep the nozzle where it is
369
     //destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;                        // Keep the nozzle where it is
374
 
370
 
375
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
371
     move_to(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], 0); // Move back to the starting position
376
     //debug_current_and_destination(PSTR("done doing X/Y move."));
372
     //debug_current_and_destination(PSTR("done doing X/Y move."));
377
 
373
 
378
-    ubl.has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
374
+    has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
379
 
375
 
380
-    if (!keep_heaters_on) {
376
+    if (!g26_keep_heaters_on) {
381
       #if HAS_TEMP_BED
377
       #if HAS_TEMP_BED
382
         thermalManager.setTargetBed(0);
378
         thermalManager.setTargetBed(0);
383
       #endif
379
       #endif
385
     }
381
     }
386
   }
382
   }
387
 
383
 
388
-
389
   float valid_trig_angle(float d) {
384
   float valid_trig_angle(float d) {
390
     while (d > 360.0) d -= 360.0;
385
     while (d > 360.0) d -= 360.0;
391
     while (d < 0.0) d += 360.0;
386
     while (d < 0.0) d += 360.0;
392
     return d;
387
     return d;
393
   }
388
   }
394
 
389
 
395
-  mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
390
+  mesh_index_pair unified_bed_leveling::find_closest_circle_to_print(const float &X, const float &Y) {
396
     float closest = 99999.99;
391
     float closest = 99999.99;
397
     mesh_index_pair return_val;
392
     mesh_index_pair return_val;
398
 
393
 
401
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
396
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
402
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
397
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
403
         if (!is_bit_set(circle_flags, i, j)) {
398
         if (!is_bit_set(circle_flags, i, j)) {
404
-          const float mx = pgm_read_float(&ubl.mesh_index_to_xpos[i]),  // We found a circle that needs to be printed
405
-                      my = pgm_read_float(&ubl.mesh_index_to_ypos[j]);
399
+          const float mx = mesh_index_to_xpos(i),  // We found a circle that needs to be printed
400
+                      my = mesh_index_to_ypos(j);
406
 
401
 
407
           // Get the distance to this intersection
402
           // Get the distance to this intersection
408
           float f = HYPOT(X - mx, Y - my);
403
           float f = HYPOT(X - mx, Y - my);
411
           // to let us find the closest circle to the start position.
406
           // to let us find the closest circle to the start position.
412
           // But if this is not the case, add a small weighting to the
407
           // But if this is not the case, add a small weighting to the
413
           // distance calculation to help it choose a better place to continue.
408
           // distance calculation to help it choose a better place to continue.
414
-          f += HYPOT(x_pos - mx, y_pos - my) / 15.0;
409
+          f += HYPOT(g26_x_pos - mx, g26_y_pos - my) / 15.0;
415
 
410
 
416
           // Add in the specified amount of Random Noise to our search
411
           // Add in the specified amount of Random Noise to our search
417
           if (random_deviation > 1.0)
412
           if (random_deviation > 1.0)
430
     return return_val;
425
     return return_val;
431
   }
426
   }
432
 
427
 
433
-  bool look_for_lines_to_connect() {
428
+  bool unified_bed_leveling::look_for_lines_to_connect() {
434
     float sx, sy, ex, ey;
429
     float sx, sy, ex, ey;
435
 
430
 
436
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
431
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
437
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
432
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
438
 
433
 
439
-        // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is
440
-        // a Press and Hold is repeated in a lot of places (including ubl_G29.cpp).   This
441
-        // should be redone and compressed.
442
-        if (ubl_lcd_clicked()) {              // Check if the user wants to stop the Mesh Validation
443
-          #if ENABLED(ULTRA_LCD)
444
-            lcd_setstatuspgm(PSTR("Mesh Validation Stopped."), 99);
445
-            lcd_quick_feedback();
446
-          #endif
447
-          while (!ubl_lcd_clicked()) {         // Wait until the user is done pressing the
448
-            idle();                            // Encoder Wheel if that is why we are leaving
449
-            lcd_reset_alert_level();
450
-            lcd_setstatuspgm(PSTR(""));
451
-          }
452
-          while (ubl_lcd_clicked()) {          // Wait until the user is done pressing the
453
-            idle();                            // Encoder Wheel if that is why we are leaving
454
-            lcd_setstatuspgm(PSTR("Unpress Wheel"), 99);
455
-          }
456
-          return true;
457
-        }
434
+        if (user_canceled()) return true;     // Check if the user wants to stop the Mesh Validation
458
 
435
 
459
         if (i < GRID_MAX_POINTS_X) { // We can't connect to anything to the right than GRID_MAX_POINTS_X.
436
         if (i < GRID_MAX_POINTS_X) { // We can't connect to anything to the right than GRID_MAX_POINTS_X.
460
-                                         // This is already a half circle because we are at the edge of the bed.
437
+                                     // This is already a half circle because we are at the edge of the bed.
461
 
438
 
462
           if (is_bit_set(circle_flags, i, j) && is_bit_set(circle_flags, i + 1, j)) { // check if we can do a line to the left
439
           if (is_bit_set(circle_flags, i, j) && is_bit_set(circle_flags, i + 1, j)) { // check if we can do a line to the left
463
             if (!is_bit_set(horizontal_mesh_line_flags, i, j)) {
440
             if (!is_bit_set(horizontal_mesh_line_flags, i, j)) {
466
               // We found two circles that need a horizontal line to connect them
443
               // We found two circles that need a horizontal line to connect them
467
               // Print it!
444
               // Print it!
468
               //
445
               //
469
-              sx = pgm_read_float(&ubl.mesh_index_to_xpos[  i  ]) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
470
-              ex = pgm_read_float(&ubl.mesh_index_to_xpos[i + 1]) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge
446
+              sx = mesh_index_to_xpos(  i  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
447
+              ex = mesh_index_to_xpos(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge
471
 
448
 
472
               sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
449
               sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
473
-              sy = ey = constrain(pgm_read_float(&ubl.mesh_index_to_ypos[j]), Y_MIN_POS + 1, Y_MAX_POS - 1);
450
+              sy = ey = constrain(mesh_index_to_ypos(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
474
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
451
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
475
 
452
 
476
               if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
453
               if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
477
 
454
 
478
-                if (ubl.g26_debug_flag) {
455
+                if (g26_debug_flag) {
479
                   SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
456
                   SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
480
                   SERIAL_ECHOPAIR(", sy=", sy);
457
                   SERIAL_ECHOPAIR(", sy=", sy);
481
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
458
                   SERIAL_ECHOPAIR(") -> (ex=", ex);
485
                   //debug_current_and_destination(PSTR("Connecting horizontal line."));
462
                   //debug_current_and_destination(PSTR("Connecting horizontal line."));
486
                 }
463
                 }
487
 
464
 
488
-                print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), layer_height);
465
+                print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height);
489
               }
466
               }
490
               bit_set(horizontal_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if we skipped it
467
               bit_set(horizontal_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if we skipped it
491
             }
468
             }
500
                 // We found two circles that need a vertical line to connect them
477
                 // We found two circles that need a vertical line to connect them
501
                 // Print it!
478
                 // Print it!
502
                 //
479
                 //
503
-                sy = pgm_read_float(&ubl.mesh_index_to_ypos[  j  ]) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
504
-                ey = pgm_read_float(&ubl.mesh_index_to_ypos[j + 1]) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge
480
+                sy = mesh_index_to_ypos(  j  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
481
+                ey = mesh_index_to_ypos(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge
505
 
482
 
506
-                sx = ex = constrain(pgm_read_float(&ubl.mesh_index_to_xpos[i]), X_MIN_POS + 1, X_MAX_POS - 1);
483
+                sx = ex = constrain(mesh_index_to_xpos(i), X_MIN_POS + 1, X_MAX_POS - 1);
507
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
484
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
508
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
485
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
509
 
486
 
510
                 if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
487
                 if (position_is_reachable_raw_xy(sx, sy) && position_is_reachable_raw_xy(ex, ey)) {
511
 
488
 
512
-                  if (ubl.g26_debug_flag) {
489
+                  if (g26_debug_flag) {
513
                     SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
490
                     SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
514
                     SERIAL_ECHOPAIR(", sy=", sy);
491
                     SERIAL_ECHOPAIR(", sy=", sy);
515
                     SERIAL_ECHOPAIR(") -> (ex=", ex);
492
                     SERIAL_ECHOPAIR(") -> (ex=", ex);
518
                     SERIAL_EOL;
495
                     SERIAL_EOL;
519
                     debug_current_and_destination(PSTR("Connecting vertical line."));
496
                     debug_current_and_destination(PSTR("Connecting vertical line."));
520
                   }
497
                   }
521
-                  print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), layer_height);
498
+                  print_line_from_here_to_there(LOGICAL_X_POSITION(sx), LOGICAL_Y_POSITION(sy), g26_layer_height, LOGICAL_X_POSITION(ex), LOGICAL_Y_POSITION(ey), g26_layer_height);
522
                 }
499
                 }
523
                 bit_set(vertical_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if skipped
500
                 bit_set(vertical_mesh_line_flags, i, j);   // Mark it as done so we don't do it again, even if skipped
524
               }
501
               }
530
     return false;
507
     return false;
531
   }
508
   }
532
 
509
 
533
-  void move_to(const float &x, const float &y, const float &z, const float &e_delta) {
510
+  void unified_bed_leveling::move_to(const float &x, const float &y, const float &z, const float &e_delta) {
534
     float feed_value;
511
     float feed_value;
535
     static float last_z = -999.99;
512
     static float last_z = -999.99;
536
 
513
 
552
     }
529
     }
553
 
530
 
554
     // Check if X or Y is involved in the movement.
531
     // Check if X or Y is involved in the movement.
555
-    // Yes: a 'normal' movement. No: a retract() or un_retract()
532
+    // Yes: a 'normal' movement. No: a retract() or recover()
556
     feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
533
     feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
557
 
534
 
558
-    if (ubl.g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
535
+    if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
559
 
536
 
560
     destination[X_AXIS] = x;
537
     destination[X_AXIS] = x;
561
     destination[Y_AXIS] = y;
538
     destination[Y_AXIS] = y;
568
 
545
 
569
   }
546
   }
570
 
547
 
571
-  void retract_filament(float where[XYZE]) {
548
+  void unified_bed_leveling::retract_filament(float where[XYZE]) {
572
     if (!g26_retracted) { // Only retract if we are not already retracted!
549
     if (!g26_retracted) { // Only retract if we are not already retracted!
573
       g26_retracted = true;
550
       g26_retracted = true;
574
-      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], -1.0 * retraction_multiplier);
551
+      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], -1.0 * g26_retraction_multiplier);
575
     }
552
     }
576
   }
553
   }
577
 
554
 
578
-  void un_retract_filament(float where[XYZE]) {
555
+  void unified_bed_leveling::recover_filament(float where[XYZE]) {
579
     if (g26_retracted) { // Only un-retract if we are retracted.
556
     if (g26_retracted) { // Only un-retract if we are retracted.
580
-      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], 1.2 * retraction_multiplier);
557
+      move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], 1.2 * g26_retraction_multiplier);
581
       g26_retracted = false;
558
       g26_retracted = false;
582
     }
559
     }
583
   }
560
   }
597
    * segment of a 'circle'.   The time this requires is very short and is easily saved by the other
574
    * segment of a 'circle'.   The time this requires is very short and is easily saved by the other
598
    * cases where the optimization comes into play.
575
    * cases where the optimization comes into play.
599
    */
576
    */
600
-  void print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) {
577
+  void unified_bed_leveling::print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) {
601
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
578
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
602
                 dy_s = current_position[Y_AXIS] - sy,
579
                 dy_s = current_position[Y_AXIS] - sy,
603
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
580
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
625
 
602
 
626
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump
603
     move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump
627
 
604
 
628
-    const float e_pos_delta = line_length * g26_e_axis_feedrate * extrusion_multiplier;
605
+    const float e_pos_delta = line_length * g26_e_axis_feedrate * g26_extrusion_multiplier;
629
 
606
 
630
-    un_retract_filament(destination);
607
+    recover_filament(destination);
631
     move_to(ex, ey, ez, e_pos_delta);  // Get to the ending point with an appropriate amount of extrusion
608
     move_to(ex, ey, ez, e_pos_delta);  // Get to the ending point with an appropriate amount of extrusion
632
   }
609
   }
633
 
610
 
636
    * parameters it made sense to turn them into static globals and get
613
    * parameters it made sense to turn them into static globals and get
637
    * this code out of sight of the main routine.
614
    * this code out of sight of the main routine.
638
    */
615
    */
639
-  bool parse_G26_parameters() {
640
-
641
-    extrusion_multiplier  = EXTRUSION_MULTIPLIER;
642
-    retraction_multiplier = RETRACTION_MULTIPLIER;
643
-    nozzle                = NOZZLE;
644
-    filament_diameter     = FILAMENT;
645
-    layer_height          = LAYER_HEIGHT;
646
-    prime_length          = PRIME_LENGTH;
647
-    bed_temp              = BED_TEMP;
648
-    hotend_temp           = HOTEND_TEMP;
649
-    prime_flag            = 0;
650
-
651
-    ooze_amount           = code_seen('O') && code_has_value() ? code_value_linear_units() : OOZE_AMOUNT;
652
-    keep_heaters_on       = code_seen('K') && code_value_bool();
653
-    continue_with_closest = code_seen('C') && code_value_bool();
616
+  bool unified_bed_leveling::parse_G26_parameters() {
617
+
618
+    g26_extrusion_multiplier  = EXTRUSION_MULTIPLIER;
619
+    g26_retraction_multiplier = RETRACTION_MULTIPLIER;
620
+    g26_nozzle                = NOZZLE;
621
+    g26_filament_diameter     = FILAMENT;
622
+    g26_layer_height          = LAYER_HEIGHT;
623
+    g26_prime_length          = PRIME_LENGTH;
624
+    g26_bed_temp              = BED_TEMP;
625
+    g26_hotend_temp           = HOTEND_TEMP;
626
+    g26_prime_flag            = 0;
627
+
628
+    g26_ooze_amount           = code_seen('O') && code_has_value() ? code_value_linear_units() : OOZE_AMOUNT;
629
+    g26_keep_heaters_on       = code_seen('K') && code_value_bool();
630
+    g26_continue_with_closest = code_seen('C') && code_value_bool();
654
 
631
 
655
     if (code_seen('B')) {
632
     if (code_seen('B')) {
656
-      bed_temp = code_value_temp_abs();
657
-      if (!WITHIN(bed_temp, 15, 140)) {
633
+      g26_bed_temp = code_value_temp_abs();
634
+      if (!WITHIN(g26_bed_temp, 15, 140)) {
658
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
635
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
659
         return UBL_ERR;
636
         return UBL_ERR;
660
       }
637
       }
661
     }
638
     }
662
 
639
 
663
     if (code_seen('L')) {
640
     if (code_seen('L')) {
664
-      layer_height = code_value_linear_units();
665
-      if (!WITHIN(layer_height, 0.0, 2.0)) {
641
+      g26_layer_height = code_value_linear_units();
642
+      if (!WITHIN(g26_layer_height, 0.0, 2.0)) {
666
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
643
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
667
         return UBL_ERR;
644
         return UBL_ERR;
668
       }
645
       }
670
 
647
 
671
     if (code_seen('Q')) {
648
     if (code_seen('Q')) {
672
       if (code_has_value()) {
649
       if (code_has_value()) {
673
-        retraction_multiplier = code_value_float();
674
-        if (!WITHIN(retraction_multiplier, 0.05, 15.0)) {
650
+        g26_retraction_multiplier = code_value_float();
651
+        if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) {
675
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
652
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
676
           return UBL_ERR;
653
           return UBL_ERR;
677
         }
654
         }
683
     }
660
     }
684
 
661
 
685
     if (code_seen('S')) {
662
     if (code_seen('S')) {
686
-      nozzle = code_value_float();
687
-      if (!WITHIN(nozzle, 0.1, 1.0)) {
663
+      g26_nozzle = code_value_float();
664
+      if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
688
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
665
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
689
         return UBL_ERR;
666
         return UBL_ERR;
690
       }
667
       }
692
 
669
 
693
     if (code_seen('P')) {
670
     if (code_seen('P')) {
694
       if (!code_has_value())
671
       if (!code_has_value())
695
-        prime_flag = -1;
672
+        g26_prime_flag = -1;
696
       else {
673
       else {
697
-        prime_flag++;
698
-        prime_length = code_value_linear_units();
699
-        if (!WITHIN(prime_length, 0.0, 25.0)) {
674
+        g26_prime_flag++;
675
+        g26_prime_length = code_value_linear_units();
676
+        if (!WITHIN(g26_prime_length, 0.0, 25.0)) {
700
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
677
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
701
           return UBL_ERR;
678
           return UBL_ERR;
702
         }
679
         }
704
     }
681
     }
705
 
682
 
706
     if (code_seen('F')) {
683
     if (code_seen('F')) {
707
-      filament_diameter = code_value_linear_units();
708
-      if (!WITHIN(filament_diameter, 1.0, 4.0)) {
684
+      g26_filament_diameter = code_value_linear_units();
685
+      if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) {
709
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
686
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
710
         return UBL_ERR;
687
         return UBL_ERR;
711
       }
688
       }
712
     }
689
     }
713
-    extrusion_multiplier *= sq(1.75) / sq(filament_diameter);         // If we aren't using 1.75mm filament, we need to
690
+    g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter);         // If we aren't using 1.75mm filament, we need to
714
                                                                       // scale up or down the length needed to get the
691
                                                                       // scale up or down the length needed to get the
715
                                                                       // same volume of filament
692
                                                                       // same volume of filament
716
 
693
 
717
-    extrusion_multiplier *= filament_diameter * sq(nozzle) / sq(0.3); // Scale up by nozzle size
694
+    g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size
718
 
695
 
719
     if (code_seen('H')) {
696
     if (code_seen('H')) {
720
-      hotend_temp = code_value_temp_abs();
721
-      if (!WITHIN(hotend_temp, 165, 280)) {
697
+      g26_hotend_temp = code_value_temp_abs();
698
+      if (!WITHIN(g26_hotend_temp, 165, 280)) {
722
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
699
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
723
         return UBL_ERR;
700
         return UBL_ERR;
724
       }
701
       }
735
       return UBL_ERR;
712
       return UBL_ERR;
736
     }
713
     }
737
 
714
 
738
-    x_pos = code_seen('X') ? code_value_linear_units() : current_position[X_AXIS];
739
-    y_pos = code_seen('Y') ? code_value_linear_units() : current_position[Y_AXIS];
740
-    if (!position_is_reachable_xy(x_pos, y_pos)) {
715
+    g26_x_pos = code_seen('X') ? code_value_linear_units() : current_position[X_AXIS];
716
+    g26_y_pos = code_seen('Y') ? code_value_linear_units() : current_position[Y_AXIS];
717
+    if (!position_is_reachable_xy(g26_x_pos, g26_y_pos)) {
741
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
718
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
742
       return UBL_ERR;
719
       return UBL_ERR;
743
     }
720
     }
745
     /**
722
     /**
746
      * Wait until all parameters are verified before altering the state!
723
      * Wait until all parameters are verified before altering the state!
747
      */
724
      */
748
-    ubl.state.active = !code_seen('D');
725
+    state.active = !code_seen('D');
749
 
726
 
750
     return UBL_OK;
727
     return UBL_OK;
751
   }
728
   }
752
 
729
 
753
-  bool exit_from_g26() {
730
+  bool unified_bed_leveling::exit_from_g26() {
754
     lcd_reset_alert_level();
731
     lcd_reset_alert_level();
755
     lcd_setstatuspgm(PSTR("Leaving G26"));
732
     lcd_setstatuspgm(PSTR("Leaving G26"));
756
     while (ubl_lcd_clicked()) idle();
733
     while (ubl_lcd_clicked()) idle();
761
    * Turn on the bed and nozzle heat and
738
    * Turn on the bed and nozzle heat and
762
    * wait for them to get up to temperature.
739
    * wait for them to get up to temperature.
763
    */
740
    */
764
-  bool turn_on_heaters() {
741
+  bool unified_bed_leveling::turn_on_heaters() {
765
     millis_t next;
742
     millis_t next;
766
     #if HAS_TEMP_BED
743
     #if HAS_TEMP_BED
767
       #if ENABLED(ULTRA_LCD)
744
       #if ENABLED(ULTRA_LCD)
768
-        if (bed_temp > 25) {
745
+        if (g26_bed_temp > 25) {
769
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
746
           lcd_setstatuspgm(PSTR("G26 Heating Bed."), 99);
770
           lcd_quick_feedback();
747
           lcd_quick_feedback();
771
       #endif
748
       #endif
772
-          ubl.has_control_of_lcd_panel = true;
773
-          thermalManager.setTargetBed(bed_temp);
749
+          has_control_of_lcd_panel = true;
750
+          thermalManager.setTargetBed(g26_bed_temp);
774
           next = millis() + 5000UL;
751
           next = millis() + 5000UL;
775
-          while (abs(thermalManager.degBed() - bed_temp) > 3) {
752
+          while (abs(thermalManager.degBed() - g26_bed_temp) > 3) {
776
             if (ubl_lcd_clicked()) return exit_from_g26();
753
             if (ubl_lcd_clicked()) return exit_from_g26();
777
             if (PENDING(millis(), next)) {
754
             if (PENDING(millis(), next)) {
778
               next = millis() + 5000UL;
755
               next = millis() + 5000UL;
788
     #endif
765
     #endif
789
 
766
 
790
     // Start heating the nozzle and wait for it to reach temperature.
767
     // Start heating the nozzle and wait for it to reach temperature.
791
-    thermalManager.setTargetHotend(hotend_temp, 0);
792
-    while (abs(thermalManager.degHotend(0) - hotend_temp) > 3) {
768
+    thermalManager.setTargetHotend(g26_hotend_temp, 0);
769
+    while (abs(thermalManager.degHotend(0) - g26_hotend_temp) > 3) {
793
       if (ubl_lcd_clicked()) return exit_from_g26();
770
       if (ubl_lcd_clicked()) return exit_from_g26();
794
       if (PENDING(millis(), next)) {
771
       if (PENDING(millis(), next)) {
795
         next = millis() + 5000UL;
772
         next = millis() + 5000UL;
810
   /**
787
   /**
811
    * Prime the nozzle if needed. Return true on error.
788
    * Prime the nozzle if needed. Return true on error.
812
    */
789
    */
813
-  bool prime_nozzle() {
790
+  bool unified_bed_leveling::prime_nozzle() {
814
     float Total_Prime = 0.0;
791
     float Total_Prime = 0.0;
815
 
792
 
816
-    if (prime_flag == -1) {  // The user wants to control how much filament gets purged
793
+    if (g26_prime_flag == -1) {  // The user wants to control how much filament gets purged
817
 
794
 
818
-      ubl.has_control_of_lcd_panel = true;
795
+      has_control_of_lcd_panel = true;
819
 
796
 
820
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
797
       lcd_setstatuspgm(PSTR("User-Controlled Prime"), 99);
821
       chirp_at_user();
798
       chirp_at_user();
822
 
799
 
823
       set_destination_to_current();
800
       set_destination_to_current();
824
 
801
 
825
-      un_retract_filament(destination); // Make sure G26 doesn't think the filament is retracted().
802
+      recover_filament(destination); // Make sure G26 doesn't think the filament is retracted().
826
 
803
 
827
       while (!ubl_lcd_clicked()) {
804
       while (!ubl_lcd_clicked()) {
828
         chirp_at_user();
805
         chirp_at_user();
850
         lcd_quick_feedback();
827
         lcd_quick_feedback();
851
       #endif
828
       #endif
852
 
829
 
853
-      ubl.has_control_of_lcd_panel = false;
830
+      has_control_of_lcd_panel = false;
854
 
831
 
855
     }
832
     }
856
     else {
833
     else {
859
         lcd_quick_feedback();
836
         lcd_quick_feedback();
860
       #endif
837
       #endif
861
       set_destination_to_current();
838
       set_destination_to_current();
862
-      destination[E_AXIS] += prime_length;
839
+      destination[E_AXIS] += g26_prime_length;
863
       G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
840
       G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
864
       stepper.synchronize();
841
       stepper.synchronize();
865
       set_destination_to_current();
842
       set_destination_to_current();

+ 14
- 14
Marlin/Marlin_main.cpp View File

2355
    *   - Raise to the BETWEEN height
2355
    *   - Raise to the BETWEEN height
2356
    * - Return the probed Z position
2356
    * - Return the probed Z position
2357
    */
2357
    */
2358
-  float probe_pt(const float x, const float y, const bool stow/*=true*/, const int verbose_level/*=1*/) {
2358
+  float probe_pt(const float &x, const float &y, const bool stow/*=true*/, const int verbose_level/*=1*/) {
2359
     #if ENABLED(DEBUG_LEVELING_FEATURE)
2359
     #if ENABLED(DEBUG_LEVELING_FEATURE)
2360
       if (DEBUGGING(LEVELING)) {
2360
       if (DEBUGGING(LEVELING)) {
2361
         SERIAL_ECHOPAIR(">>> probe_pt(", x);
2361
         SERIAL_ECHOPAIR(">>> probe_pt(", x);
3416
       return;
3416
       return;
3417
     }
3417
     }
3418
 
3418
 
3419
-    destination[X_AXIS] = hasI ? pgm_read_float(&ubl.mesh_index_to_xpos[ix]) : current_position[X_AXIS];
3420
-    destination[Y_AXIS] = hasJ ? pgm_read_float(&ubl.mesh_index_to_ypos[iy]) : current_position[Y_AXIS];
3419
+    destination[X_AXIS] = hasI ? ubl.mesh_index_to_xpos(ix) : current_position[X_AXIS];
3420
+    destination[Y_AXIS] = hasJ ? ubl.mesh_index_to_ypos(iy) : current_position[Y_AXIS];
3421
     destination[Z_AXIS] = current_position[Z_AXIS]; //todo: perhaps add Z-move support?
3421
     destination[Z_AXIS] = current_position[Z_AXIS]; //todo: perhaps add Z-move support?
3422
     destination[E_AXIS] = current_position[E_AXIS];
3422
     destination[E_AXIS] = current_position[E_AXIS];
3423
 
3423
 
5107
      *      P4-P7  Probe all positions at different locations and average them.
5107
      *      P4-P7  Probe all positions at different locations and average them.
5108
      *
5108
      *
5109
      *   T   Don't calibrate tower angle corrections
5109
      *   T   Don't calibrate tower angle corrections
5110
-     *   
5110
+     *
5111
      *   Cn.nn Calibration precision; when omitted calibrates to maximum precision
5111
      *   Cn.nn Calibration precision; when omitted calibrates to maximum precision
5112
-     *   
5112
+     *
5113
      *   Vn  Verbose level:
5113
      *   Vn  Verbose level:
5114
      *
5114
      *
5115
      *      V0  Dry-run mode. Report settings and probe results. No calibration.
5115
      *      V0  Dry-run mode. Report settings and probe results. No calibration.
5229
       #endif
5229
       #endif
5230
 
5230
 
5231
       int8_t iterations = 0;
5231
       int8_t iterations = 0;
5232
-      
5232
+
5233
       home_offset[Z_AXIS] -= probe_pt(0.0, 0.0 , true, 1); // 1st probe to set height
5233
       home_offset[Z_AXIS] -= probe_pt(0.0, 0.0 , true, 1); // 1st probe to set height
5234
       do_probe_raise(Z_CLEARANCE_BETWEEN_PROBES);
5234
       do_probe_raise(Z_CLEARANCE_BETWEEN_PROBES);
5235
 
5235
 
5239
         int16_t N = 0;
5239
         int16_t N = 0;
5240
 
5240
 
5241
         test_precision = zero_std_dev_old != 999.0 ? (zero_std_dev + zero_std_dev_old) / 2 : zero_std_dev;
5241
         test_precision = zero_std_dev_old != 999.0 ? (zero_std_dev + zero_std_dev_old) / 2 : zero_std_dev;
5242
-        
5242
+
5243
         iterations++;
5243
         iterations++;
5244
 
5244
 
5245
         // Probe the points
5245
         // Probe the points
5286
           }
5286
           }
5287
         zero_std_dev_old = zero_std_dev;
5287
         zero_std_dev_old = zero_std_dev;
5288
         zero_std_dev = round(sqrt(S2 / N) * 1000.0) / 1000.0 + 0.00001;
5288
         zero_std_dev = round(sqrt(S2 / N) * 1000.0) / 1000.0 + 0.00001;
5289
-        
5289
+
5290
         if (iterations == 1) home_offset[Z_AXIS] = zh_old; // reset height after 1st probe change
5290
         if (iterations == 1) home_offset[Z_AXIS] = zh_old; // reset height after 1st probe change
5291
 
5291
 
5292
         // Solve matrices
5292
         // Solve matrices
5416
             else {
5416
             else {
5417
               SERIAL_PROTOCOLPGM("std dev:");
5417
               SERIAL_PROTOCOLPGM("std dev:");
5418
               SERIAL_PROTOCOL_F(zero_std_dev, 3);
5418
               SERIAL_PROTOCOL_F(zero_std_dev, 3);
5419
-            }            
5419
+            }
5420
             SERIAL_EOL;
5420
             SERIAL_EOL;
5421
             LCD_MESSAGEPGM("Calibration OK"); // TODO: Make translatable string
5421
             LCD_MESSAGEPGM("Calibration OK"); // TODO: Make translatable string
5422
           }
5422
           }
5481
         home_delta();
5481
         home_delta();
5482
         endstops.not_homing();
5482
         endstops.not_homing();
5483
 
5483
 
5484
-      } 
5484
+      }
5485
       while (zero_std_dev < test_precision && zero_std_dev > calibration_precision && iterations < 31);
5485
       while (zero_std_dev < test_precision && zero_std_dev > calibration_precision && iterations < 31);
5486
 
5486
 
5487
       #if ENABLED(DELTA_HOME_TO_SAFE_ZONE)
5487
       #if ENABLED(DELTA_HOME_TO_SAFE_ZONE)
8704
     const bool hasZ = code_seen('Z'), hasQ = !hasZ && code_seen('Q');
8704
     const bool hasZ = code_seen('Z'), hasQ = !hasZ && code_seen('Q');
8705
 
8705
 
8706
     if (hasC) {
8706
     if (hasC) {
8707
-      const mesh_index_pair location = find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false);
8707
+      const mesh_index_pair location = ubl.find_closest_mesh_point_of_type(REAL, current_position[X_AXIS], current_position[Y_AXIS], USE_NOZZLE_AS_REFERENCE, NULL, false);
8708
       ix = location.x_index;
8708
       ix = location.x_index;
8709
       iy = location.y_index;
8709
       iy = location.y_index;
8710
     }
8710
     }
11467
     #if ENABLED(AUTO_BED_LEVELING_UBL)
11467
     #if ENABLED(AUTO_BED_LEVELING_UBL)
11468
       const float fr_scaled = MMS_SCALED(feedrate_mm_s);
11468
       const float fr_scaled = MMS_SCALED(feedrate_mm_s);
11469
       if (ubl.state.active) {
11469
       if (ubl.state.active) {
11470
-        ubl_line_to_destination_cartesian(fr_scaled, active_extruder);
11470
+        ubl.line_to_destination_cartesian(fr_scaled, active_extruder);
11471
         return true;
11471
         return true;
11472
       }
11472
       }
11473
       else
11473
       else
11612
   if (
11612
   if (
11613
     #if IS_KINEMATIC
11613
     #if IS_KINEMATIC
11614
       #if UBL_DELTA
11614
       #if UBL_DELTA
11615
-        ubl_prepare_linear_move_to(destination, feedrate_mm_s)
11615
+        ubl.prepare_linear_move_to(destination, feedrate_mm_s)
11616
       #else
11616
       #else
11617
         prepare_kinematic_move_to(destination)
11617
         prepare_kinematic_move_to(destination)
11618
       #endif
11618
       #endif
11619
     #elif ENABLED(DUAL_X_CARRIAGE)
11619
     #elif ENABLED(DUAL_X_CARRIAGE)
11620
       prepare_move_to_destination_dualx()
11620
       prepare_move_to_destination_dualx()
11621
     #elif UBL_DELTA // will work for CARTESIAN too (smaller segments follow mesh more closely)
11621
     #elif UBL_DELTA // will work for CARTESIAN too (smaller segments follow mesh more closely)
11622
-      ubl_prepare_linear_move_to(destination, feedrate_mm_s)
11622
+      ubl.prepare_linear_move_to(destination, feedrate_mm_s)
11623
     #else
11623
     #else
11624
       prepare_move_to_destination_cartesian()
11624
       prepare_move_to_destination_cartesian()
11625
     #endif
11625
     #endif

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

903
   #define UBL_PROBE_PT_3_Y 20
903
   #define UBL_PROBE_PT_3_Y 20
904
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
904
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
905
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
905
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
906
- 
906
+
907
 #elif ENABLED(MESH_BED_LEVELING)
907
 #elif ENABLED(MESH_BED_LEVELING)
908
 
908
 
909
   //===========================================================================
909
   //===========================================================================

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

907
   #define UBL_PROBE_PT_3_Y 20
907
   #define UBL_PROBE_PT_3_Y 20
908
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
908
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
909
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
909
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
910
- 
910
+
911
 #elif ENABLED(MESH_BED_LEVELING)
911
 #elif ENABLED(MESH_BED_LEVELING)
912
 
912
 
913
   //===========================================================================
913
   //===========================================================================

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

943
   #define UBL_PROBE_PT_3_Y 20
943
   #define UBL_PROBE_PT_3_Y 20
944
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
944
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
945
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
945
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
946
- 
946
+
947
 #elif ENABLED(MESH_BED_LEVELING)
947
 #elif ENABLED(MESH_BED_LEVELING)
948
 
948
 
949
   //===========================================================================
949
   //===========================================================================

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

878
   #define UBL_PROBE_PT_3_Y 20
878
   #define UBL_PROBE_PT_3_Y 20
879
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
879
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
880
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
880
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
881
- 
881
+
882
 #elif ENABLED(MESH_BED_LEVELING)
882
 #elif ENABLED(MESH_BED_LEVELING)
883
 
883
 
884
   //===========================================================================
884
   //===========================================================================

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

883
   #define UBL_PROBE_PT_3_Y 20
883
   #define UBL_PROBE_PT_3_Y 20
884
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
884
   #define UBL_G26_MESH_VALIDATION   // Enable G26 mesh validation
885
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
885
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
886
- 
886
+
887
 #elif ENABLED(MESH_BED_LEVELING)
887
 #elif ENABLED(MESH_BED_LEVELING)
888
 
888
 
889
   //===========================================================================
889
   //===========================================================================

+ 10
- 8
Marlin/fastio.h View File

21
  */
21
  */
22
 
22
 
23
 /**
23
 /**
24
- * Contributed by Triffid_Hunter, modified by Kliment, extended by the Marlin team
25
- * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
24
+ * Fast I/O Routines
25
+ * Use direct port manipulation to save scads of processor time.
26
+ * Contributed by Triffid_Hunter. Modified by Kliment and the Marlin team.
26
  */
27
  */
27
 
28
 
28
-#ifndef _FASTIO_ARDUINO_H
29
+#ifndef _FASTIO_ARDUINO_H 
29
 #define _FASTIO_ARDUINO_H
30
 #define _FASTIO_ARDUINO_H
30
 
31
 
31
 #include <avr/io.h>
32
 #include <avr/io.h>
32
 
33
 
33
 /**
34
 /**
34
- * Include Ports and Functions
35
- */
36
-
37
-/**
38
  * Enable this option to use Teensy++ 2.0 assignments for AT90USB processors.
35
  * Enable this option to use Teensy++ 2.0 assignments for AT90USB processors.
39
  */
36
  */
40
 //#define AT90USBxx_TEENSYPP_ASSIGNMENTS
37
 //#define AT90USBxx_TEENSYPP_ASSIGNMENTS
41
 
38
 
39
+/**
40
+ * Include Ports and Functions
41
+ */
42
 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
42
 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
43
   #include "fastio_168.h"
43
   #include "fastio_168.h"
44
 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
44
 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
58
 #endif
58
 #endif
59
 
59
 
60
 #ifndef _BV
60
 #ifndef _BV
61
-  #define _BV(PIN) (1 << PIN)
61
+  #define _BV(PIN) (1UL << PIN)
62
 #endif
62
 #endif
63
 
63
 
64
 /**
64
 /**
65
  * Magic I/O routines
65
  * Magic I/O routines
66
  *
66
  *
67
  * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
67
  * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
68
+ *
69
+ * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
68
  */
70
  */
69
 
71
 
70
 #define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN)))
72
 #define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN)))

+ 0
- 1
Marlin/fastio_AT90USB-Teensy.h View File

679
 #define PF7_PWM     NULL
679
 #define PF7_PWM     NULL
680
 #define PF7_DDR     DDRF
680
 #define PF7_DDR     DDRF
681
 
681
 
682
-#endif // AT90USBxx_TEENSYPP_ASSIGNMENTS Teensyduino assignments
683
 #endif // _FASTIO_AT90USB
682
 #endif // _FASTIO_AT90USB

+ 4
- 4
Marlin/least_squares_fit.h View File

52
   memset(lsf, 0, sizeof(linear_fit_data));
52
   memset(lsf, 0, sizeof(linear_fit_data));
53
 }
53
 }
54
 
54
 
55
-void inline incremental_WLSF(struct linear_fit_data *lsf, float x, float y, float z, float w) {
55
+void inline incremental_WLSF(struct linear_fit_data *lsf, const float &x, const float &y, const float &z, const float &w) {
56
   // weight each accumulator by factor w, including the "number" of samples
56
   // weight each accumulator by factor w, including the "number" of samples
57
   // (analagous to calling inc_LSF twice with same values to weight it by 2X)
57
   // (analagous to calling inc_LSF twice with same values to weight it by 2X)
58
   lsf->xbar  += w * x;
58
   lsf->xbar  += w * x;
65
   lsf->xzbar += w * x * z;
65
   lsf->xzbar += w * x * z;
66
   lsf->yzbar += w * y * z;
66
   lsf->yzbar += w * y * z;
67
   lsf->N     += w;
67
   lsf->N     += w;
68
-  lsf->max_absx = max(fabs( w * x ), lsf->max_absx);
69
-  lsf->max_absy = max(fabs( w * y ), lsf->max_absy);
68
+  lsf->max_absx = max(fabs(w * x), lsf->max_absx);
69
+  lsf->max_absy = max(fabs(w * y), lsf->max_absy);
70
 }
70
 }
71
 
71
 
72
-void inline incremental_LSF(struct linear_fit_data *lsf, float x, float y, float z) {
72
+void inline incremental_LSF(struct linear_fit_data *lsf, const float &x, const float &y, const float &z) {
73
   lsf->xbar += x;
73
   lsf->xbar += x;
74
   lsf->ybar += y;
74
   lsf->ybar += y;
75
   lsf->zbar += z;
75
   lsf->zbar += z;

+ 6
- 6
Marlin/macros.h View File

29
 #define XYZ  3
29
 #define XYZ  3
30
 
30
 
31
 #define FORCE_INLINE __attribute__((always_inline)) inline
31
 #define FORCE_INLINE __attribute__((always_inline)) inline
32
-
33
-#define _O0 __attribute__((optimize("O0")))
34
-#define _Os __attribute__((optimize("Os")))
35
-#define _O1 __attribute__((optimize("O1")))
36
-#define _O2 __attribute__((optimize("O2")))
37
-#define _O3 __attribute__((optimize("O3")))
32
+#define _UNUSED      __attribute__((unused))
33
+#define _O0          __attribute__((optimize("O0")))
34
+#define _Os          __attribute__((optimize("Os")))
35
+#define _O1          __attribute__((optimize("O1")))
36
+#define _O2          __attribute__((optimize("O2")))
37
+#define _O3          __attribute__((optimize("O3")))
38
 
38
 
39
 // Bracket code that shouldn't be interrupted
39
 // Bracket code that shouldn't be interrupted
40
 #ifndef CRITICAL_SECTION_START
40
 #ifndef CRITICAL_SECTION_START

+ 16
- 16
Marlin/nozzle.cpp View File

12
   * @param strokes number of strokes to execute
12
   * @param strokes number of strokes to execute
13
   */
13
   */
14
 void Nozzle::stroke(
14
 void Nozzle::stroke(
15
-  __attribute__((unused)) point_t const &start,
16
-  __attribute__((unused)) point_t const &end,
17
-  __attribute__((unused)) uint8_t const &strokes
15
+  _UNUSED point_t const &start,
16
+  _UNUSED point_t const &end,
17
+  _UNUSED uint8_t const &strokes
18
 ) {
18
 ) {
19
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
19
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
20
 
20
 
56
   * @param objects number of objects to create
56
   * @param objects number of objects to create
57
   */
57
   */
58
 void Nozzle::zigzag(
58
 void Nozzle::zigzag(
59
-  __attribute__((unused)) point_t const &start,
60
-  __attribute__((unused)) point_t const &end,
61
-  __attribute__((unused)) uint8_t const &strokes,
62
-  __attribute__((unused)) uint8_t const &objects
59
+  _UNUSED point_t const &start,
60
+  _UNUSED point_t const &end,
61
+  _UNUSED uint8_t const &strokes,
62
+  _UNUSED uint8_t const &objects
63
 ) {
63
 ) {
64
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
64
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
65
     const float A = nozzle_clean_horizontal ? nozzle_clean_height : nozzle_clean_length, // [twice the] Amplitude
65
     const float A = nozzle_clean_horizontal ? nozzle_clean_height : nozzle_clean_length, // [twice the] Amplitude
114
   * @param radius radius of circle
114
   * @param radius radius of circle
115
   */
115
   */
116
 void Nozzle::circle(
116
 void Nozzle::circle(
117
-  __attribute__((unused)) point_t const &start,
118
-  __attribute__((unused)) point_t const &middle,
119
-  __attribute__((unused)) uint8_t const &strokes,
120
-  __attribute__((unused)) float const &radius
117
+  _UNUSED point_t const &start,
118
+  _UNUSED point_t const &middle,
119
+  _UNUSED uint8_t const &strokes,
120
+  _UNUSED float const &radius
121
 ) {
121
 ) {
122
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
122
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
123
     if (strokes == 0) return;
123
     if (strokes == 0) return;
177
   * @param argument depends on the cleaning pattern
177
   * @param argument depends on the cleaning pattern
178
   */
178
   */
179
 void Nozzle::clean(
179
 void Nozzle::clean(
180
-  __attribute__((unused)) uint8_t const &pattern,
181
-  __attribute__((unused)) uint8_t const &strokes,
182
-  __attribute__((unused)) float const &radius,
183
-  __attribute__((unused)) uint8_t const &objects
180
+  _UNUSED uint8_t const &pattern,
181
+  _UNUSED uint8_t const &strokes,
182
+  _UNUSED float const &radius,
183
+  _UNUSED uint8_t const &objects
184
 ) {
184
 ) {
185
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
185
   #if ENABLED(NOZZLE_CLEAN_FEATURE)
186
     #if ENABLED(DELTA)
186
     #if ENABLED(DELTA)
209
 }
209
 }
210
 
210
 
211
 void Nozzle::park(
211
 void Nozzle::park(
212
-  __attribute__((unused)) uint8_t const &z_action
212
+  _UNUSED uint8_t const &z_action
213
 ) {
213
 ) {
214
   #if ENABLED(NOZZLE_PARK_FEATURE)
214
   #if ENABLED(NOZZLE_PARK_FEATURE)
215
     float const z = current_position[Z_AXIS];
215
     float const z = current_position[Z_AXIS];

+ 21
- 21
Marlin/nozzle.h View File

50
      * @param strokes number of strokes to execute
50
      * @param strokes number of strokes to execute
51
      */
51
      */
52
     static void stroke(
52
     static void stroke(
53
-      __attribute__((unused)) point_t const &start,
54
-      __attribute__((unused)) point_t const &end,
55
-      __attribute__((unused)) uint8_t const &strokes
56
-    ) __attribute__((optimize ("Os")));
53
+      _UNUSED point_t const &start,
54
+      _UNUSED point_t const &end,
55
+      _UNUSED uint8_t const &strokes
56
+    ) _Os;
57
 
57
 
58
     /**
58
     /**
59
      * @brief Zig-zag clean pattern
59
      * @brief Zig-zag clean pattern
65
      * @param objects number of objects to create
65
      * @param objects number of objects to create
66
      */
66
      */
67
     static void zigzag(
67
     static void zigzag(
68
-      __attribute__((unused)) point_t const &start,
69
-      __attribute__((unused)) point_t const &end,
70
-      __attribute__((unused)) uint8_t const &strokes,
71
-      __attribute__((unused)) uint8_t const &objects
72
-    ) __attribute__((optimize ("Os")));
68
+      _UNUSED point_t const &start,
69
+      _UNUSED point_t const &end,
70
+      _UNUSED uint8_t const &strokes,
71
+      _UNUSED uint8_t const &objects
72
+    ) _Os;
73
 
73
 
74
     /**
74
     /**
75
      * @brief Circular clean pattern
75
      * @brief Circular clean pattern
80
      * @param radius radius of circle
80
      * @param radius radius of circle
81
      */
81
      */
82
     static void circle(
82
     static void circle(
83
-      __attribute__((unused)) point_t const &start,
84
-      __attribute__((unused)) point_t const &middle,
85
-      __attribute__((unused)) uint8_t const &strokes,
86
-      __attribute__((unused)) float const &radius
87
-    ) __attribute__((optimize ("Os")));
83
+      _UNUSED point_t const &start,
84
+      _UNUSED point_t const &middle,
85
+      _UNUSED uint8_t const &strokes,
86
+      _UNUSED float const &radius
87
+    ) _Os;
88
 
88
 
89
   public:
89
   public:
90
     /**
90
     /**
95
      * @param argument depends on the cleaning pattern
95
      * @param argument depends on the cleaning pattern
96
      */
96
      */
97
     static void clean(
97
     static void clean(
98
-      __attribute__((unused)) uint8_t const &pattern,
99
-      __attribute__((unused)) uint8_t const &strokes,
100
-      __attribute__((unused)) float const &radius,
101
-      __attribute__((unused)) uint8_t const &objects = 0
102
-    ) __attribute__((optimize ("Os")));
98
+      _UNUSED uint8_t const &pattern,
99
+      _UNUSED uint8_t const &strokes,
100
+      _UNUSED float const &radius,
101
+      _UNUSED uint8_t const &objects = 0
102
+    ) _Os;
103
 
103
 
104
     static void park(
104
     static void park(
105
-      __attribute__((unused)) uint8_t const &z_action
106
-    ) __attribute__((optimize ("Os")));
105
+      _UNUSED uint8_t const &z_action
106
+    ) _Os;
107
 };
107
 };
108
 
108
 
109
 #endif
109
 #endif

+ 10
- 21
Marlin/spi.h View File

27
 #include "softspi.h"
27
 #include "softspi.h"
28
 
28
 
29
 template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
29
 template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
30
-class Spi {
31
-  static SoftSPI<MisoPin, MosiPin, SckPin> softSpi;
30
+class SPI {
31
+  static SoftSPI<MisoPin, MosiPin, SckPin> softSPI;
32
   public:
32
   public:
33
-    inline __attribute__((always_inline))
34
-    static void init() {
35
-        softSpi.begin();
36
-    }
37
-    inline __attribute__((always_inline))
38
-    static void send(uint8_t data) {
39
-        softSpi.send(data);
40
-    }
41
-    inline __attribute__((always_inline))
42
-    static uint8_t receive() {
43
-        return softSpi.receive();
44
-    }
33
+    FORCE_INLINE static void init() { softSPI.begin(); }
34
+    FORCE_INLINE static void send(uint8_t data) { softSPI.send(data); }
35
+    FORCE_INLINE static uint8_t receive() { return softSPI.receive(); }
45
 };
36
 };
46
 
37
 
47
 
38
 
48
-//hardware spi
39
+// Hardware SPI
49
 template<>
40
 template<>
50
-class Spi<MISO_PIN, MOSI_PIN, SCK_PIN> {
41
+class SPI<MISO_PIN, MOSI_PIN, SCK_PIN> {
51
   public:
42
   public:
52
-    inline __attribute__((always_inline))
53
-    static void init() {
43
+    FORCE_INLINE static void init() {
54
         OUT_WRITE(SCK_PIN, LOW);
44
         OUT_WRITE(SCK_PIN, LOW);
55
         OUT_WRITE(MOSI_PIN, HIGH);
45
         OUT_WRITE(MOSI_PIN, HIGH);
56
         SET_INPUT(MISO_PIN);
46
         SET_INPUT(MISO_PIN);
57
         WRITE(MISO_PIN, HIGH);
47
         WRITE(MISO_PIN, HIGH);
58
     }
48
     }
59
-    inline __attribute__((always_inline))
60
-    static uint8_t receive() {
49
+    FORCE_INLINE static uint8_t receive() {
61
       SPDR = 0;
50
       SPDR = 0;
62
       for (;!TEST(SPSR, SPIF););
51
       for (;!TEST(SPSR, SPIF););
63
       return SPDR;
52
       return SPDR;
65
 
54
 
66
 };
55
 };
67
 
56
 
68
-#endif
57
+#endif // __SPI_H__

+ 1
- 1
Marlin/temperature.cpp View File

935
   #ifndef MAX6675_DO_PIN
935
   #ifndef MAX6675_DO_PIN
936
     #define MAX6675_DO_PIN MISO_PIN
936
     #define MAX6675_DO_PIN MISO_PIN
937
   #endif
937
   #endif
938
-  Spi<MAX6675_DO_PIN, MOSI_PIN, MAX6675_SCK_PIN> max6675_spi;
938
+  SPI<MAX6675_DO_PIN, MOSI_PIN, MAX6675_SCK_PIN> max6675_spi;
939
 #endif
939
 #endif
940
 
940
 
941
 /**
941
 /**

+ 1
- 2
Marlin/temperature.h View File

288
     /**
288
     /**
289
      * Call periodically to manage heaters
289
      * Call periodically to manage heaters
290
      */
290
      */
291
-    //static void manage_heater(); // changed to address compiler error
292
-    static void manage_heater()  __attribute__((__optimize__("O2")));
291
+    static void manage_heater() _O2; // Added _O2 to work around a compiler error
293
 
292
 
294
     /**
293
     /**
295
      * Preheating hotends
294
      * Preheating hotends

+ 4
- 4
Marlin/ubl.cpp View File

69
 
69
 
70
   // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
70
   // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
71
   // until determinism prevails
71
   // until determinism prevails
72
-  constexpr float unified_bed_leveling::mesh_index_to_xpos[16],
73
-                  unified_bed_leveling::mesh_index_to_ypos[16];
72
+  constexpr float unified_bed_leveling::_mesh_index_to_xpos[16],
73
+                  unified_bed_leveling::_mesh_index_to_ypos[16];
74
 
74
 
75
   bool unified_bed_leveling::g26_debug_flag = false,
75
   bool unified_bed_leveling::g26_debug_flag = false,
76
        unified_bed_leveling::has_control_of_lcd_panel = false;
76
        unified_bed_leveling::has_control_of_lcd_panel = false;
117
       SERIAL_EOL;
117
       SERIAL_EOL;
118
     }
118
     }
119
 
119
 
120
-    const float current_xi = ubl.get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0),
121
-                current_yi = ubl.get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0);
120
+    const float current_xi = get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0),
121
+                current_yi = get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0);
122
 
122
 
123
     for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
123
     for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
124
       for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
124
       for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {

+ 106
- 55
Marlin/ubl.h View File

53
   // ubl_motion.cpp
53
   // ubl_motion.cpp
54
 
54
 
55
   void debug_current_and_destination(const char * const title);
55
   void debug_current_and_destination(const char * const title);
56
-  void ubl_line_to_destination_cartesian(const float&, uint8_t);
57
-  bool ubl_prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate );
58
 
56
 
59
   // ubl_G29.cpp
57
   // ubl_G29.cpp
60
 
58
 
61
   enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
59
   enum MeshPointType { INVALID, REAL, SET_IN_BITMAP };
62
 
60
 
63
-  void dump(char * const str, const float &f);
64
-  void probe_entire_mesh(const float&, const float&, const bool, const bool, const bool);
65
-  float measure_business_card_thickness(float&);
66
-  mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, unsigned int[16], bool);
67
-  void shift_mesh_height();
68
-  void fine_tune_mesh(const float&, const float&, const bool);
69
-  bool g29_parameter_parsing();
70
-  void g29_eeprom_dump();
71
-  void g29_compare_current_mesh_to_stored_mesh();
72
-
73
   // External references
61
   // External references
74
 
62
 
75
   char *ftostr43sign(const float&, char);
63
   char *ftostr43sign(const float&, char);
76
   bool ubl_lcd_clicked();
64
   bool ubl_lcd_clicked();
77
   void home_all_axes();
65
   void home_all_axes();
78
-  void gcode_G26();
79
-  void gcode_G29();
80
 
66
 
81
   extern uint8_t ubl_cnt;
67
   extern uint8_t ubl_cnt;
82
 
68
 
101
 
87
 
102
       static float last_specified_z;
88
       static float last_specified_z;
103
 
89
 
90
+      static int    g29_verbose_level,
91
+                    g29_phase_value,
92
+                    g29_repetition_cnt,
93
+                    g29_storage_slot,
94
+                    g29_map_type,
95
+                    g29_grid_size;
96
+      static bool   g29_c_flag, g29_x_flag, g29_y_flag;
97
+      static float  g29_x_pos, g29_y_pos,
98
+                    g29_card_thickness,
99
+                    g29_constant;
100
+
101
+      #if ENABLED(UBL_G26_MESH_VALIDATION)
102
+        static float   g26_extrusion_multiplier,
103
+                       g26_retraction_multiplier,
104
+                       g26_nozzle,
105
+                       g26_filament_diameter,
106
+                       g26_prime_length,
107
+                       g26_x_pos, g26_y_pos,
108
+                       g26_ooze_amount,
109
+                       g26_layer_height;
110
+        static int16_t g26_bed_temp,
111
+                       g26_hotend_temp,
112
+                       g26_repeats;
113
+        static int8_t  g26_prime_flag;
114
+        static bool    g26_continue_with_closest, g26_keep_heaters_on;
115
+      #endif
116
+
117
+      static float measure_point_with_encoder();
118
+      static float measure_business_card_thickness(float&);
119
+      static bool g29_parameter_parsing();
120
+      static void find_mean_mesh_height();
121
+      static void shift_mesh_height();
122
+      static void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
123
+      static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool);
124
+      static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
125
+      static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
126
+      static void g29_what_command();
127
+      static void g29_eeprom_dump();
128
+      static void g29_compare_current_mesh_to_stored_mesh();
129
+      static void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map);
130
+      static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
131
+      static void smart_fill_mesh();
132
+
133
+      #if ENABLED(UBL_G26_MESH_VALIDATION)
134
+        static bool exit_from_g26();
135
+        static bool parse_G26_parameters();
136
+        static void G26_line_to_destination(const float &feed_rate);
137
+        static mesh_index_pair find_closest_circle_to_print(const float&, const float&);
138
+        static bool look_for_lines_to_connect();
139
+        static bool turn_on_heaters();
140
+        static bool prime_nozzle();
141
+        static void retract_filament(float where[XYZE]);
142
+        static void recover_filament(float where[XYZE]);
143
+        static void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&);
144
+        static void move_to(const float&, const float&, const float&, const float&);
145
+      #endif
146
+
104
     public:
147
     public:
105
 
148
 
106
-      void echo_name();
107
-      void report_state();
108
-      void find_mean_mesh_height();
109
-      void shift_mesh_height();
110
-      void probe_entire_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
111
-      void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
112
-      void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
113
-      void save_ubl_active_state_and_disable();
114
-      void restore_ubl_active_state_and_leave();
115
-      void g29_what_command();
116
-      void g29_eeprom_dump();
117
-      void g29_compare_current_mesh_to_stored_mesh();
118
-      void fine_tune_mesh(const float &lx, const float &ly, const bool do_ubl_mesh_map);
119
-      void smart_fill_mesh();
120
-      void display_map(const int);
121
-      void reset();
122
-      void invalidate();
123
-      bool sanity_check();
149
+      static void echo_name();
150
+      static void report_state();
151
+      static void save_ubl_active_state_and_disable();
152
+      static void restore_ubl_active_state_and_leave();
153
+      static void display_map(const int);
154
+      static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, unsigned int[16], bool);
155
+      static void reset();
156
+      static void invalidate();
157
+      static bool sanity_check();
158
+
159
+      static void G29() _O0;                          // O0 for no optimization
160
+      static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560
161
+
162
+      #if ENABLED(UBL_G26_MESH_VALIDATION)
163
+        static void G26();
164
+      #endif
124
 
165
 
125
       static ubl_state state;
166
       static ubl_state state;
126
 
167
 
128
 
169
 
129
       // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
170
       // 15 is the maximum nubmer of grid points supported + 1 safety margin for now,
130
       // until determinism prevails
171
       // until determinism prevails
131
-      constexpr static float mesh_index_to_xpos[16] PROGMEM = {
172
+      constexpr static float _mesh_index_to_xpos[16] PROGMEM = {
132
                                 UBL_MESH_MIN_X +  0 * (MESH_X_DIST), UBL_MESH_MIN_X +  1 * (MESH_X_DIST),
173
                                 UBL_MESH_MIN_X +  0 * (MESH_X_DIST), UBL_MESH_MIN_X +  1 * (MESH_X_DIST),
133
                                 UBL_MESH_MIN_X +  2 * (MESH_X_DIST), UBL_MESH_MIN_X +  3 * (MESH_X_DIST),
174
                                 UBL_MESH_MIN_X +  2 * (MESH_X_DIST), UBL_MESH_MIN_X +  3 * (MESH_X_DIST),
134
                                 UBL_MESH_MIN_X +  4 * (MESH_X_DIST), UBL_MESH_MIN_X +  5 * (MESH_X_DIST),
175
                                 UBL_MESH_MIN_X +  4 * (MESH_X_DIST), UBL_MESH_MIN_X +  5 * (MESH_X_DIST),
139
                                 UBL_MESH_MIN_X + 14 * (MESH_X_DIST), UBL_MESH_MIN_X + 15 * (MESH_X_DIST)
180
                                 UBL_MESH_MIN_X + 14 * (MESH_X_DIST), UBL_MESH_MIN_X + 15 * (MESH_X_DIST)
140
                               };
181
                               };
141
 
182
 
142
-      constexpr static float mesh_index_to_ypos[16] PROGMEM = {
183
+      constexpr static float _mesh_index_to_ypos[16] PROGMEM = {
143
                                 UBL_MESH_MIN_Y +  0 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  1 * (MESH_Y_DIST),
184
                                 UBL_MESH_MIN_Y +  0 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  1 * (MESH_Y_DIST),
144
                                 UBL_MESH_MIN_Y +  2 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  3 * (MESH_Y_DIST),
185
                                 UBL_MESH_MIN_Y +  2 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  3 * (MESH_Y_DIST),
145
                                 UBL_MESH_MIN_Y +  4 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  5 * (MESH_Y_DIST),
186
                                 UBL_MESH_MIN_Y +  4 * (MESH_Y_DIST), UBL_MESH_MIN_Y +  5 * (MESH_Y_DIST),
156
 
197
 
157
       unified_bed_leveling();
198
       unified_bed_leveling();
158
 
199
 
159
-      FORCE_INLINE void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
200
+      FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const float &z) { z_values[px][py] = z; }
160
 
201
 
161
-      int8_t get_cell_index_x(const float &x) {
202
+      static int8_t get_cell_index_x(const float &x) {
162
         const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
203
         const int8_t cx = (x - (UBL_MESH_MIN_X)) * (1.0 / (MESH_X_DIST));
163
         return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1);   // -1 is appropriate if we want all movement to the X_MAX
204
         return constrain(cx, 0, (GRID_MAX_POINTS_X) - 1);   // -1 is appropriate if we want all movement to the X_MAX
164
       }                                                     // position. But with this defined this way, it is possible
205
       }                                                     // position. But with this defined this way, it is possible
165
                                                             // to extrapolate off of this point even further out. Probably
206
                                                             // to extrapolate off of this point even further out. Probably
166
                                                             // that is OK because something else should be keeping that from
207
                                                             // that is OK because something else should be keeping that from
167
                                                             // happening and should not be worried about at this level.
208
                                                             // happening and should not be worried about at this level.
168
-      int8_t get_cell_index_y(const float &y) {
209
+      static int8_t get_cell_index_y(const float &y) {
169
         const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
210
         const int8_t cy = (y - (UBL_MESH_MIN_Y)) * (1.0 / (MESH_Y_DIST));
170
         return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
211
         return constrain(cy, 0, (GRID_MAX_POINTS_Y) - 1);   // -1 is appropriate if we want all movement to the Y_MAX
171
       }                                                     // position. But with this defined this way, it is possible
212
       }                                                     // position. But with this defined this way, it is possible
173
                                                             // that is OK because something else should be keeping that from
214
                                                             // that is OK because something else should be keeping that from
174
                                                             // happening and should not be worried about at this level.
215
                                                             // happening and should not be worried about at this level.
175
 
216
 
176
-      int8_t find_closest_x_index(const float &x) {
217
+      static int8_t find_closest_x_index(const float &x) {
177
         const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
218
         const int8_t px = (x - (UBL_MESH_MIN_X) + (MESH_X_DIST) * 0.5) * (1.0 / (MESH_X_DIST));
178
         return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
219
         return WITHIN(px, 0, GRID_MAX_POINTS_X - 1) ? px : -1;
179
       }
220
       }
180
 
221
 
181
-      int8_t find_closest_y_index(const float &y) {
222
+      static int8_t find_closest_y_index(const float &y) {
182
         const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
223
         const int8_t py = (y - (UBL_MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * (1.0 / (MESH_Y_DIST));
183
         return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
224
         return WITHIN(py, 0, GRID_MAX_POINTS_Y - 1) ? py : -1;
184
       }
225
       }
198
        *  It is fairly expensive with its 4 floating point additions and 2 floating point
239
        *  It is fairly expensive with its 4 floating point additions and 2 floating point
199
        *  multiplications.
240
        *  multiplications.
200
        */
241
        */
201
-      FORCE_INLINE float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
242
+      FORCE_INLINE static float calc_z0(const float &a0, const float &a1, const float &z1, const float &a2, const float &z2) {
202
         return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
243
         return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1);
203
       }
244
       }
204
 
245
 
206
        * z_correction_for_x_on_horizontal_mesh_line is an optimization for
247
        * z_correction_for_x_on_horizontal_mesh_line is an optimization for
207
        * the rare occasion when a point lies exactly on a Mesh line (denoted by index yi).
248
        * the rare occasion when a point lies exactly on a Mesh line (denoted by index yi).
208
        */
249
        */
209
-      inline float z_correction_for_x_on_horizontal_mesh_line(const float &lx0, const int x1_i, const int yi) {
250
+      inline static float z_correction_for_x_on_horizontal_mesh_line(const float &lx0, const int x1_i, const int yi) {
210
         if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
251
         if (!WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(yi, 0, GRID_MAX_POINTS_Y - 1)) {
211
           serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") );
252
           serialprintPGM( !WITHIN(x1_i, 0, GRID_MAX_POINTS_X - 1) ? PSTR("x1l_i") : PSTR("yi") );
212
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0);
253
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(lx0=", lx0);
217
           return NAN;
258
           return NAN;
218
         }
259
         }
219
 
260
 
220
-        const float xratio = (RAW_X_POSITION(lx0) - pgm_read_float(&mesh_index_to_xpos[x1_i])) * (1.0 / (MESH_X_DIST)),
261
+        const float xratio = (RAW_X_POSITION(lx0) - mesh_index_to_xpos(x1_i)) * (1.0 / (MESH_X_DIST)),
221
                     z1 = z_values[x1_i][yi];
262
                     z1 = z_values[x1_i][yi];
222
 
263
 
223
         return z1 + xratio * (z_values[x1_i + 1][yi] - z1);
264
         return z1 + xratio * (z_values[x1_i + 1][yi] - z1);
226
       //
267
       //
227
       // See comments above for z_correction_for_x_on_horizontal_mesh_line
268
       // See comments above for z_correction_for_x_on_horizontal_mesh_line
228
       //
269
       //
229
-      inline float z_correction_for_y_on_vertical_mesh_line(const float &ly0, const int xi, const int y1_i) {
270
+      inline static float z_correction_for_y_on_vertical_mesh_line(const float &ly0, const int xi, const int y1_i) {
230
         if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) {
271
         if (!WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(y1_i, 0, GRID_MAX_POINTS_Y - 1)) {
231
           serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") );
272
           serialprintPGM( !WITHIN(xi, 0, GRID_MAX_POINTS_X - 1) ? PSTR("xi") : PSTR("yl_i") );
232
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0);
273
           SERIAL_ECHOPAIR(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ly0=", ly0);
237
           return NAN;
278
           return NAN;
238
         }
279
         }
239
 
280
 
240
-        const float yratio = (RAW_Y_POSITION(ly0) - pgm_read_float(&mesh_index_to_ypos[y1_i])) * (1.0 / (MESH_Y_DIST)),
281
+        const float yratio = (RAW_Y_POSITION(ly0) - mesh_index_to_ypos(y1_i)) * (1.0 / (MESH_Y_DIST)),
241
                     z1 = z_values[xi][y1_i];
282
                     z1 = z_values[xi][y1_i];
242
 
283
 
243
         return z1 + yratio * (z_values[xi][y1_i + 1] - z1);
284
         return z1 + yratio * (z_values[xi][y1_i + 1] - z1);
249
        * Z-Height at both ends. Then it does a linear interpolation of these heights based
290
        * Z-Height at both ends. Then it does a linear interpolation of these heights based
250
        * on the Y position within the cell.
291
        * on the Y position within the cell.
251
        */
292
        */
252
-      float get_z_correction(const float &lx0, const float &ly0) {
293
+      static float get_z_correction(const float &lx0, const float &ly0) {
253
         const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)),
294
         const int8_t cx = get_cell_index_x(RAW_X_POSITION(lx0)),
254
                      cy = get_cell_index_y(RAW_Y_POSITION(ly0));
295
                      cy = get_cell_index_y(RAW_Y_POSITION(ly0));
255
 
296
 
268
         }
309
         }
269
 
310
 
270
         const float z1 = calc_z0(RAW_X_POSITION(lx0),
311
         const float z1 = calc_z0(RAW_X_POSITION(lx0),
271
-                                 pgm_read_float(&mesh_index_to_xpos[cx]), z_values[cx][cy],
272
-                                 pgm_read_float(&mesh_index_to_xpos[cx + 1]), z_values[cx + 1][cy]);
312
+                                 mesh_index_to_xpos(cx), z_values[cx][cy],
313
+                                 mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy]);
273
 
314
 
274
         const float z2 = calc_z0(RAW_X_POSITION(lx0),
315
         const float z2 = calc_z0(RAW_X_POSITION(lx0),
275
-                                 pgm_read_float(&mesh_index_to_xpos[cx]), z_values[cx][cy + 1],
276
-                                 pgm_read_float(&mesh_index_to_xpos[cx + 1]), z_values[cx + 1][cy + 1]);
316
+                                 mesh_index_to_xpos(cx), z_values[cx][cy + 1],
317
+                                 mesh_index_to_xpos(cx + 1), z_values[cx + 1][cy + 1]);
277
 
318
 
278
         float z0 = calc_z0(RAW_Y_POSITION(ly0),
319
         float z0 = calc_z0(RAW_Y_POSITION(ly0),
279
-                           pgm_read_float(&mesh_index_to_ypos[cy]), z1,
280
-                           pgm_read_float(&mesh_index_to_ypos[cy + 1]), z2);
320
+                           mesh_index_to_ypos(cy), z1,
321
+                           mesh_index_to_ypos(cy + 1), z2);
281
 
322
 
282
         #if ENABLED(DEBUG_LEVELING_FEATURE)
323
         #if ENABLED(DEBUG_LEVELING_FEATURE)
283
           if (DEBUGGING(MESH_ADJUST)) {
324
           if (DEBUGGING(MESH_ADJUST)) {
324
        *  Returns 0.0 if Z is past the specified 'Fade Height'.
365
        *  Returns 0.0 if Z is past the specified 'Fade Height'.
325
        */
366
        */
326
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
367
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
327
-        inline float fade_scaling_factor_for_z(const float &lz) {
368
+        static inline float fade_scaling_factor_for_z(const float &lz) {
328
           if (planner.z_fade_height == 0.0) return 1.0;
369
           if (planner.z_fade_height == 0.0) return 1.0;
329
           static float fade_scaling_factor = 1.0;
370
           static float fade_scaling_factor = 1.0;
330
           const float rz = RAW_Z_POSITION(lz);
371
           const float rz = RAW_Z_POSITION(lz);
338
           return fade_scaling_factor;
379
           return fade_scaling_factor;
339
         }
380
         }
340
       #else
381
       #else
341
-        inline float fade_scaling_factor_for_z(const float &lz) {
342
-          return 1.0;
343
-        }
382
+        FORCE_INLINE static float fade_scaling_factor_for_z(const float &lz) { return 1.0; }
344
       #endif
383
       #endif
345
 
384
 
385
+      FORCE_INLINE static float mesh_index_to_xpos(const uint8_t i) { return pgm_read_float(&_mesh_index_to_xpos[i]); }
386
+      FORCE_INLINE static float mesh_index_to_ypos(const uint8_t i) { return pgm_read_float(&_mesh_index_to_ypos[i]); }
387
+
388
+      static bool prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate);
389
+      static void line_to_destination_cartesian(const float &fr, uint8_t e);
390
+
346
   }; // class unified_bed_leveling
391
   }; // class unified_bed_leveling
347
 
392
 
348
   extern unified_bed_leveling ubl;
393
   extern unified_bed_leveling ubl;
349
 
394
 
395
+  #if ENABLED(UBL_G26_MESH_VALIDATION)
396
+    FORCE_INLINE void gcode_G26() { ubl.G26(); }
397
+  #endif
398
+
399
+  FORCE_INLINE void gcode_G29() { ubl.G29(); }
400
+
350
 #endif // AUTO_BED_LEVELING_UBL
401
 #endif // AUTO_BED_LEVELING_UBL
351
 #endif // UNIFIED_BED_LEVELING_H
402
 #endif // UNIFIED_BED_LEVELING_H

+ 235
- 246
Marlin/ubl_G29.cpp
File diff suppressed because it is too large
View File


+ 64
- 64
Marlin/ubl_motion.cpp View File

85
 
85
 
86
   }
86
   }
87
 
87
 
88
-  void ubl_line_to_destination_cartesian(const float &feed_rate, uint8_t extruder) {
88
+  void unified_bed_leveling::line_to_destination_cartesian(const float &feed_rate, uint8_t extruder) {
89
     /**
89
     /**
90
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
90
      * Much of the nozzle movement will be within the same cell. So we will do as little computation
91
      * as possible to determine if this is the case. If this move is within the same cell, we will
91
      * as possible to determine if this is the case. If this move is within the same cell, we will
104
                   destination[E_AXIS]
104
                   destination[E_AXIS]
105
                 };
105
                 };
106
 
106
 
107
-    const int cell_start_xi = ubl.get_cell_index_x(RAW_X_POSITION(start[X_AXIS])),
108
-              cell_start_yi = ubl.get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])),
109
-              cell_dest_xi  = ubl.get_cell_index_x(RAW_X_POSITION(end[X_AXIS])),
110
-              cell_dest_yi  = ubl.get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS]));
107
+    const int cell_start_xi = get_cell_index_x(RAW_X_POSITION(start[X_AXIS])),
108
+              cell_start_yi = get_cell_index_y(RAW_Y_POSITION(start[Y_AXIS])),
109
+              cell_dest_xi  = get_cell_index_x(RAW_X_POSITION(end[X_AXIS])),
110
+              cell_dest_yi  = get_cell_index_y(RAW_Y_POSITION(end[Y_AXIS]));
111
 
111
 
112
-    if (ubl.g26_debug_flag) {
113
-      SERIAL_ECHOPAIR(" ubl_line_to_destination(xe=", end[X_AXIS]);
112
+    if (g26_debug_flag) {
113
+      SERIAL_ECHOPAIR(" ubl.line_to_destination(xe=", end[X_AXIS]);
114
       SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]);
114
       SERIAL_ECHOPAIR(", ye=", end[Y_AXIS]);
115
       SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]);
115
       SERIAL_ECHOPAIR(", ze=", end[Z_AXIS]);
116
       SERIAL_ECHOPAIR(", ee=", end[E_AXIS]);
116
       SERIAL_ECHOPAIR(", ee=", end[E_AXIS]);
117
       SERIAL_CHAR(')');
117
       SERIAL_CHAR(')');
118
       SERIAL_EOL;
118
       SERIAL_EOL;
119
-      debug_current_and_destination(PSTR("Start of ubl_line_to_destination()"));
119
+      debug_current_and_destination(PSTR("Start of ubl.line_to_destination()"));
120
     }
120
     }
121
 
121
 
122
     if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell,
122
     if (cell_start_xi == cell_dest_xi && cell_start_yi == cell_dest_yi) { // if the whole move is within the same cell,
132
         // Note: There is no Z Correction in this case. We are off the grid and don't know what
132
         // Note: There is no Z Correction in this case. We are off the grid and don't know what
133
         // a reasonable correction would be.
133
         // a reasonable correction would be.
134
 
134
 
135
-        planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + ubl.state.z_offset, end[E_AXIS], feed_rate, extruder);
135
+        planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + state.z_offset, end[E_AXIS], feed_rate, extruder);
136
         set_current_to_destination();
136
         set_current_to_destination();
137
 
137
 
138
-        if (ubl.g26_debug_flag)
139
-          debug_current_and_destination(PSTR("out of bounds in ubl_line_to_destination()"));
138
+        if (g26_debug_flag)
139
+          debug_current_and_destination(PSTR("out of bounds in ubl.line_to_destination()"));
140
 
140
 
141
         return;
141
         return;
142
       }
142
       }
152
        * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
152
        * to create a 1-over number for us. That will allow us to do a floating point multiply instead of a floating point divide.
153
        */
153
        */
154
 
154
 
155
-      const float xratio = (RAW_X_POSITION(end[X_AXIS]) - pgm_read_float(&ubl.mesh_index_to_xpos[cell_dest_xi])) * (1.0 / (MESH_X_DIST)),
156
-                  z1 = ubl.z_values[cell_dest_xi    ][cell_dest_yi    ] + xratio *
157
-                      (ubl.z_values[cell_dest_xi + 1][cell_dest_yi    ] - ubl.z_values[cell_dest_xi][cell_dest_yi    ]),
158
-                  z2 = ubl.z_values[cell_dest_xi    ][cell_dest_yi + 1] + xratio *
159
-                      (ubl.z_values[cell_dest_xi + 1][cell_dest_yi + 1] - ubl.z_values[cell_dest_xi][cell_dest_yi + 1]);
155
+      const float xratio = (RAW_X_POSITION(end[X_AXIS]) - mesh_index_to_xpos(cell_dest_xi)) * (1.0 / (MESH_X_DIST)),
156
+                  z1 = z_values[cell_dest_xi    ][cell_dest_yi    ] + xratio *
157
+                      (z_values[cell_dest_xi + 1][cell_dest_yi    ] - z_values[cell_dest_xi][cell_dest_yi    ]),
158
+                  z2 = z_values[cell_dest_xi    ][cell_dest_yi + 1] + xratio *
159
+                      (z_values[cell_dest_xi + 1][cell_dest_yi + 1] - z_values[cell_dest_xi][cell_dest_yi + 1]);
160
 
160
 
161
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
161
       // we are done with the fractional X distance into the cell. Now with the two Z-Heights we have calculated, we
162
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
162
       // are going to apply the Y-Distance into the cell to interpolate the final Z correction.
163
 
163
 
164
-      const float yratio = (RAW_Y_POSITION(end[Y_AXIS]) - pgm_read_float(&ubl.mesh_index_to_ypos[cell_dest_yi])) * (1.0 / (MESH_Y_DIST));
164
+      const float yratio = (RAW_Y_POSITION(end[Y_AXIS]) - mesh_index_to_ypos(cell_dest_yi)) * (1.0 / (MESH_Y_DIST));
165
 
165
 
166
       float z0 = z1 + (z2 - z1) * yratio;
166
       float z0 = z1 + (z2 - z1) * yratio;
167
 
167
 
168
-      z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
168
+      z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
169
 
169
 
170
       /**
170
       /**
171
        * If part of the Mesh is undefined, it will show up as NAN
171
        * If part of the Mesh is undefined, it will show up as NAN
176
        */
176
        */
177
       if (isnan(z0)) z0 = 0.0;
177
       if (isnan(z0)) z0 = 0.0;
178
 
178
 
179
-      planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0 + ubl.state.z_offset, end[E_AXIS], feed_rate, extruder);
179
+      planner._buffer_line(end[X_AXIS], end[Y_AXIS], end[Z_AXIS] + z0 + state.z_offset, end[E_AXIS], feed_rate, extruder);
180
 
180
 
181
-      if (ubl.g26_debug_flag)
182
-        debug_current_and_destination(PSTR("FINAL_MOVE in ubl_line_to_destination()"));
181
+      if (g26_debug_flag)
182
+        debug_current_and_destination(PSTR("FINAL_MOVE in ubl.line_to_destination()"));
183
 
183
 
184
       set_current_to_destination();
184
       set_current_to_destination();
185
       return;
185
       return;
240
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
240
       current_yi += down_flag;  // Line is heading down, we just want to go to the bottom
241
       while (current_yi != cell_dest_yi + down_flag) {
241
       while (current_yi != cell_dest_yi + down_flag) {
242
         current_yi += dyi;
242
         current_yi += dyi;
243
-        const float next_mesh_line_y = LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[current_yi]));
243
+        const float next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi));
244
 
244
 
245
         /**
245
         /**
246
          * if the slope of the line is infinite, we won't do the calculations
246
          * if the slope of the line is infinite, we won't do the calculations
249
          */
249
          */
250
         const float x = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m;
250
         const float x = inf_m_flag ? start[X_AXIS] : (next_mesh_line_y - c) / m;
251
 
251
 
252
-        float z0 = ubl.z_correction_for_x_on_horizontal_mesh_line(x, current_xi, current_yi);
252
+        float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi, current_yi);
253
 
253
 
254
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
254
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
255
 
255
 
256
         /**
256
         /**
257
          * If part of the Mesh is undefined, it will show up as NAN
257
          * If part of the Mesh is undefined, it will show up as NAN
262
          */
262
          */
263
         if (isnan(z0)) z0 = 0.0;
263
         if (isnan(z0)) z0 = 0.0;
264
 
264
 
265
-        const float y = LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[current_yi]));
265
+        const float y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi));
266
 
266
 
267
         /**
267
         /**
268
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
268
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
281
             z_position = end[Z_AXIS];
281
             z_position = end[Z_AXIS];
282
           }
282
           }
283
 
283
 
284
-          planner._buffer_line(x, y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
284
+          planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
285
         } //else printf("FIRST MOVE PRUNED  ");
285
         } //else printf("FIRST MOVE PRUNED  ");
286
       }
286
       }
287
 
287
 
288
-      if (ubl.g26_debug_flag)
289
-        debug_current_and_destination(PSTR("vertical move done in ubl_line_to_destination()"));
288
+      if (g26_debug_flag)
289
+        debug_current_and_destination(PSTR("vertical move done in ubl.line_to_destination()"));
290
 
290
 
291
       //
291
       //
292
       // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done.
292
       // Check if we are at the final destination. Usually, we won't be, but if it is on a Y Mesh Line, we are done.
311
                                 // edge of this cell for the first move.
311
                                 // edge of this cell for the first move.
312
       while (current_xi != cell_dest_xi + left_flag) {
312
       while (current_xi != cell_dest_xi + left_flag) {
313
         current_xi += dxi;
313
         current_xi += dxi;
314
-        const float next_mesh_line_x = LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[current_xi])),
314
+        const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi)),
315
                     y = m * next_mesh_line_x + c;   // Calculate Y at the next X mesh line
315
                     y = m * next_mesh_line_x + c;   // Calculate Y at the next X mesh line
316
 
316
 
317
-        float z0 = ubl.z_correction_for_y_on_vertical_mesh_line(y, current_xi, current_yi);
317
+        float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi, current_yi);
318
 
318
 
319
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
319
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
320
 
320
 
321
         /**
321
         /**
322
          * If part of the Mesh is undefined, it will show up as NAN
322
          * If part of the Mesh is undefined, it will show up as NAN
327
          */
327
          */
328
         if (isnan(z0)) z0 = 0.0;
328
         if (isnan(z0)) z0 = 0.0;
329
 
329
 
330
-        const float x = LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[current_xi]));
330
+        const float x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi));
331
 
331
 
332
         /**
332
         /**
333
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
333
          * Without this check, it is possible for the algorithm to generate a zero length move in the case
346
             z_position = end[Z_AXIS];
346
             z_position = end[Z_AXIS];
347
           }
347
           }
348
 
348
 
349
-          planner._buffer_line(x, y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
349
+          planner._buffer_line(x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
350
         } //else printf("FIRST MOVE PRUNED  ");
350
         } //else printf("FIRST MOVE PRUNED  ");
351
       }
351
       }
352
 
352
 
353
-      if (ubl.g26_debug_flag)
354
-        debug_current_and_destination(PSTR("horizontal move done in ubl_line_to_destination()"));
353
+      if (g26_debug_flag)
354
+        debug_current_and_destination(PSTR("horizontal move done in ubl.line_to_destination()"));
355
 
355
 
356
       if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
356
       if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
357
         goto FINAL_MOVE;
357
         goto FINAL_MOVE;
377
 
377
 
378
     while (xi_cnt > 0 || yi_cnt > 0) {
378
     while (xi_cnt > 0 || yi_cnt > 0) {
379
 
379
 
380
-      const float next_mesh_line_x = LOGICAL_X_POSITION(pgm_read_float(&ubl.mesh_index_to_xpos[current_xi + dxi])),
381
-                  next_mesh_line_y = LOGICAL_Y_POSITION(pgm_read_float(&ubl.mesh_index_to_ypos[current_yi + dyi])),
380
+      const float next_mesh_line_x = LOGICAL_X_POSITION(mesh_index_to_xpos(current_xi + dxi)),
381
+                  next_mesh_line_y = LOGICAL_Y_POSITION(mesh_index_to_ypos(current_yi + dyi)),
382
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
382
                   y = m * next_mesh_line_x + c,   // Calculate Y at the next X mesh line
383
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
383
                   x = (next_mesh_line_y - c) / m; // Calculate X at the next Y mesh line
384
                                                   // (No need to worry about m being zero.
384
                                                   // (No need to worry about m being zero.
387
 
387
 
388
       if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
388
       if (left_flag == (x > next_mesh_line_x)) { // Check if we hit the Y line first
389
         // Yes!  Crossing a Y Mesh Line next
389
         // Yes!  Crossing a Y Mesh Line next
390
-        float z0 = ubl.z_correction_for_x_on_horizontal_mesh_line(x, current_xi - left_flag, current_yi + dyi);
390
+        float z0 = z_correction_for_x_on_horizontal_mesh_line(x, current_xi - left_flag, current_yi + dyi);
391
 
391
 
392
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
392
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
393
 
393
 
394
         /**
394
         /**
395
          * If part of the Mesh is undefined, it will show up as NAN
395
          * If part of the Mesh is undefined, it will show up as NAN
409
           e_position = end[E_AXIS];
409
           e_position = end[E_AXIS];
410
           z_position = end[Z_AXIS];
410
           z_position = end[Z_AXIS];
411
         }
411
         }
412
-        planner._buffer_line(x, next_mesh_line_y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
412
+        planner._buffer_line(x, next_mesh_line_y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
413
         current_yi += dyi;
413
         current_yi += dyi;
414
         yi_cnt--;
414
         yi_cnt--;
415
       }
415
       }
416
       else {
416
       else {
417
         // Yes!  Crossing a X Mesh Line next
417
         // Yes!  Crossing a X Mesh Line next
418
-        float z0 = ubl.z_correction_for_y_on_vertical_mesh_line(y, current_xi + dxi, current_yi - down_flag);
418
+        float z0 = z_correction_for_y_on_vertical_mesh_line(y, current_xi + dxi, current_yi - down_flag);
419
 
419
 
420
-        z0 *= ubl.fade_scaling_factor_for_z(end[Z_AXIS]);
420
+        z0 *= fade_scaling_factor_for_z(end[Z_AXIS]);
421
 
421
 
422
         /**
422
         /**
423
          * If part of the Mesh is undefined, it will show up as NAN
423
          * If part of the Mesh is undefined, it will show up as NAN
438
           z_position = end[Z_AXIS];
438
           z_position = end[Z_AXIS];
439
         }
439
         }
440
 
440
 
441
-        planner._buffer_line(next_mesh_line_x, y, z_position + z0 + ubl.state.z_offset, e_position, feed_rate, extruder);
441
+        planner._buffer_line(next_mesh_line_x, y, z_position + z0 + state.z_offset, e_position, feed_rate, extruder);
442
         current_xi += dxi;
442
         current_xi += dxi;
443
         xi_cnt--;
443
         xi_cnt--;
444
       }
444
       }
446
       if (xi_cnt < 0 || yi_cnt < 0) break; // we've gone too far, so exit the loop and move on to FINAL_MOVE
446
       if (xi_cnt < 0 || yi_cnt < 0) break; // we've gone too far, so exit the loop and move on to FINAL_MOVE
447
     }
447
     }
448
 
448
 
449
-    if (ubl.g26_debug_flag)
450
-      debug_current_and_destination(PSTR("generic move done in ubl_line_to_destination()"));
449
+    if (g26_debug_flag)
450
+      debug_current_and_destination(PSTR("generic move done in ubl.line_to_destination()"));
451
 
451
 
452
     if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
452
     if (current_position[X_AXIS] != end[X_AXIS] || current_position[Y_AXIS] != end[Y_AXIS])
453
       goto FINAL_MOVE;
453
       goto FINAL_MOVE;
502
      * Returns true if the caller did NOT update current_position, otherwise false.
502
      * Returns true if the caller did NOT update current_position, otherwise false.
503
      */
503
      */
504
 
504
 
505
-    static bool ubl_prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate) {
505
+    static bool unified_bed_leveling::prepare_linear_move_to(const float ltarget[XYZE], const float &feedrate) {
506
 
506
 
507
       if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS]))  // fail if moving outside reachable boundary
507
       if (!position_is_reachable_xy(ltarget[X_AXIS], ltarget[Y_AXIS]))  // fail if moving outside reachable boundary
508
         return true; // did not move, so current_position still accurate
508
         return true; // did not move, so current_position still accurate
554
 
554
 
555
       // Only compute leveling per segment if ubl active and target below z_fade_height.
555
       // Only compute leveling per segment if ubl active and target below z_fade_height.
556
 
556
 
557
-      if (!ubl.state.active || above_fade_height) {   // no mesh leveling
557
+      if (!state.active || above_fade_height) {   // no mesh leveling
558
 
558
 
559
-        const float z_offset = ubl.state.active ? ubl.state.z_offset : 0.0;
559
+        const float z_offset = state.active ? state.z_offset : 0.0;
560
 
560
 
561
         float seg_dest[XYZE];                   // per-segment destination,
561
         float seg_dest[XYZE];                   // per-segment destination,
562
         COPY_XYZE(seg_dest, current_position);  // starting from current position
562
         COPY_XYZE(seg_dest, current_position);  // starting from current position
579
       // Otherwise perform per-segment leveling
579
       // Otherwise perform per-segment leveling
580
 
580
 
581
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
581
       #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
582
-        const float fade_scaling_factor = ubl.fade_scaling_factor_for_z(ltarget[Z_AXIS]);
582
+        const float fade_scaling_factor = fade_scaling_factor_for_z(ltarget[Z_AXIS]);
583
       #endif
583
       #endif
584
 
584
 
585
       float seg_dest[XYZE];  // per-segment destination, initialize to first segment
585
       float seg_dest[XYZE];  // per-segment destination, initialize to first segment
591
       float rx = RAW_X_POSITION(seg_dest[X_AXIS]),  // assume raw vs logical coordinates shifted but not scaled.
591
       float rx = RAW_X_POSITION(seg_dest[X_AXIS]),  // assume raw vs logical coordinates shifted but not scaled.
592
             ry = RAW_Y_POSITION(seg_dest[Y_AXIS]);
592
             ry = RAW_Y_POSITION(seg_dest[Y_AXIS]);
593
 
593
 
594
-      do {  // for each mesh cell encountered during the move
594
+      for(;;) {  // for each mesh cell encountered during the move
595
 
595
 
596
         // Compute mesh cell invariants that remain constant for all segments within cell.
596
         // Compute mesh cell invariants that remain constant for all segments within cell.
597
         // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter)
597
         // Note for cell index, if point is outside the mesh grid (in MESH_INSET perimeter)
606
         cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
606
         cell_xi = constrain(cell_xi, 0, (GRID_MAX_POINTS_X) - 1);
607
         cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
607
         cell_yi = constrain(cell_yi, 0, (GRID_MAX_POINTS_Y) - 1);
608
 
608
 
609
-        const float x0 = pgm_read_float(&(ubl.mesh_index_to_xpos[cell_xi  ])),  // 64 byte table lookup avoids mul+add
610
-                    y0 = pgm_read_float(&(ubl.mesh_index_to_ypos[cell_yi  ])),  // 64 byte table lookup avoids mul+add
611
-                    x1 = pgm_read_float(&(ubl.mesh_index_to_xpos[cell_xi+1])),  // 64 byte table lookup avoids mul+add
612
-                    y1 = pgm_read_float(&(ubl.mesh_index_to_ypos[cell_yi+1]));  // 64 byte table lookup avoids mul+add
609
+        const float x0 = pgm_read_float(&(mesh_index_to_xpos[cell_xi  ])),  // 64 byte table lookup avoids mul+add
610
+                    y0 = pgm_read_float(&(mesh_index_to_ypos[cell_yi  ])),  // 64 byte table lookup avoids mul+add
611
+                    x1 = pgm_read_float(&(mesh_index_to_xpos[cell_xi+1])),  // 64 byte table lookup avoids mul+add
612
+                    y1 = pgm_read_float(&(mesh_index_to_ypos[cell_yi+1]));  // 64 byte table lookup avoids mul+add
613
 
613
 
614
         float cx = rx - x0,   // cell-relative x
614
         float cx = rx - x0,   // cell-relative x
615
               cy = ry - y0,   // cell-relative y
615
               cy = ry - y0,   // cell-relative y
616
-              z_x0y0 = ubl.z_values[cell_xi  ][cell_yi  ],  // z at lower left corner
617
-              z_x1y0 = ubl.z_values[cell_xi+1][cell_yi  ],  // z at upper left corner
618
-              z_x0y1 = ubl.z_values[cell_xi  ][cell_yi+1],  // z at lower right corner
619
-              z_x1y1 = ubl.z_values[cell_xi+1][cell_yi+1];  // z at upper right corner
616
+              z_x0y0 = z_values[cell_xi  ][cell_yi  ],  // z at lower left corner
617
+              z_x1y0 = z_values[cell_xi+1][cell_yi  ],  // z at upper left corner
618
+              z_x0y1 = z_values[cell_xi  ][cell_yi+1],  // z at lower right corner
619
+              z_x1y1 = z_values[cell_xi+1][cell_yi+1];  // z at upper right corner
620
 
620
 
621
-        if (isnan(z_x0y0)) z_x0y0 = 0;              // ideally activating ubl.state.active (G29 A)
621
+        if (isnan(z_x0y0)) z_x0y0 = 0;              // ideally activating state.active (G29 A)
622
         if (isnan(z_x1y0)) z_x1y0 = 0;              //   should refuse if any invalid mesh points
622
         if (isnan(z_x1y0)) z_x1y0 = 0;              //   should refuse if any invalid mesh points
623
         if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
623
         if (isnan(z_x0y1)) z_x0y1 = 0;              //   in order to avoid isnan tests per cell,
624
         if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
624
         if (isnan(z_x1y1)) z_x1y1 = 0;              //   thus guessing zero for undefined points
642
         const float z_sxy0 = z_xmy0 * dx_seg,                                     // per-segment adjustment to z_cxy0
642
         const float z_sxy0 = z_xmy0 * dx_seg,                                     // per-segment adjustment to z_cxy0
643
                     z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * dx_seg;  // per-segment adjustment to z_cxym
643
                     z_sxym = (z_xmy1 - z_xmy0) * (1.0 / (MESH_Y_DIST)) * dx_seg;  // per-segment adjustment to z_cxym
644
 
644
 
645
-        do {  // for all segments within this mesh cell
645
+        for(;;) {  // for all segments within this mesh cell
646
 
646
 
647
           float z_cxcy = z_cxy0 + z_cxym * cy;      // interpolated mesh z height along cx at cy
647
           float z_cxcy = z_cxy0 + z_cxym * cy;      // interpolated mesh z height along cx at cy
648
 
648
 
650
             z_cxcy *= fade_scaling_factor;          // apply fade factor to interpolated mesh height
650
             z_cxcy *= fade_scaling_factor;          // apply fade factor to interpolated mesh height
651
           #endif
651
           #endif
652
 
652
 
653
-          z_cxcy += ubl.state.z_offset;             // add fixed mesh offset from G29 Z
653
+          z_cxcy += state.z_offset;             // add fixed mesh offset from G29 Z
654
 
654
 
655
           if (--segments == 0) {                    // if this is last segment, use ltarget for exact
655
           if (--segments == 0) {                    // if this is last segment, use ltarget for exact
656
             COPY_XYZE(seg_dest, ltarget);
656
             COPY_XYZE(seg_dest, ltarget);
681
           z_cxy0 += z_sxy0;   // adjust z_cxy0 by per-segment z_sxy0
681
           z_cxy0 += z_sxy0;   // adjust z_cxy0 by per-segment z_sxy0
682
           z_cxym += z_sxym;   // adjust z_cxym by per-segment z_sxym
682
           z_cxym += z_sxym;   // adjust z_cxym by per-segment z_sxym
683
 
683
 
684
-        } while (true);   // per-segment loop exits by break after last segment within cell, or by return on final segment
685
-      } while (true);   // per-cell loop
686
-    }                 // end of function
684
+        } // segment loop
685
+      } // cell loop
686
+    }
687
 
687
 
688
   #endif // UBL_DELTA
688
   #endif // UBL_DELTA
689
 
689
 

+ 3
- 3
Marlin/ultralcd.cpp View File

1480
     void _lcd_level_bed_get_z() {
1480
     void _lcd_level_bed_get_z() {
1481
       ENCODER_DIRECTION_NORMAL();
1481
       ENCODER_DIRECTION_NORMAL();
1482
 
1482
 
1483
-      // Encoder wheel adjusts the Z position
1483
+      // Encoder knob or keypad buttons adjust the Z position
1484
       if (encoderPosition) {
1484
       if (encoderPosition) {
1485
         refresh_cmd_timeout();
1485
         refresh_cmd_timeout();
1486
         current_position[Z_AXIS] += float((int32_t)encoderPosition) * (MBL_Z_STEP);
1486
         current_position[Z_AXIS] += float((int32_t)encoderPosition) * (MBL_Z_STEP);
4202
       }
4202
       }
4203
       #if ENABLED(AUTO_BED_LEVELING_UBL)
4203
       #if ENABLED(AUTO_BED_LEVELING_UBL)
4204
         if (ubl.has_control_of_lcd_panel) {
4204
         if (ubl.has_control_of_lcd_panel) {
4205
-          ubl.encoder_diff = encoderDiff;    // Make the encoder's rotation available to G29's Mesh Editor
4205
+          ubl.encoder_diff = encoderDiff;   // Make the encoder's rotation available to G29's Mesh Editor
4206
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
4206
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
4207
-                                            // wheel has not turned.
4207
+                                            // knob has not turned.
4208
         }
4208
         }
4209
       #endif
4209
       #endif
4210
       lastEncoderBits = enc;
4210
       lastEncoderBits = enc;

Loading…
Cancel
Save