Browse Source

Convert UBL mesh tilting to all use the same algorithm (#9204)

A number of regressions were patched also. The UBL G29 P2 and P4 Press and Hold had stopped working. It is very possible this is broken in the bugfix_v1.1.x branch also.

The main purpose of the Pull Request is to get the 3-Point mesh tilting to use the LSF algorithm just like the grid based mesh tilt. This simplifies the logic and reduces the code size some what. But the real reason to do it is the 3-Point case can be solved exactly. And by feeding these numbers into the LSF algorithm it provides a way to check all that code for 'correctness'.
Roxy-3D 7 years ago
parent
commit
f5f1b069ad
No account linked to committer's email address

+ 2
- 2
Marlin/src/config/examples/gCreate/gMax1.5+/Configuration.h View File

1061
 #define Z_SAFE_HOMING
1061
 #define Z_SAFE_HOMING
1062
 
1062
 
1063
 #if ENABLED(Z_SAFE_HOMING)
1063
 #if ENABLED(Z_SAFE_HOMING)
1064
-  #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2 - 4) // X point for Z homing when homing all axes (G28).
1065
-  #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2 + 4) // Y point for Z homing when homing all axes (G28).
1064
+  #define Z_SAFE_HOMING_X_POINT ((X_BED_SIZE) / 2 - 8) // X point for Z homing when homing all axes (G28).
1065
+  #define Z_SAFE_HOMING_Y_POINT ((Y_BED_SIZE) / 2 - 4) // Y point for Z homing when homing all axes (G28).
1066
 #endif
1066
 #endif
1067
 
1067
 
1068
 // Homing speeds (mm/m)
1068
 // Homing speeds (mm/m)

+ 14
- 14
Marlin/src/feature/Max7219_Debug_LEDs.cpp View File

237
 
237
 
238
   for (x = 0; x <= 7; x++)        // Do an aesthetically pleasing pattern to fully test
238
   for (x = 0; x <= 7; x++)        // Do an aesthetically pleasing pattern to fully test
239
     for (y = 0; y <= 7; y++) {    // the Max7219 module and LEDs. First, turn them
239
     for (y = 0; y <= 7; y++) {    // the Max7219 module and LEDs. First, turn them
240
-      Max7219_LED_On(x, y);       // all on.
240
+      Max7219_LED_On(y, x);       // all on.
241
       delay(3);
241
       delay(3);
242
     }
242
     }
243
 
243
 
244
   for (x = 0; x <= 7; x++)        // Now, turn them all off.
244
   for (x = 0; x <= 7; x++)        // Now, turn them all off.
245
     for (y = 0; y <= 7; y++) {
245
     for (y = 0; y <= 7; y++) {
246
-      Max7219_LED_Off(x, y);
246
+      Max7219_LED_Off(y, x);
247
       delay(3);                   // delay() is OK here. Max7219_init() is only called from
247
       delay(3);                   // delay() is OK here. Max7219_init() is only called from
248
     }                             // setup() and nothing is running yet.
248
     }                             // setup() and nothing is running yet.
249
 
249
 
251
 
251
 
252
   for (x = 8; x--;)               // Now, do the same thing from the opposite direction
252
   for (x = 8; x--;)               // Now, do the same thing from the opposite direction
253
     for (y = 0; y <= 7; y++) {
253
     for (y = 0; y <= 7; y++) {
254
-      Max7219_LED_On(x, y);
254
+      Max7219_LED_On(y, x);
255
       delay(2);
255
       delay(2);
256
     }
256
     }
257
 
257
 
258
   for (x = 8; x--;)
258
   for (x = 8; x--;)
259
     for (y = 0; y <= 7; y++) {
259
     for (y = 0; y <= 7; y++) {
260
-      Max7219_LED_Off(x, y);
260
+      Max7219_LED_Off(y, x);
261
       delay(2);
261
       delay(2);
262
     }
262
     }
263
 }
263
 }
295
     static int16_t last_head_cnt = 0;
295
     static int16_t last_head_cnt = 0;
296
     if (last_head_cnt != head) {
296
     if (last_head_cnt != head) {
297
       if (last_head_cnt < 8)
297
       if (last_head_cnt < 8)
298
-        Max7219_LED_Off(last_head_cnt, MAX7219_DEBUG_STEPPER_HEAD);
298
+        Max7219_LED_Off(MAX7219_DEBUG_STEPPER_HEAD, last_head_cnt);
299
       else
299
       else
300
-        Max7219_LED_Off(last_head_cnt - 8, MAX7219_DEBUG_STEPPER_HEAD + 1);
300
+        Max7219_LED_Off(MAX7219_DEBUG_STEPPER_HEAD + 1, last_head_cnt - 8);
301
 
301
 
302
       last_head_cnt = head;
302
       last_head_cnt = head;
303
       if (head < 8)
303
       if (head < 8)
304
-        Max7219_LED_On(head, MAX7219_DEBUG_STEPPER_HEAD);
304
+        Max7219_LED_On(MAX7219_DEBUG_STEPPER_HEAD, head);
305
       else
305
       else
306
-        Max7219_LED_On(head - 8, MAX7219_DEBUG_STEPPER_HEAD + 1);
306
+        Max7219_LED_On(MAX7219_DEBUG_STEPPER_HEAD + 1, head - 8);
307
     }
307
     }
308
   #endif
308
   #endif
309
 
309
 
311
     static int16_t last_tail_cnt = 0;
311
     static int16_t last_tail_cnt = 0;
312
     if (last_tail_cnt != tail) {
312
     if (last_tail_cnt != tail) {
313
       if (last_tail_cnt < 8)
313
       if (last_tail_cnt < 8)
314
-        Max7219_LED_Off(last_tail_cnt, MAX7219_DEBUG_STEPPER_TAIL);
314
+        Max7219_LED_Off(MAX7219_DEBUG_STEPPER_TAIL, last_tail_cnt);
315
       else
315
       else
316
-        Max7219_LED_Off(last_tail_cnt - 8, MAX7219_DEBUG_STEPPER_TAIL + 1);
316
+        Max7219_LED_Off(MAX7219_DEBUG_STEPPER_TAIL + 1, last_tail_cnt - 8);
317
 
317
 
318
       last_tail_cnt = tail;
318
       last_tail_cnt = tail;
319
       if (tail < 8)
319
       if (tail < 8)
320
-        Max7219_LED_On(tail, MAX7219_DEBUG_STEPPER_TAIL);
320
+        Max7219_LED_On(MAX7219_DEBUG_STEPPER_TAIL, tail);
321
       else
321
       else
322
-        Max7219_LED_On(tail - 8, MAX7219_DEBUG_STEPPER_TAIL + 1);
322
+        Max7219_LED_On(MAX7219_DEBUG_STEPPER_TAIL + 1, tail - 8);
323
     }
323
     }
324
   #endif
324
   #endif
325
 
325
 
336
                     en = max(current_depth, last_depth);
336
                     en = max(current_depth, last_depth);
337
       if (current_depth < last_depth)
337
       if (current_depth < last_depth)
338
         for (uint8_t i = st; i <= en; i++)   // clear the highest order LEDs
338
         for (uint8_t i = st; i <= en; i++)   // clear the highest order LEDs
339
-          Max7219_LED_Off(i / 2, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1));
339
+          Max7219_LED_Off(MAX7219_DEBUG_STEPPER_QUEUE + (i & 1), i / 2);
340
       else
340
       else
341
         for (uint8_t i = st; i <= en; i++)   // set the LEDs to current depth
341
         for (uint8_t i = st; i <= en; i++)   // set the LEDs to current depth
342
-          Max7219_LED_On(i / 2, MAX7219_DEBUG_STEPPER_QUEUE + (i & 1));
342
+          Max7219_LED_On(MAX7219_DEBUG_STEPPER_QUEUE + (i & 1), i / 2);
343
 
343
 
344
       last_depth = current_depth;
344
       last_depth = current_depth;
345
     }
345
     }

+ 2
- 2
Marlin/src/feature/bedlevel/ubl/ubl.h View File

59
 
59
 
60
 #if ENABLED(ULTRA_LCD)
60
 #if ENABLED(ULTRA_LCD)
61
   extern char lcd_status_message[];
61
   extern char lcd_status_message[];
62
-  void lcd_quick_feedback();
62
+  void lcd_quick_feedback(const bool clear_buttons);
63
 #endif
63
 #endif
64
 
64
 
65
 #define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1))
65
 #define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / float(GRID_MAX_POINTS_X - 1))
85
     #if ENABLED(NEWPANEL)
85
     #if ENABLED(NEWPANEL)
86
       static void move_z_with_encoder(const float &multiplier);
86
       static void move_z_with_encoder(const float &multiplier);
87
       static float measure_point_with_encoder();
87
       static float measure_point_with_encoder();
88
-      static float measure_business_card_thickness(const float&);
88
+      static float measure_business_card_thickness(float);
89
       static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool);
89
       static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool);
90
       static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map);
90
       static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map);
91
     #endif
91
     #endif

+ 151
- 164
Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp View File

40
   #include "../../../feature/bedlevel/bedlevel.h"
40
   #include "../../../feature/bedlevel/bedlevel.h"
41
   #include "../../../libs/least_squares_fit.h"
41
   #include "../../../libs/least_squares_fit.h"
42
 
42
 
43
+#include "../../../feature/Max7219_Debug_LEDs.h"
44
+
43
   #include <math.h>
45
   #include <math.h>
44
 
46
 
45
   #define UBL_G29_P31
47
   #define UBL_G29_P31
98
    *   C     Continue   G29 P1 C continues the generation of a partially-constructed Mesh without invalidating
100
    *   C     Continue   G29 P1 C continues the generation of a partially-constructed Mesh without invalidating
99
    *                    previous measurements.
101
    *                    previous measurements.
100
    *
102
    *
101
-   *   C     Constant   G29 P2 C specifies a Constant and tells the Manual Probe subsystem to use the current
102
-   *                    location in its search for the closest unmeasured Mesh Point.
103
+   *   C                G29 P2 C tells the Manual Probe subsystem to not use the current nozzle
104
+   *                    location in its search for the closest unmeasured Mesh Point.  Instead, attempt to
105
+   *                    start at one end of the uprobed points and Continue sequentually.
103
    *
106
    *
104
    *                    G29 P3 C specifies the Constant for the fill. Otherwise, uses a "reasonable" value.
107
    *                    G29 P3 C specifies the Constant for the fill. Otherwise, uses a "reasonable" value.
105
    *
108
    *
281
    *
284
    *
282
    *   Release Notes:
285
    *   Release Notes:
283
    *   You MUST do M502, M500 to initialize the storage. Failure to do this will cause all
286
    *   You MUST do M502, M500 to initialize the storage. Failure to do this will cause all
284
-   *   kinds of problems. Enabling EEPROM Storage is highly recommended. With EEPROM Storage
285
-   *   of the mesh, you are limited to 3-Point and Grid Leveling. (G29 P0 T and G29 P0 G
286
-   *   respectively.)
287
+   *   kinds of problems. Enabling EEPROM Storage is required.
287
    *
288
    *
288
    *   When you do a G28 and then a G29 P1 to automatically build your first mesh, you are going to notice
289
    *   When you do a G28 and then a G29 P1 to automatically build your first mesh, you are going to notice
289
    *   the Unified Bed Leveling probes points further and further away from the starting location. (The
290
    *   the Unified Bed Leveling probes points further and further away from the starting location. (The
385
       if (parser.seen('J')) {
386
       if (parser.seen('J')) {
386
         if (g29_grid_size) {  // if not 0 it is a normal n x n grid being probed
387
         if (g29_grid_size) {  // if not 0 it is a normal n x n grid being probed
387
           save_ubl_active_state_and_disable();
388
           save_ubl_active_state_and_disable();
388
-          tilt_mesh_based_on_probed_grid(parser.seen('T'));
389
+          tilt_mesh_based_on_probed_grid(false /* false says to do normal grid probing */ );
389
           restore_ubl_active_state_and_leave();
390
           restore_ubl_active_state_and_leave();
390
         }
391
         }
391
         else { // grid_size == 0 : A 3-Point leveling has been requested
392
         else { // grid_size == 0 : A 3-Point leveling has been requested
392
-          float z3, z2, z1 = probe_pt(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y, false, g29_verbose_level);
393
-          if (!isnan(z1)) {
394
-            z2 = probe_pt(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y, false, g29_verbose_level);
395
-            if (!isnan(z2))
396
-              z3 = probe_pt(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y, true, g29_verbose_level);
397
-          }
398
-
399
-          if (isnan(z1) || isnan(z2) || isnan(z3)) { // probe_pt will return NAN if unreachable
400
-            SERIAL_ERROR_START();
401
-            SERIAL_ERRORLNPGM("Attempt to probe off the bed.");
402
-            goto LEAVE;
403
-          }
404
-
405
-          // Adjust z1, z2, z3 by the Mesh Height at these points. Just because they're non-zero
406
-          // doesn't mean the Mesh is tilted! (Compensate each probe point by what the Mesh says
407
-          // its height is.)
408
 
393
 
409
           save_ubl_active_state_and_disable();
394
           save_ubl_active_state_and_disable();
410
-          z1 -= get_z_correction(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y) /* + zprobe_zoffset */ ;
411
-          z2 -= get_z_correction(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y) /* + zprobe_zoffset */ ;
412
-          z3 -= get_z_correction(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y) /* + zprobe_zoffset */ ;
413
-
414
-          do_blocking_move_to_xy(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)));
415
-          tilt_mesh_based_on_3pts(z1, z2, z3);
395
+          tilt_mesh_based_on_probed_grid(true /* true says to do 3-Point leveling */ );
416
           restore_ubl_active_state_and_leave();
396
           restore_ubl_active_state_and_leave();
417
         }
397
         }
398
+        do_blocking_move_to_xy(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)));
418
       }
399
       }
419
 
400
 
420
     #endif // HAS_BED_PROBE
401
     #endif // HAS_BED_PROBE
464
             SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.");
445
             SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations.");
465
             do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
446
             do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
466
 
447
 
467
-            if (!g29_x_flag && !g29_y_flag) {
448
+            if (parser.seen('C') && !g29_x_flag && !g29_y_flag) {
468
               /**
449
               /**
469
                * Use a good default location for the path.
450
                * Use a good default location for the path.
470
                * The flipped > and < operators in these comparisons is intentional.
451
                * The flipped > and < operators in these comparisons is intentional.
481
               #endif
462
               #endif
482
             }
463
             }
483
 
464
 
484
-            if (parser.seen('C')) {
485
-              g29_x_pos = current_position[X_AXIS];
486
-              g29_y_pos = current_position[Y_AXIS];
487
-            }
488
-
489
             if (parser.seen('B')) {
465
             if (parser.seen('B')) {
490
-              g29_card_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness(Z_CLEARANCE_BETWEEN_PROBES);
466
+              g29_card_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness((float) Z_CLEARANCE_BETWEEN_PROBES);
491
               if (FABS(g29_card_thickness) > 1.5) {
467
               if (FABS(g29_card_thickness) > 1.5) {
492
                 SERIAL_PROTOCOLLNPGM("?Error in Business Card measurement.");
468
                 SERIAL_PROTOCOLLNPGM("?Error in Business Card measurement.");
493
                 return;
469
                 return;
672
     #if ENABLED(NEWPANEL)
648
     #if ENABLED(NEWPANEL)
673
       lcd_reset_alert_level();
649
       lcd_reset_alert_level();
674
       LCD_MESSAGEPGM("");
650
       LCD_MESSAGEPGM("");
675
-      lcd_quick_feedback();
651
+      lcd_quick_feedback(true);
676
       lcd_external_control = false;
652
       lcd_external_control = false;
677
     #endif
653
     #endif
678
 
654
 
730
 
706
 
731
     bool click_and_hold(const clickFunc_t func=NULL) {
707
     bool click_and_hold(const clickFunc_t func=NULL) {
732
       if (is_lcd_clicked()) {
708
       if (is_lcd_clicked()) {
733
-        lcd_quick_feedback();
709
+        lcd_quick_feedback(false); // Do NOT clear button status!  If cleared, the code
710
+                                   // code can not look for a 'click and hold'
734
         const millis_t nxt = millis() + 1500UL;
711
         const millis_t nxt = millis() + 1500UL;
735
         while (is_lcd_clicked()) {                // Loop while the encoder is pressed. Uses hardware flag!
712
         while (is_lcd_clicked()) {                // Loop while the encoder is pressed. Uses hardware flag!
736
           idle();                                 // idle, of course
713
           idle();                                 // idle, of course
737
           if (ELAPSED(millis(), nxt)) {           // After 1.5 seconds
714
           if (ELAPSED(millis(), nxt)) {           // After 1.5 seconds
738
-            lcd_quick_feedback();
715
+            lcd_quick_feedback(true);
739
             if (func) (*func)();
716
             if (func) (*func)();
740
             wait_for_release();
717
             wait_for_release();
741
             safe_delay(50);                       // Debounce the Encoder wheel
718
             safe_delay(50);                       // Debounce the Encoder wheel
743
           }
720
           }
744
         }
721
         }
745
       }
722
       }
723
+      safe_delay(5);
746
       return false;
724
       return false;
747
     }
725
     }
748
 
726
 
771
         #if ENABLED(NEWPANEL)
749
         #if ENABLED(NEWPANEL)
772
           if (is_lcd_clicked()) {
750
           if (is_lcd_clicked()) {
773
             SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n");
751
             SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n");
774
-            lcd_quick_feedback();
752
+            lcd_quick_feedback(false);
775
             STOW_PROBE();
753
             STOW_PROBE();
776
-            wait_for_release();
754
+            while (is_lcd_clicked()) idle();
777
             lcd_external_control = false;
755
             lcd_external_control = false;
778
             restore_ubl_active_state_and_leave();
756
             restore_ubl_active_state_and_leave();
757
+            safe_delay(50);  // Debounce the Encoder wheel
779
             return;
758
             return;
780
           }
759
           }
781
         #endif
760
         #endif
804
       );
783
       );
805
     }
784
     }
806
 
785
 
807
-    void unified_bed_leveling::tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3) {
808
-      matrix_3x3 rotation;
809
-      vector_3 v1 = vector_3( (UBL_PROBE_PT_1_X - UBL_PROBE_PT_2_X),
810
-                              (UBL_PROBE_PT_1_Y - UBL_PROBE_PT_2_Y),
811
-                              (z1 - z2) ),
812
-
813
-               v2 = vector_3( (UBL_PROBE_PT_3_X - UBL_PROBE_PT_2_X),
814
-                              (UBL_PROBE_PT_3_Y - UBL_PROBE_PT_2_Y),
815
-                              (z3 - z2) ),
816
-
817
-               normal = vector_3::cross(v1, v2);
818
-
819
-      normal = normal.get_normal();
820
-
821
-      /**
822
-       * This vector is normal to the tilted plane.
823
-       * However, we don't know its direction. We need it to point up. So if
824
-       * Z is negative, we need to invert the sign of all components of the vector
825
-       */
826
-      if (normal.z < 0.0) {
827
-        normal.x = -normal.x;
828
-        normal.y = -normal.y;
829
-        normal.z = -normal.z;
830
-      }
831
-
832
-      rotation = matrix_3x3::create_look_at(vector_3(normal.x, normal.y, 1));
833
-
834
-      if (g29_verbose_level > 2) {
835
-        SERIAL_ECHOPGM("bed plane normal = [");
836
-        SERIAL_PROTOCOL_F(normal.x, 7);
837
-        SERIAL_PROTOCOLCHAR(',');
838
-        SERIAL_PROTOCOL_F(normal.y, 7);
839
-        SERIAL_PROTOCOLCHAR(',');
840
-        SERIAL_PROTOCOL_F(normal.z, 7);
841
-        SERIAL_ECHOLNPGM("]");
842
-        rotation.debug(PSTR("rotation matrix:"));
843
-      }
844
-
845
-      //
846
-      // All of 3 of these points should give us the same d constant
847
-      //
848
-
849
-      float t = normal.x * (UBL_PROBE_PT_1_X) + normal.y * (UBL_PROBE_PT_1_Y),
850
-            d = t + normal.z * z1;
851
-
852
-      if (g29_verbose_level>2) {
853
-        SERIAL_ECHOPGM("D constant: ");
854
-        SERIAL_PROTOCOL_F(d, 7);
855
-        SERIAL_ECHOLNPGM(" ");
856
-      }
857
-
858
-      #if ENABLED(DEBUG_LEVELING_FEATURE)
859
-        if (DEBUGGING(LEVELING)) {
860
-          SERIAL_ECHOPGM("d from 1st point: ");
861
-          SERIAL_ECHO_F(d, 6);
862
-          SERIAL_EOL();
863
-          t = normal.x * (UBL_PROBE_PT_2_X) + normal.y * (UBL_PROBE_PT_2_Y);
864
-          d = t + normal.z * z2;
865
-          SERIAL_ECHOPGM("d from 2nd point: ");
866
-          SERIAL_ECHO_F(d, 6);
867
-          SERIAL_EOL();
868
-          t = normal.x * (UBL_PROBE_PT_3_X) + normal.y * (UBL_PROBE_PT_3_Y);
869
-          d = t + normal.z * z3;
870
-          SERIAL_ECHOPGM("d from 3rd point: ");
871
-          SERIAL_ECHO_F(d, 6);
872
-          SERIAL_EOL();
873
-        }
874
-      #endif
875
-
876
-      for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
877
-        for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
878
-          float x_tmp = mesh_index_to_xpos(i),
879
-                y_tmp = mesh_index_to_ypos(j),
880
-                z_tmp = z_values[i][j];
881
-          #if ENABLED(DEBUG_LEVELING_FEATURE)
882
-            if (DEBUGGING(LEVELING)) {
883
-              SERIAL_ECHOPGM("before rotation = [");
884
-              SERIAL_PROTOCOL_F(x_tmp, 7);
885
-              SERIAL_PROTOCOLCHAR(',');
886
-              SERIAL_PROTOCOL_F(y_tmp, 7);
887
-              SERIAL_PROTOCOLCHAR(',');
888
-              SERIAL_PROTOCOL_F(z_tmp, 7);
889
-              SERIAL_ECHOPGM("]   ---> ");
890
-              safe_delay(20);
891
-            }
892
-          #endif
893
-          apply_rotation_xyz(rotation, x_tmp, y_tmp, z_tmp);
894
-          #if ENABLED(DEBUG_LEVELING_FEATURE)
895
-            if (DEBUGGING(LEVELING)) {
896
-              SERIAL_ECHOPGM("after rotation = [");
897
-              SERIAL_PROTOCOL_F(x_tmp, 7);
898
-              SERIAL_PROTOCOLCHAR(',');
899
-              SERIAL_PROTOCOL_F(y_tmp, 7);
900
-              SERIAL_PROTOCOLCHAR(',');
901
-              SERIAL_PROTOCOL_F(z_tmp, 7);
902
-              SERIAL_ECHOLNPGM("]");
903
-              safe_delay(55);
904
-            }
905
-          #endif
906
-          z_values[i][j] += z_tmp - d;
907
-        }
908
-      }
909
-    }
910
 
786
 
911
   #endif // HAS_BED_PROBE
787
   #endif // HAS_BED_PROBE
912
 
788
 
932
 
808
 
933
     static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); }
809
     static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); }
934
 
810
 
935
-    float unified_bed_leveling::measure_business_card_thickness(const float &in_height) {
811
+    float unified_bed_leveling::measure_business_card_thickness(float in_height) {
936
       lcd_external_control = true;
812
       lcd_external_control = true;
937
       save_ubl_active_state_and_disable();   // Disable bed level correction for probing
813
       save_ubl_active_state_and_disable();   // Disable bed level correction for probing
938
 
814
 
985
       lcd_external_control = true;
861
       lcd_external_control = true;
986
 
862
 
987
       save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
863
       save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
988
-      do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES);
864
+      do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_clearance);
989
 
865
 
990
       lcd_return_to_status();
866
       lcd_return_to_status();
991
 
867
 
1047
 
923
 
1048
     #if ENABLED(NEWPANEL)
924
     #if ENABLED(NEWPANEL)
1049
       LCD_MESSAGEPGM(MSG_UBL_DOING_G29);
925
       LCD_MESSAGEPGM(MSG_UBL_DOING_G29);
1050
-      lcd_quick_feedback();
926
+      lcd_quick_feedback(true);
1051
     #endif
927
     #endif
1052
 
928
 
1053
     g29_constant = 0.0;
929
     g29_constant = 0.0;
1170
         SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
1046
         SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
1171
         #if ENABLED(NEWPANEL)
1047
         #if ENABLED(NEWPANEL)
1172
           LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR);
1048
           LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR);
1173
-          lcd_quick_feedback();
1049
+          lcd_quick_feedback(true);
1174
         #endif
1050
         #endif
1175
         return;
1051
         return;
1176
       }
1052
       }
1185
         SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
1061
         SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
1186
         #if ENABLED(NEWPANEL)
1062
         #if ENABLED(NEWPANEL)
1187
           LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR);
1063
           LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR);
1188
-          lcd_quick_feedback();
1064
+          lcd_quick_feedback(true);
1189
         #endif
1065
         #endif
1190
         return;
1066
         return;
1191
       }
1067
       }
1217
       SERIAL_EOL();
1093
       SERIAL_EOL();
1218
     #endif
1094
     #endif
1219
 
1095
 
1096
+    find_mean_mesh_height();
1097
+
1220
     #if HAS_BED_PROBE
1098
     #if HAS_BED_PROBE
1221
       SERIAL_PROTOCOLPGM("zprobe_zoffset: ");
1099
       SERIAL_PROTOCOLPGM("zprobe_zoffset: ");
1222
       SERIAL_PROTOCOL_F(zprobe_zoffset, 7);
1100
       SERIAL_PROTOCOL_F(zprobe_zoffset, 7);
1531
 
1409
 
1532
         lcd_mesh_edit_setup(new_z);
1410
         lcd_mesh_edit_setup(new_z);
1533
 
1411
 
1534
-        while (!is_lcd_clicked()) {
1412
+        do {
1535
           new_z = lcd_mesh_edit();
1413
           new_z = lcd_mesh_edit();
1536
           #if ENABLED(UBL_MESH_EDIT_MOVES_Z)
1414
           #if ENABLED(UBL_MESH_EDIT_MOVES_Z)
1537
             do_blocking_move_to_z(h_offset + new_z); // Move the nozzle as the point is edited
1415
             do_blocking_move_to_z(h_offset + new_z); // Move the nozzle as the point is edited
1538
           #endif
1416
           #endif
1539
           idle();
1417
           idle();
1540
-        }
1418
+        } while (!is_lcd_clicked());
1541
 
1419
 
1542
         if (!lcd_map_control) lcd_return_to_status();
1420
         if (!lcd_map_control) lcd_return_to_status();
1543
 
1421
 
1632
 
1510
 
1633
   #if HAS_BED_PROBE
1511
   #if HAS_BED_PROBE
1634
 
1512
 
1635
-    void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map) {
1513
+    void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_3_pt_leveling) {
1636
       constexpr int16_t x_min = max(MIN_PROBE_X, MESH_MIN_X),
1514
       constexpr int16_t x_min = max(MIN_PROBE_X, MESH_MIN_X),
1637
                         x_max = min(MAX_PROBE_X, MESH_MAX_X),
1515
                         x_max = min(MAX_PROBE_X, MESH_MAX_X),
1638
                         y_min = max(MIN_PROBE_Y, MESH_MIN_Y),
1516
                         y_min = max(MIN_PROBE_Y, MESH_MIN_Y),
1639
                         y_max = min(MAX_PROBE_Y, MESH_MAX_Y);
1517
                         y_max = min(MAX_PROBE_Y, MESH_MAX_Y);
1640
 
1518
 
1519
+      bool abort_flag=false;
1520
+
1521
+      float measured_z;
1522
+
1641
       const float dx = float(x_max - x_min) / (g29_grid_size - 1.0),
1523
       const float dx = float(x_max - x_min) / (g29_grid_size - 1.0),
1642
                   dy = float(y_max - y_min) / (g29_grid_size - 1.0);
1524
                   dy = float(y_max - y_min) / (g29_grid_size - 1.0);
1643
 
1525
 
1644
       struct linear_fit_data lsf_results;
1526
       struct linear_fit_data lsf_results;
1527
+
1528
+//    float z1, z2, z3;  // Needed for algorithm validation down below.
1529
+
1645
       incremental_LSF_reset(&lsf_results);
1530
       incremental_LSF_reset(&lsf_results);
1646
 
1531
 
1532
+      if (do_3_pt_leveling) {
1533
+        measured_z = probe_pt(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y, false, g29_verbose_level);
1534
+        if (isnan(measured_z))
1535
+          abort_flag = true;
1536
+        else {
1537
+          measured_z -= get_z_correction(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y);
1538
+//        z1 = measured_z;
1539
+          if (g29_verbose_level>3) {
1540
+            serial_spaces(16);
1541
+            SERIAL_ECHOLNPAIR("Corrected_Z=", measured_z);
1542
+          }
1543
+          incremental_LSF(&lsf_results, UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y, measured_z);
1544
+        }
1545
+
1546
+        if (!abort_flag) {
1547
+          measured_z = probe_pt(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y, false, g29_verbose_level);
1548
+//        z2 = measured_z;
1549
+          if (isnan(measured_z))
1550
+            abort_flag = true;
1551
+          else {
1552
+            measured_z -= get_z_correction(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y);
1553
+            if (g29_verbose_level>3) {
1554
+              serial_spaces(16);
1555
+              SERIAL_ECHOLNPAIR("Corrected_Z=", measured_z);
1556
+            }
1557
+            incremental_LSF(&lsf_results, UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y, measured_z);
1558
+          }
1559
+        }
1560
+
1561
+        if (!abort_flag) {
1562
+          measured_z = probe_pt(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y, true, g29_verbose_level);
1563
+//        z3 = measured_z;
1564
+          if (isnan(measured_z))
1565
+            abort_flag = true;
1566
+          else {
1567
+            measured_z -= get_z_correction(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y);
1568
+            if (g29_verbose_level>3) {
1569
+              serial_spaces(16);
1570
+              SERIAL_ECHOLNPAIR("Corrected_Z=", measured_z);
1571
+            }
1572
+            incremental_LSF(&lsf_results, UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y, measured_z);
1573
+          }
1574
+        }
1575
+
1576
+        if (abort_flag) {
1577
+          SERIAL_ECHOPGM("?Error probing point.  Aborting operation.\n");
1578
+          return;
1579
+        }
1580
+      } else {
1581
+
1647
       bool zig_zag = false;
1582
       bool zig_zag = false;
1648
       for (uint8_t ix = 0; ix < g29_grid_size; ix++) {
1583
       for (uint8_t ix = 0; ix < g29_grid_size; ix++) {
1649
         const float rx = float(x_min) + ix * dx;
1584
         const float rx = float(x_min) + ix * dx;
1650
         for (int8_t iy = 0; iy < g29_grid_size; iy++) {
1585
         for (int8_t iy = 0; iy < g29_grid_size; iy++) {
1651
           const float ry = float(y_min) + dy * (zig_zag ? g29_grid_size - 1 - iy : iy);
1586
           const float ry = float(y_min) + dy * (zig_zag ? g29_grid_size - 1 - iy : iy);
1652
-          float measured_z = probe_pt(rx, ry, parser.seen('E'), g29_verbose_level); // TODO: Needs error handling
1587
+
1588
+            if (!abort_flag) {
1589
+              measured_z = probe_pt(rx, ry, parser.seen('E'), g29_verbose_level); // TODO: Needs error handling
1590
+
1591
+              if (isnan(measured_z))
1592
+                abort_flag = true;
1593
+
1653
           #if ENABLED(DEBUG_LEVELING_FEATURE)
1594
           #if ENABLED(DEBUG_LEVELING_FEATURE)
1654
             if (DEBUGGING(LEVELING)) {
1595
             if (DEBUGGING(LEVELING)) {
1655
               SERIAL_CHAR('(');
1596
               SERIAL_CHAR('(');
1680
 
1621
 
1681
           incremental_LSF(&lsf_results, rx, ry, measured_z);
1622
           incremental_LSF(&lsf_results, rx, ry, measured_z);
1682
         }
1623
         }
1624
+          }
1683
 
1625
 
1684
         zig_zag ^= true;
1626
         zig_zag ^= true;
1685
       }
1627
       }
1686
 
1628
 
1687
-      if (finish_incremental_LSF(&lsf_results)) {
1629
+      }
1630
+
1631
+      if (abort_flag || finish_incremental_LSF(&lsf_results)) {
1688
         SERIAL_ECHOPGM("Could not complete LSF!");
1632
         SERIAL_ECHOPGM("Could not complete LSF!");
1689
         return;
1633
         return;
1690
       }
1634
       }
1691
 
1635
 
1692
-      if (g29_verbose_level > 3) {
1693
-        SERIAL_ECHOPGM("LSF Results A=");
1694
-        SERIAL_PROTOCOL_F(lsf_results.A, 7);
1695
-        SERIAL_ECHOPGM("  B=");
1696
-        SERIAL_PROTOCOL_F(lsf_results.B, 7);
1697
-        SERIAL_ECHOPGM("  D=");
1698
-        SERIAL_PROTOCOL_F(lsf_results.D, 7);
1699
-        SERIAL_EOL();
1700
-      }
1701
 
1636
 
1702
       vector_3 normal = vector_3(lsf_results.A, lsf_results.B, 1.0000).get_normal();
1637
       vector_3 normal = vector_3(lsf_results.A, lsf_results.B, 1.0000).get_normal();
1703
 
1638
 
1753
 
1688
 
1754
       #if ENABLED(DEBUG_LEVELING_FEATURE)
1689
       #if ENABLED(DEBUG_LEVELING_FEATURE)
1755
         if (DEBUGGING(LEVELING)) {
1690
         if (DEBUGGING(LEVELING)) {
1756
-          rotation.debug(PSTR("rotation matrix:"));
1691
+          rotation.debug(PSTR("rotation matrix:\n"));
1757
           SERIAL_ECHOPGM("LSF Results A=");
1692
           SERIAL_ECHOPGM("LSF Results A=");
1758
           SERIAL_PROTOCOL_F(lsf_results.A, 7);
1693
           SERIAL_PROTOCOL_F(lsf_results.A, 7);
1759
           SERIAL_ECHOPGM("  B=");
1694
           SERIAL_ECHOPGM("  B=");
1771
           SERIAL_PROTOCOL_F(normal.z, 7);
1706
           SERIAL_PROTOCOL_F(normal.z, 7);
1772
           SERIAL_ECHOPGM("]\n");
1707
           SERIAL_ECHOPGM("]\n");
1773
           SERIAL_EOL();
1708
           SERIAL_EOL();
1709
+
1710
+/*
1711
+ * The following code can be used to check the validity of the mesh tilting algorithm.
1712
+ * When a 3-Point Mesh Tilt is done, the same algorithm is used as the grid based tilting.
1713
+ * The only difference is just 3 points are used in the calculations.   That fact guarantees
1714
+ * each probed point should have an exact match when a get_z_correction() for that location
1715
+ * is calculated.  The Z error between the probed point locations and the get_z_correction()
1716
+ * numbers for those locations should be 0.000
1717
+ */
1718
+/*
1719
+          float t, t1, d;
1720
+          t = normal.x * (UBL_PROBE_PT_1_X) + normal.y * (UBL_PROBE_PT_1_Y);
1721
+          d = t + normal.z * z1;
1722
+          SERIAL_ECHOPGM("D from 1st point: ");
1723
+          SERIAL_ECHO_F(d, 6);
1724
+          SERIAL_ECHO("   Z error: ");
1725
+          SERIAL_ECHO_F(normal.z*z1-get_z_correction(UBL_PROBE_PT_1_X, UBL_PROBE_PT_1_Y),6);
1726
+          SERIAL_EOL();
1727
+
1728
+          t = normal.x * (UBL_PROBE_PT_2_X) + normal.y * (UBL_PROBE_PT_2_Y);
1729
+          d = t + normal.z * z2;
1730
+          SERIAL_EOL();
1731
+          SERIAL_ECHOPGM("D from 2nd point: ");
1732
+          SERIAL_ECHO_F(d, 6);
1733
+          SERIAL_ECHO("   Z error: ");
1734
+          SERIAL_ECHO_F(normal.z*z2-get_z_correction(UBL_PROBE_PT_2_X, UBL_PROBE_PT_2_Y),6);
1735
+          SERIAL_EOL();
1736
+
1737
+          t = normal.x * (UBL_PROBE_PT_3_X) + normal.y * (UBL_PROBE_PT_3_Y);
1738
+          d = t + normal.z * z3;
1739
+          SERIAL_ECHOPGM("D from 3rd point: ");
1740
+          SERIAL_ECHO_F(d, 6);
1741
+          SERIAL_ECHO("   Z error: ");
1742
+          SERIAL_ECHO_F(normal.z*z3-get_z_correction(UBL_PROBE_PT_3_X, UBL_PROBE_PT_3_Y),6);
1743
+          SERIAL_EOL();
1744
+
1745
+          t = normal.x * (Z_SAFE_HOMING_X_POINT) + normal.y * (Z_SAFE_HOMING_Y_POINT);
1746
+          d = t + normal.z * 0.000;
1747
+          SERIAL_ECHOPGM("D from home location with Z=0 : ");
1748
+          SERIAL_ECHO_F(d, 6);
1749
+          SERIAL_EOL();
1750
+
1751
+          t = normal.x * (Z_SAFE_HOMING_X_POINT) + normal.y * (Z_SAFE_HOMING_Y_POINT);
1752
+          d = t + get_z_correction(Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT); // normal.z * 0.000;
1753
+          SERIAL_ECHOPGM("D from home location using mesh value for Z: ");
1754
+          SERIAL_ECHO_F(d, 6);
1755
+
1756
+          SERIAL_ECHOPAIR("   Z error: (", Z_SAFE_HOMING_X_POINT );
1757
+          SERIAL_ECHOPAIR(",", Z_SAFE_HOMING_Y_POINT );
1758
+          SERIAL_ECHO(") = ");
1759
+          SERIAL_ECHO_F( get_z_correction(Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT),6);
1760
+          SERIAL_EOL();
1761
+*/
1774
         }
1762
         }
1775
       #endif
1763
       #endif
1776
 
1764
 
1777
-      if (do_ubl_mesh_map) display_map(g29_map_type);
1778
     }
1765
     }
1779
 
1766
 
1780
   #endif // HAS_BED_PROBE
1767
   #endif // HAS_BED_PROBE

+ 15
- 6
Marlin/src/gcode/bedlevel/G26.cpp View File

165
     if (!is_lcd_clicked()) return false; // Return if the button isn't pressed
165
     if (!is_lcd_clicked()) return false; // Return if the button isn't pressed
166
     lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99);
166
     lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99);
167
     #if ENABLED(ULTIPANEL)
167
     #if ENABLED(ULTIPANEL)
168
-      lcd_quick_feedback();
168
+      lcd_quick_feedback(true);
169
     #endif
169
     #endif
170
     wait_for_release();
170
     wait_for_release();
171
     return true;
171
     return true;
421
     #if ENABLED(ULTRA_LCD)
421
     #if ENABLED(ULTRA_LCD)
422
       if (g26_bed_temp > 25) {
422
       if (g26_bed_temp > 25) {
423
         lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99);
423
         lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99);
424
-        lcd_quick_feedback();
424
+        lcd_quick_feedback(true);
425
         lcd_external_control = true;
425
         lcd_external_control = true;
426
     #endif
426
     #endif
427
         thermalManager.setTargetBed(g26_bed_temp);
427
         thermalManager.setTargetBed(g26_bed_temp);
441
     #if ENABLED(ULTRA_LCD)
441
     #if ENABLED(ULTRA_LCD)
442
       }
442
       }
443
       lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99);
443
       lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99);
444
-      lcd_quick_feedback();
444
+      lcd_quick_feedback(true);
445
     #endif
445
     #endif
446
   #endif
446
   #endif
447
 
447
 
463
 
463
 
464
   #if ENABLED(ULTRA_LCD)
464
   #if ENABLED(ULTRA_LCD)
465
     lcd_reset_status();
465
     lcd_reset_status();
466
-    lcd_quick_feedback();
466
+    lcd_quick_feedback(true);
467
   #endif
467
   #endif
468
 
468
 
469
   return G26_OK;
469
   return G26_OK;
509
       strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue;
509
       strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue;
510
                                                           // So... We cheat to get a message up.
510
                                                           // So... We cheat to get a message up.
511
       lcd_setstatusPGM(PSTR("Done Priming"), 99);
511
       lcd_setstatusPGM(PSTR("Done Priming"), 99);
512
-      lcd_quick_feedback();
512
+      lcd_quick_feedback(true);
513
       lcd_external_control = false;
513
       lcd_external_control = false;
514
     }
514
     }
515
     else
515
     else
517
   {
517
   {
518
     #if ENABLED(ULTRA_LCD)
518
     #if ENABLED(ULTRA_LCD)
519
       lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99);
519
       lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99);
520
-      lcd_quick_feedback();
520
+      lcd_quick_feedback(true);
521
     #endif
521
     #endif
522
     set_destination_from_current();
522
     set_destination_from_current();
523
     destination[E_AXIS] += g26_prime_length;
523
     destination[E_AXIS] += g26_prime_length;
680
   set_bed_leveling_enabled(!parser.seen('D'));
680
   set_bed_leveling_enabled(!parser.seen('D'));
681
 
681
 
682
   if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
682
   if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
683
+SERIAL_PROTOCOLLNPGM("! move nozzle to Z_CLEARANCE_BETWEEN_PROBES height.");
684
+SERIAL_ECHOLNPAIR("  Z at:", current_position[Z_AXIS]);
683
     do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
685
     do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
684
     stepper.synchronize();
686
     stepper.synchronize();
685
     set_current_from_destination();
687
     set_current_from_destination();
688
+SERIAL_ECHOLNPAIR("  Z now at:", current_position[Z_AXIS]);
686
   }
689
   }
687
 
690
 
688
   if (turn_on_heaters() != G26_OK) goto LEAVE;
691
   if (turn_on_heaters() != G26_OK) goto LEAVE;
708
 
711
 
709
   // Move nozzle to the specified height for the first layer
712
   // Move nozzle to the specified height for the first layer
710
   set_destination_from_current();
713
   set_destination_from_current();
714
+SERIAL_PROTOCOLLNPGM("! moving nozzle to 1st layer height.");
715
+SERIAL_ECHOLNPAIR("  Z1 at:", current_position[Z_AXIS]);
716
+
711
   destination[Z_AXIS] = g26_layer_height;
717
   destination[Z_AXIS] = g26_layer_height;
712
   move_to(destination, 0.0);
718
   move_to(destination, 0.0);
719
+  stepper.synchronize();
720
+  set_destination_from_current();
721
+SERIAL_ECHOLNPAIR("  Z2 at:", current_position[Z_AXIS]);
713
   move_to(destination, g26_ooze_amount);
722
   move_to(destination, g26_ooze_amount);
714
 
723
 
715
   #if ENABLED(ULTRA_LCD)
724
   #if ENABLED(ULTRA_LCD)

+ 8
- 5
Marlin/src/lcd/ultralcd.cpp View File

774
     #endif
774
     #endif
775
   }
775
   }
776
 
776
 
777
-  void lcd_quick_feedback() {
777
+  void lcd_quick_feedback(const bool clear_buttons) {
778
     lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
778
     lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
779
-    buttons = 0;
779
+
780
+    if (clear_buttons)
781
+      buttons = 0;
782
+
780
     next_button_update_ms = millis() + 500;
783
     next_button_update_ms = millis() + 500;
781
 
784
 
782
     // Buzz and wait. The delay is needed for buttons to settle!
785
     // Buzz and wait. The delay is needed for buttons to settle!
4672
         if (encoderDirection == -1) { // side effect which signals we are inside a menu
4675
         if (encoderDirection == -1) { // side effect which signals we are inside a menu
4673
           if      (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN)  encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM;
4676
           if      (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_DOWN)  encoderPosition -= ENCODER_STEPS_PER_MENU_ITEM;
4674
           else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP)    encoderPosition += ENCODER_STEPS_PER_MENU_ITEM;
4677
           else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_UP)    encoderPosition += ENCODER_STEPS_PER_MENU_ITEM;
4675
-          else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT)  { menu_action_back(); lcd_quick_feedback(); }
4676
-          else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) { lcd_return_to_status(); lcd_quick_feedback(); }
4678
+          else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_LEFT)  { menu_action_back(); lcd_quick_feedback(true); }
4679
+          else if (buttons_reprapworld_keypad & EN_REPRAPWORLD_KEYPAD_RIGHT) { lcd_return_to_status(); lcd_quick_feedback(true); }
4677
         }
4680
         }
4678
         else {
4681
         else {
4679
           if (buttons_reprapworld_keypad & (EN_REPRAPWORLD_KEYPAD_DOWN|EN_REPRAPWORLD_KEYPAD_UP|EN_REPRAPWORLD_KEYPAD_RIGHT)) {
4682
           if (buttons_reprapworld_keypad & (EN_REPRAPWORLD_KEYPAD_DOWN|EN_REPRAPWORLD_KEYPAD_UP|EN_REPRAPWORLD_KEYPAD_RIGHT)) {
4941
         wait_for_unclick = true;         //  Set debounce flag to ignore continous clicks
4944
         wait_for_unclick = true;         //  Set debounce flag to ignore continous clicks
4942
         lcd_clicked = !wait_for_user && !no_reentry; //  Keep the click if not waiting for a user-click
4945
         lcd_clicked = !wait_for_user && !no_reentry; //  Keep the click if not waiting for a user-click
4943
         wait_for_user = false;           //  Any click clears wait for user
4946
         wait_for_user = false;           //  Any click clears wait for user
4944
-        lcd_quick_feedback();            //  Always make a click sound
4947
+        lcd_quick_feedback(true);        //  Always make a click sound
4945
       }
4948
       }
4946
     }
4949
     }
4947
     else wait_for_unclick = false;
4950
     else wait_for_unclick = false;

+ 1
- 1
Marlin/src/lcd/ultralcd.h View File

116
 
116
 
117
     extern volatile uint8_t buttons;  // The last-checked buttons in a bit array.
117
     extern volatile uint8_t buttons;  // The last-checked buttons in a bit array.
118
     void lcd_buttons_update();
118
     void lcd_buttons_update();
119
-    void lcd_quick_feedback();        // Audible feedback for a button click - could also be visual
119
+    void lcd_quick_feedback(const bool clear_buttons); // Audible feedback for a button click - could also be visual
120
     void lcd_completion_feedback(const bool good=true);
120
     void lcd_completion_feedback(const bool good=true);
121
 
121
 
122
     #if ENABLED(ADVANCED_PAUSE_FEATURE)
122
     #if ENABLED(ADVANCED_PAUSE_FEATURE)

Loading…
Cancel
Save