Ver código fonte

Make G26 work with all mesh leveling.

Example Configuration.h files are not updated yet.   You need to cross
your settings over to the default Configuration.h file in the \Marlin
directory.   (UBL_G26_MESH_VALIDATION enablement has moved to a new
location in the file.)
Roxy-3D 6 anos atrás
pai
commit
8282d732c1

+ 3
- 3
.travis.yml Ver arquivo

99
   # Test a probeless build of AUTO_BED_LEVELING_UBL
99
   # Test a probeless build of AUTO_BED_LEVELING_UBL
100
   #
100
   #
101
   - restore_configs
101
   - restore_configs
102
-  - opt_enable AUTO_BED_LEVELING_UBL UBL_G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT EEPROM_SETTINGS G3D_PANEL
102
+  - opt_enable AUTO_BED_LEVELING_UBL G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT EEPROM_SETTINGS G3D_PANEL
103
   - opt_enable_adv CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING
103
   - opt_enable_adv CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING
104
   - build_marlin
104
   - build_marlin
105
   #
105
   #
128
   # Test MESH_BED_LEVELING feature, with LCD
128
   # Test MESH_BED_LEVELING feature, with LCD
129
   #
129
   #
130
   - restore_configs
130
   - restore_configs
131
-  - opt_enable MESH_BED_LEVELING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER
131
+  - opt_enable MESH_BED_LEVELING G26_MESH_EDITING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER
132
   - build_marlin
132
   - build_marlin
133
   #
133
   #
134
   # Test MINIRAMBO for PWM_MOTOR_CURRENT
134
   # Test MINIRAMBO for PWM_MOTOR_CURRENT
142
   #
142
   #
143
   - restore_configs
143
   - restore_configs
144
   - opt_set MOTHERBOARD BOARD_MINIRAMBO
144
   - opt_set MOTHERBOARD BOARD_MINIRAMBO
145
-  - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR LCD_BED_LEVELING ULTIMAKERCONTROLLER
145
+  - opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR G26_MESH_EDITING LCD_BED_LEVELING ULTIMAKERCONTROLLER
146
   - opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER M100_FREE_MEMORY_DUMPER M100_FREE_MEMORY_CORRUPTOR INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT
146
   - opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER M100_FREE_MEMORY_DUMPER M100_FREE_MEMORY_CORRUPTOR INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT
147
   - opt_enable ULTIMAKERCONTROLLER SDSUPPORT
147
   - opt_enable ULTIMAKERCONTROLLER SDSUPPORT
148
   - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 USE_XMAX_PLUG
148
   - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 USE_XMAX_PLUG

+ 12
- 7
Marlin/Configuration.h Ver arquivo

890
   // at which point movement will be level to the machine's XY plane.
890
   // at which point movement will be level to the machine's XY plane.
891
   // The height can be set with M420 Z<height>
891
   // The height can be set with M420 Z<height>
892
   #define ENABLE_LEVELING_FADE_HEIGHT
892
   #define ENABLE_LEVELING_FADE_HEIGHT
893
+
894
+  /**
895
+   * Enable the G26 Mesh Validation Pattern tool.
896
+   */
897
+  #define G26_MESH_VALIDATION   // Enable G26 mesh validation
898
+  #if ENABLED(G26_MESH_VALIDATION)
899
+    #define MESH_TEST_NOZZLE_SIZE     0.4   // (mm) Diameter of primary nozzle.
900
+    #define MESH_TEST_LAYER_HEIGHT    0.2   // (mm) Default layer height for the G26 Mesh Validation Tool.
901
+    #define MESH_TEST_HOTEND_TEMP   205.0   // (°C) Default nozzle temperature for the G26 Mesh Validation Tool.
902
+    #define MESH_TEST_BED_TEMP       60.0   // (°C) Default bed temperature for the G26 Mesh Validation Tool.
903
+  #endif
904
+
893
 #endif
905
 #endif
894
 
906
 
895
 #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
907
 #if ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR)
956
   #define UBL_PROBE_PT_3_X 180
968
   #define UBL_PROBE_PT_3_X 180
957
   #define UBL_PROBE_PT_3_Y 20
969
   #define UBL_PROBE_PT_3_Y 20
958
 
970
 
959
-  //#define UBL_G26_MESH_VALIDATION // Enable G26 mesh validation
960
-  #if ENABLED(UBL_G26_MESH_VALIDATION)
961
-    #define MESH_TEST_NOZZLE_SIZE     0.4   // (mm) Diameter of primary nozzle.
962
-    #define MESH_TEST_LAYER_HEIGHT    0.2   // (mm) Default layer height for the G26 Mesh Validation Tool.
963
-    #define MESH_TEST_HOTEND_TEMP   205.0   // (°C) Default nozzle temperature for the G26 Mesh Validation Tool.
964
-    #define MESH_TEST_BED_TEMP       60.0   // (°C) Default bed temperature for the G26 Mesh Validation Tool.
965
-  #endif
966
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
971
   #define UBL_MESH_EDIT_MOVES_Z     // Sophisticated users prefer no movement of nozzle
967
   #define UBL_SAVE_ACTIVE_ON_M500   // Save the currently active mesh in the current slot on M500
972
   #define UBL_SAVE_ACTIVE_ON_M500   // Save the currently active mesh in the current slot on M500
968
 
973
 

+ 94
- 72
Marlin/G26_Mesh_Validation_Tool.cpp Ver arquivo

26
 
26
 
27
 #include "MarlinConfig.h"
27
 #include "MarlinConfig.h"
28
 
28
 
29
-#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION)
29
+#if ENABLED(G26_MESH_VALIDATION)
30
 
30
 
31
-  #include "ubl.h"
32
   #include "Marlin.h"
31
   #include "Marlin.h"
33
   #include "planner.h"
32
   #include "planner.h"
34
   #include "stepper.h"
33
   #include "stepper.h"
35
   #include "temperature.h"
34
   #include "temperature.h"
36
   #include "ultralcd.h"
35
   #include "ultralcd.h"
37
   #include "gcode.h"
36
   #include "gcode.h"
37
+  #include "bitmap_flags.h"
38
+
39
+  #if ENABLED(MESH_BED_LEVELING)
40
+    #include "mesh_bed_leveling.h"
41
+  #elif ENABLED(AUTO_BED_LEVELING_UBL)
42
+    #include "ubl.h"
43
+  #endif
38
 
44
 
39
   #define EXTRUSION_MULTIPLIER 1.0
45
   #define EXTRUSION_MULTIPLIER 1.0
40
   #define RETRACTION_MULTIPLIER 1.0
46
   #define RETRACTION_MULTIPLIER 1.0
48
     #error "SIZE_OF_CROSSHAIRS must be less than SIZE_OF_INTERSECTION_CIRCLES."
54
     #error "SIZE_OF_CROSSHAIRS must be less than SIZE_OF_INTERSECTION_CIRCLES."
49
   #endif
55
   #endif
50
 
56
 
57
+  #define G26_OK false
58
+  #define G26_ERROR true
59
+
51
   /**
60
   /**
52
    *   G26 Mesh Validation Tool
61
    *   G26 Mesh Validation Tool
53
    *
62
    *
146
 
155
 
147
   static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
156
   static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
148
                                      // retracts/recovers won't result in a bad state.
157
                                      // retracts/recovers won't result in a bad state.
149
-
150
   float valid_trig_angle(float);
158
   float valid_trig_angle(float);
151
 
159
 
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;
161
-
162
-  int16_t unified_bed_leveling::g26_bed_temp,
163
-          unified_bed_leveling::g26_hotend_temp;
164
-
165
-  int8_t unified_bed_leveling::g26_prime_flag;
166
-
167
-  bool unified_bed_leveling::g26_continue_with_closest,
168
-       unified_bed_leveling::g26_keep_heaters_on;
169
-
170
-  int16_t unified_bed_leveling::g26_repeats;
171
-
172
-  void unified_bed_leveling::G26_line_to_destination(const float &feed_rate) {
160
+  void G26_line_to_destination(const float &feed_rate) {
173
     const float save_feedrate = feedrate_mm_s;
161
     const float save_feedrate = feedrate_mm_s;
174
     feedrate_mm_s = feed_rate;      // use specified feed rate
162
     feedrate_mm_s = feed_rate;      // use specified feed rate
175
-    prepare_move_to_destination();  // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_DELTA
163
+    prepare_move_to_destination();  // will ultimately call ubl.line_to_destination_cartesian for UBL or ubl.prepare_linear_move_to for UBL_DELTA
176
     feedrate_mm_s = save_feedrate;  // restore global feed rate
164
     feedrate_mm_s = save_feedrate;  // restore global feed rate
177
   }
165
   }
166
+  static bool exit_from_g26();
167
+  static bool parse_G26_parameters();
168
+  static mesh_index_pair find_closest_circle_to_print(const float&, const float&);
169
+  static bool look_for_lines_to_connect();
170
+  static bool turn_on_heaters();
171
+  static bool prime_nozzle();
172
+  static void retract_filament(const float where[XYZE]);
173
+  static void recover_filament(const float where[XYZE]);
174
+  static void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&);
175
+  static void move_to(const float&, const float&, const float&, const float&);
176
+  #if ENABLED(NEWPANEL)
177
+    extern bool ubl_lcd_clicked();
178
+  #endif
179
+  static void move_to(const float where[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); }
180
+
181
+  static float   g26_extrusion_multiplier,
182
+                 g26_retraction_multiplier,
183
+                 g26_nozzle,
184
+                 g26_filament_diameter,
185
+                 g26_prime_length,
186
+                 g26_x_pos, g26_y_pos,
187
+                 g26_ooze_amount,
188
+                 g26_layer_height;
189
+  static int16_t g26_bed_temp,
190
+                 g26_hotend_temp,
191
+                 g26_repeats;
192
+  static int8_t  g26_prime_flag;
193
+  static bool    g26_continue_with_closest, g26_keep_heaters_on;
178
 
194
 
179
   #if ENABLED(NEWPANEL)
195
   #if ENABLED(NEWPANEL)
180
     /**
196
     /**
207
    * Used to interactively edit UBL's Mesh by placing the
223
    * Used to interactively edit UBL's Mesh by placing the
208
    * nozzle in a problem area and doing a G29 P4 R command.
224
    * nozzle in a problem area and doing a G29 P4 R command.
209
    */
225
    */
210
-  void unified_bed_leveling::G26() {
226
+  void gcode_G26() {
211
     SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s).");
227
     SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s).");
212
     float tmp, start_angle, end_angle;
228
     float tmp, start_angle, end_angle;
213
     int   i, xi, yi;
229
     int   i, xi, yi;
250
     move_to(destination, 0.0);
266
     move_to(destination, 0.0);
251
     move_to(destination, g26_ooze_amount);
267
     move_to(destination, g26_ooze_amount);
252
 
268
 
253
-    has_control_of_lcd_panel = true;
269
+    #if ENABLED(ULTRA_LCD)
270
+      lcd_external_control = true;
271
+    #endif
272
+
254
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
273
     //debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
255
 
274
 
256
     /**
275
     /**
269
         : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now.
288
         : find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now.
270
 
289
 
271
       if (location.x_index >= 0 && location.y_index >= 0) {
290
       if (location.x_index >= 0 && location.y_index >= 0) {
272
-        const float circle_x = mesh_index_to_xpos(location.x_index),
273
-                    circle_y = mesh_index_to_ypos(location.y_index);
291
+        const float circle_x = _GET_MESH_X(location.x_index),
292
+                    circle_y = _GET_MESH_Y(location.y_index);
274
 
293
 
275
         // If this mesh location is outside the printable_radius, skip it.
294
         // If this mesh location is outside the printable_radius, skip it.
276
 
295
 
373
     move_to(destination, 0); // Move back to the starting position
392
     move_to(destination, 0); // Move back to the starting position
374
     //debug_current_and_destination(PSTR("done doing X/Y move."));
393
     //debug_current_and_destination(PSTR("done doing X/Y move."));
375
 
394
 
376
-    has_control_of_lcd_panel = false;     // Give back control of the LCD Panel!
395
+    #if ENABLED(ULTRA_LCD)
396
+      lcd_external_control = false;     // Give back control of the LCD Panel!
397
+    #endif
377
 
398
 
378
     if (!g26_keep_heaters_on) {
399
     if (!g26_keep_heaters_on) {
379
       #if HAS_TEMP_BED
400
       #if HAS_TEMP_BED
389
     return d;
410
     return d;
390
   }
411
   }
391
 
412
 
392
-  mesh_index_pair unified_bed_leveling::find_closest_circle_to_print(const float &X, const float &Y) {
413
+  mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
393
     float closest = 99999.99;
414
     float closest = 99999.99;
394
     mesh_index_pair return_val;
415
     mesh_index_pair return_val;
395
 
416
 
398
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
419
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
399
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
420
       for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
400
         if (!is_bit_set(circle_flags, i, j)) {
421
         if (!is_bit_set(circle_flags, i, j)) {
401
-          const float mx = mesh_index_to_xpos(i),  // We found a circle that needs to be printed
402
-                      my = mesh_index_to_ypos(j);
422
+          const float mx = _GET_MESH_X(i),  // We found a circle that needs to be printed
423
+                      my = _GET_MESH_Y(j);
403
 
424
 
404
           // Get the distance to this intersection
425
           // Get the distance to this intersection
405
           float f = HYPOT(X - mx, Y - my);
426
           float f = HYPOT(X - mx, Y - my);
427
     return return_val;
448
     return return_val;
428
   }
449
   }
429
 
450
 
430
-  bool unified_bed_leveling::look_for_lines_to_connect() {
451
+  bool look_for_lines_to_connect() {
431
     float sx, sy, ex, ey;
452
     float sx, sy, ex, ey;
432
 
453
 
433
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
454
     for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
447
               // We found two circles that need a horizontal line to connect them
468
               // We found two circles that need a horizontal line to connect them
448
               // Print it!
469
               // Print it!
449
               //
470
               //
450
-              sx = mesh_index_to_xpos(  i  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
451
-              ex = mesh_index_to_xpos(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge
471
+              sx = _GET_MESH_X(  i  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // right edge
472
+              ex = _GET_MESH_X(i + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // left edge
452
 
473
 
453
               sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
474
               sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
454
-              sy = ey = constrain(mesh_index_to_ypos(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
475
+              sy = ey = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
455
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
476
               ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
456
 
477
 
457
               if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) {
478
               if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) {
480
                 // We found two circles that need a vertical line to connect them
501
                 // We found two circles that need a vertical line to connect them
481
                 // Print it!
502
                 // Print it!
482
                 //
503
                 //
483
-                sy = mesh_index_to_ypos(  j  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
484
-                ey = mesh_index_to_ypos(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge
504
+                sy = _GET_MESH_Y(  j  ) + (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // top edge
505
+                ey = _GET_MESH_Y(j + 1) - (SIZE_OF_INTERSECTION_CIRCLES - (SIZE_OF_CROSSHAIRS)); // bottom edge
485
 
506
 
486
-                sx = ex = constrain(mesh_index_to_xpos(i), X_MIN_POS + 1, X_MAX_POS - 1);
507
+                sx = ex = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1);
487
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
508
                 sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
488
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
509
                 ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
489
 
510
 
496
                     SERIAL_ECHOPAIR(", ey=", ey);
517
                     SERIAL_ECHOPAIR(", ey=", ey);
497
                     SERIAL_CHAR(')');
518
                     SERIAL_CHAR(')');
498
                     SERIAL_EOL();
519
                     SERIAL_EOL();
499
-                    debug_current_and_destination(PSTR("Connecting vertical line."));
520
+
521
+                    #if ENABLED(AUTO_BED_LEVELING_UBL)
522
+                      debug_current_and_destination(PSTR("Connecting vertical line."));
523
+                    #endif
500
                   }
524
                   }
501
                   print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height);
525
                   print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height);
502
                 }
526
                 }
510
     return false;
534
     return false;
511
   }
535
   }
512
 
536
 
513
-  void unified_bed_leveling::move_to(const float &x, const float &y, const float &z, const float &e_delta) {
537
+  void move_to(const float &x, const float &y, const float &z, const float &e_delta) {
514
     float feed_value;
538
     float feed_value;
515
     static float last_z = -999.99;
539
     static float last_z = -999.99;
516
 
540
 
548
 
572
 
549
   }
573
   }
550
 
574
 
551
-  void unified_bed_leveling::retract_filament(const float where[XYZE]) {
575
+  void retract_filament(const float where[XYZE]) {
552
     if (!g26_retracted) { // Only retract if we are not already retracted!
576
     if (!g26_retracted) { // Only retract if we are not already retracted!
553
       g26_retracted = true;
577
       g26_retracted = true;
554
       move_to(where, -1.0 * g26_retraction_multiplier);
578
       move_to(where, -1.0 * g26_retraction_multiplier);
555
     }
579
     }
556
   }
580
   }
557
 
581
 
558
-  void unified_bed_leveling::recover_filament(const float where[XYZE]) {
582
+  void recover_filament(const float where[XYZE]) {
559
     if (g26_retracted) { // Only un-retract if we are retracted.
583
     if (g26_retracted) { // Only un-retract if we are retracted.
560
       move_to(where, 1.2 * g26_retraction_multiplier);
584
       move_to(where, 1.2 * g26_retraction_multiplier);
561
       g26_retracted = false;
585
       g26_retracted = false;
577
    * segment of a 'circle'. The time this requires is very short and is easily saved by the other
601
    * segment of a 'circle'. The time this requires is very short and is easily saved by the other
578
    * cases where the optimization comes into play.
602
    * cases where the optimization comes into play.
579
    */
603
    */
580
-  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) {
604
+  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) {
581
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
605
     const float dx_s = current_position[X_AXIS] - sx,   // find our distance from the start of the actual line segment
582
                 dy_s = current_position[Y_AXIS] - sy,
606
                 dy_s = current_position[Y_AXIS] - sy,
583
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
607
                 dist_start = HYPOT2(dx_s, dy_s),        // We don't need to do a sqrt(), we can compare the distance^2
615
    * parameters it made sense to turn them into static globals and get
639
    * parameters it made sense to turn them into static globals and get
616
    * this code out of sight of the main routine.
640
    * this code out of sight of the main routine.
617
    */
641
    */
618
-  bool unified_bed_leveling::parse_G26_parameters() {
642
+  bool parse_G26_parameters() {
619
 
643
 
620
     g26_extrusion_multiplier  = EXTRUSION_MULTIPLIER;
644
     g26_extrusion_multiplier  = EXTRUSION_MULTIPLIER;
621
     g26_retraction_multiplier = RETRACTION_MULTIPLIER;
645
     g26_retraction_multiplier = RETRACTION_MULTIPLIER;
635
       g26_bed_temp = parser.value_celsius();
659
       g26_bed_temp = parser.value_celsius();
636
       if (!WITHIN(g26_bed_temp, 15, 140)) {
660
       if (!WITHIN(g26_bed_temp, 15, 140)) {
637
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
661
         SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible.");
638
-        return UBL_ERR;
662
+        return G26_ERROR;
639
       }
663
       }
640
     }
664
     }
641
 
665
 
643
       g26_layer_height = parser.value_linear_units();
667
       g26_layer_height = parser.value_linear_units();
644
       if (!WITHIN(g26_layer_height, 0.0, 2.0)) {
668
       if (!WITHIN(g26_layer_height, 0.0, 2.0)) {
645
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
669
         SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
646
-        return UBL_ERR;
670
+        return G26_ERROR;
647
       }
671
       }
648
     }
672
     }
649
 
673
 
652
         g26_retraction_multiplier = parser.value_float();
676
         g26_retraction_multiplier = parser.value_float();
653
         if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) {
677
         if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) {
654
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
678
           SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
655
-          return UBL_ERR;
679
+          return G26_ERROR;
656
         }
680
         }
657
       }
681
       }
658
       else {
682
       else {
659
         SERIAL_PROTOCOLLNPGM("?Retraction Multiplier must be specified.");
683
         SERIAL_PROTOCOLLNPGM("?Retraction Multiplier must be specified.");
660
-        return UBL_ERR;
684
+        return G26_ERROR;
661
       }
685
       }
662
     }
686
     }
663
 
687
 
665
       g26_nozzle = parser.value_float();
689
       g26_nozzle = parser.value_float();
666
       if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
690
       if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
667
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
691
         SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
668
-        return UBL_ERR;
692
+        return G26_ERROR;
669
       }
693
       }
670
     }
694
     }
671
 
695
 
675
           g26_prime_flag = -1;
699
           g26_prime_flag = -1;
676
         #else
700
         #else
677
           SERIAL_PROTOCOLLNPGM("?Prime length must be specified when not using an LCD.");
701
           SERIAL_PROTOCOLLNPGM("?Prime length must be specified when not using an LCD.");
678
-          return UBL_ERR;
702
+          return G26_ERROR;
679
         #endif
703
         #endif
680
       }
704
       }
681
       else {
705
       else {
683
         g26_prime_length = parser.value_linear_units();
707
         g26_prime_length = parser.value_linear_units();
684
         if (!WITHIN(g26_prime_length, 0.0, 25.0)) {
708
         if (!WITHIN(g26_prime_length, 0.0, 25.0)) {
685
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
709
           SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
686
-          return UBL_ERR;
710
+          return G26_ERROR;
687
         }
711
         }
688
       }
712
       }
689
     }
713
     }
692
       g26_filament_diameter = parser.value_linear_units();
716
       g26_filament_diameter = parser.value_linear_units();
693
       if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) {
717
       if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) {
694
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
718
         SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
695
-        return UBL_ERR;
719
+        return G26_ERROR;
696
       }
720
       }
697
     }
721
     }
698
     g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter); // If we aren't using 1.75mm filament, we need to
722
     g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter); // If we aren't using 1.75mm filament, we need to
705
       g26_hotend_temp = parser.value_celsius();
729
       g26_hotend_temp = parser.value_celsius();
706
       if (!WITHIN(g26_hotend_temp, 165, 280)) {
730
       if (!WITHIN(g26_hotend_temp, 165, 280)) {
707
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
731
         SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
708
-        return UBL_ERR;
732
+        return G26_ERROR;
709
       }
733
       }
710
     }
734
     }
711
 
735
 
720
     #else
744
     #else
721
       if (!parser.seen('R')) {
745
       if (!parser.seen('R')) {
722
         SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD.");
746
         SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD.");
723
-        return UBL_ERR;
747
+        return G26_ERROR;
724
       }
748
       }
725
       else
749
       else
726
         g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1;
750
         g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1;
727
     #endif
751
     #endif
728
     if (g26_repeats < 1) {
752
     if (g26_repeats < 1) {
729
       SERIAL_PROTOCOLLNPGM("?(R)epeat value not plausible; must be at least 1.");
753
       SERIAL_PROTOCOLLNPGM("?(R)epeat value not plausible; must be at least 1.");
730
-      return UBL_ERR;
754
+      return G26_ERROR;
731
     }
755
     }
732
 
756
 
733
     g26_x_pos = parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[X_AXIS];
757
     g26_x_pos = parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[X_AXIS];
734
     g26_y_pos = parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : current_position[Y_AXIS];
758
     g26_y_pos = parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : current_position[Y_AXIS];
735
     if (!position_is_reachable(g26_x_pos, g26_y_pos)) {
759
     if (!position_is_reachable(g26_x_pos, g26_y_pos)) {
736
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
760
       SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
737
-      return UBL_ERR;
761
+      return G26_ERROR;
738
     }
762
     }
739
 
763
 
740
     /**
764
     /**
742
      */
766
      */
743
     set_bed_leveling_enabled(!parser.seen('D'));
767
     set_bed_leveling_enabled(!parser.seen('D'));
744
 
768
 
745
-    return UBL_OK;
769
+    return G26_OK;
746
   }
770
   }
747
 
771
 
748
   #if ENABLED(NEWPANEL)
772
   #if ENABLED(NEWPANEL)
749
-    bool unified_bed_leveling::exit_from_g26() {
773
+    bool exit_from_g26() {
750
       lcd_setstatusPGM(PSTR("Leaving G26"), -1);
774
       lcd_setstatusPGM(PSTR("Leaving G26"), -1);
751
       while (ubl_lcd_clicked()) idle();
775
       while (ubl_lcd_clicked()) idle();
752
-      return UBL_ERR;
776
+      return G26_ERROR;
753
     }
777
     }
754
   #endif
778
   #endif
755
 
779
 
757
    * Turn on the bed and nozzle heat and
781
    * Turn on the bed and nozzle heat and
758
    * wait for them to get up to temperature.
782
    * wait for them to get up to temperature.
759
    */
783
    */
760
-  bool unified_bed_leveling::turn_on_heaters() {
784
+  bool turn_on_heaters() {
761
     millis_t next = millis() + 5000UL;
785
     millis_t next = millis() + 5000UL;
762
     #if HAS_TEMP_BED
786
     #if HAS_TEMP_BED
763
       #if ENABLED(ULTRA_LCD)
787
       #if ENABLED(ULTRA_LCD)
764
         if (g26_bed_temp > 25) {
788
         if (g26_bed_temp > 25) {
765
           lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99);
789
           lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99);
766
           lcd_quick_feedback();
790
           lcd_quick_feedback();
791
+          lcd_external_control = true;
767
       #endif
792
       #endif
768
-          has_control_of_lcd_panel = true;
769
           thermalManager.setTargetBed(g26_bed_temp);
793
           thermalManager.setTargetBed(g26_bed_temp);
770
           while (abs(thermalManager.degBed() - g26_bed_temp) > 3) {
794
           while (abs(thermalManager.degBed() - g26_bed_temp) > 3) {
771
 
795
 
808
       lcd_quick_feedback();
832
       lcd_quick_feedback();
809
     #endif
833
     #endif
810
 
834
 
811
-    return UBL_OK;
835
+    return G26_OK;
812
   }
836
   }
813
 
837
 
814
   /**
838
   /**
815
    * Prime the nozzle if needed. Return true on error.
839
    * Prime the nozzle if needed. Return true on error.
816
    */
840
    */
817
-  bool unified_bed_leveling::prime_nozzle() {
841
+  bool prime_nozzle() {
818
 
842
 
819
     #if ENABLED(NEWPANEL)
843
     #if ENABLED(NEWPANEL)
820
       float Total_Prime = 0.0;
844
       float Total_Prime = 0.0;
821
 
845
 
822
       if (g26_prime_flag == -1) {  // The user wants to control how much filament gets purged
846
       if (g26_prime_flag == -1) {  // The user wants to control how much filament gets purged
823
 
847
 
824
-        has_control_of_lcd_panel = true;
848
+        lcd_external_control = true;
825
         lcd_setstatusPGM(PSTR("User-Controlled Prime"), 99);
849
         lcd_setstatusPGM(PSTR("User-Controlled Prime"), 99);
826
         chirp_at_user();
850
         chirp_at_user();
827
 
851
 
834
           destination[E_AXIS] += 0.25;
858
           destination[E_AXIS] += 0.25;
835
           #ifdef PREVENT_LENGTHY_EXTRUDE
859
           #ifdef PREVENT_LENGTHY_EXTRUDE
836
             Total_Prime += 0.25;
860
             Total_Prime += 0.25;
837
-            if (Total_Prime >= EXTRUDE_MAXLENGTH) return UBL_ERR;
861
+            if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERROR;
838
           #endif
862
           #endif
839
           G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
863
           G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
840
 
864
 
853
                                                               // So... We cheat to get a message up.
877
                                                               // So... We cheat to get a message up.
854
           lcd_setstatusPGM(PSTR("Done Priming"), 99);
878
           lcd_setstatusPGM(PSTR("Done Priming"), 99);
855
           lcd_quick_feedback();
879
           lcd_quick_feedback();
880
+          lcd_external_control = false;
856
         #endif
881
         #endif
857
-
858
-        has_control_of_lcd_panel = false;
859
-
860
       }
882
       }
861
       else {
883
       else {
862
     #else
884
     #else
874
       retract_filament(destination);
896
       retract_filament(destination);
875
     }
897
     }
876
 
898
 
877
-    return UBL_OK;
899
+    return G26_OK;
878
   }
900
   }
879
 
901
 
880
-#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION
902
+#endif // G26_MESH_VALIDATION

+ 17
- 0
Marlin/Marlin.h Ver arquivo

311
   void forward_kinematics_SCARA(const float &a, const float &b);
311
   void forward_kinematics_SCARA(const float &a, const float &b);
312
 #endif
312
 #endif
313
 
313
 
314
+#if ENABLED(G26_MESH_VALIDATION)
315
+  extern bool g26_debug_flag;
316
+#elif ENABLED(AUTO_BED_LEVELING_UBL)
317
+  constexpr bool g26_debug_flag = false;
318
+#endif
319
+
320
+#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
321
+  #define _GET_MESH_X(I) bilinear_start[X_AXIS] + I * bilinear_grid_spacing[X_AXIS]
322
+  #define _GET_MESH_Y(J) bilinear_start[Y_AXIS] + J * bilinear_grid_spacing[Y_AXIS]
323
+#elif ENABLED(AUTO_BED_LEVELING_UBL)
324
+  #define _GET_MESH_X(I) ubl.mesh_index_to_xpos(I)
325
+  #define _GET_MESH_Y(J) ubl.mesh_index_to_ypos(J)
326
+#elif ENABLED(MESH_BED_LEVELING)
327
+  #define _GET_MESH_X(I) mbl.index_to_xpos[I]
328
+  #define _GET_MESH_Y(J) mbl.index_to_ypos[J]
329
+#endif
330
+
314
 #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
331
 #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
315
   extern int bilinear_grid_spacing[2], bilinear_start[2];
332
   extern int bilinear_grid_spacing[2], bilinear_start[2];
316
   extern float bilinear_grid_factor[2],
333
   extern float bilinear_grid_factor[2],

+ 15
- 21
Marlin/Marlin_main.cpp Ver arquivo

59
  * G19  - Select Plane YZ (Requires CNC_WORKSPACE_PLANES)
59
  * G19  - Select Plane YZ (Requires CNC_WORKSPACE_PLANES)
60
  * G20  - Set input units to inches (Requires INCH_MODE_SUPPORT)
60
  * G20  - Set input units to inches (Requires INCH_MODE_SUPPORT)
61
  * G21  - Set input units to millimeters (Requires INCH_MODE_SUPPORT)
61
  * G21  - Set input units to millimeters (Requires INCH_MODE_SUPPORT)
62
- * G26  - Mesh Validation Pattern (Requires UBL_G26_MESH_VALIDATION)
62
+ * G26  - Mesh Validation Pattern (Requires G26_MESH_VALIDATION)
63
  * G27  - Park Nozzle (Requires NOZZLE_PARK_FEATURE)
63
  * G27  - Park Nozzle (Requires NOZZLE_PARK_FEATURE)
64
  * G28  - Home one or more axes
64
  * G28  - Home one or more axes
65
  * G29  - Start or continue the bed leveling probe procedure (Requires bed leveling)
65
  * G29  - Start or continue the bed leveling probe procedure (Requires bed leveling)
326
   void M100_dump_routine(const char * const title, const char *start, const char *end);
326
   void M100_dump_routine(const char * const title, const char *start, const char *end);
327
 #endif
327
 #endif
328
 
328
 
329
+#if ENABLED(G26_MESH_VALIDATION)
330
+  bool g26_debug_flag; // =false
331
+  void gcode_G26();
332
+#endif
333
+
329
 #if ENABLED(SDSUPPORT)
334
 #if ENABLED(SDSUPPORT)
330
   CardReader card;
335
   CardReader card;
331
 #endif
336
 #endif
6197
         return;
6202
         return;
6198
       }
6203
       }
6199
 
6204
 
6200
-      #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
6201
-        #define _GET_MESH_X(I) bilinear_start[X_AXIS] + I * bilinear_grid_spacing[X_AXIS]
6202
-        #define _GET_MESH_Y(J) bilinear_start[Y_AXIS] + J * bilinear_grid_spacing[Y_AXIS]
6203
-      #elif ENABLED(AUTO_BED_LEVELING_UBL)
6204
-        #define _GET_MESH_X(I) ubl.mesh_index_to_xpos(I)
6205
-        #define _GET_MESH_Y(J) ubl.mesh_index_to_ypos(J)
6206
-      #elif ENABLED(MESH_BED_LEVELING)
6207
-        #define _GET_MESH_X(I) mbl.index_to_xpos[I]
6208
-        #define _GET_MESH_Y(J) mbl.index_to_ypos[J]
6209
-      #endif
6210
-
6211
       set_destination_from_current();
6205
       set_destination_from_current();
6212
       if (hasI) destination[X_AXIS] = _GET_MESH_X(ix);
6206
       if (hasI) destination[X_AXIS] = _GET_MESH_X(ix);
6213
       if (hasJ) destination[Y_AXIS] = _GET_MESH_Y(iy);
6207
       if (hasJ) destination[Y_AXIS] = _GET_MESH_Y(iy);
7567
 
7561
 
7568
 #endif // Z_MIN_PROBE_REPEATABILITY_TEST
7562
 #endif // Z_MIN_PROBE_REPEATABILITY_TEST
7569
 
7563
 
7570
-#if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION)
7564
+#if ENABLED(G26_MESH_VALIDATION)
7571
 
7565
 
7572
   inline void gcode_M49() {
7566
   inline void gcode_M49() {
7573
-    ubl.g26_debug_flag ^= true;
7574
-    SERIAL_PROTOCOLPGM("UBL Debug Flag turned ");
7575
-    serialprintPGM(ubl.g26_debug_flag ? PSTR("on.") : PSTR("off."));
7567
+    g26_debug_flag ^= true;
7568
+    SERIAL_PROTOCOLPGM("G26 Debug ");
7569
+    serialprintPGM(g26_debug_flag ? PSTR("on.") : PSTR("off."));
7576
   }
7570
   }
7577
 
7571
 
7578
-#endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION
7572
+#endif // G26_MESH_VALIDATION
7579
 
7573
 
7580
 #if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY)
7574
 #if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY)
7581
   /**
7575
   /**
11295
           break;
11289
           break;
11296
       #endif // INCH_MODE_SUPPORT
11290
       #endif // INCH_MODE_SUPPORT
11297
 
11291
 
11298
-      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION)
11292
+      #if ENABLED(G26_MESH_VALIDATION)
11299
         case 26: // G26: Mesh Validation Pattern generation
11293
         case 26: // G26: Mesh Validation Pattern generation
11300
           gcode_G26();
11294
           gcode_G26();
11301
           break;
11295
           break;
11302
-      #endif // AUTO_BED_LEVELING_UBL
11296
+      #endif // G26_MESH_VALIDATION
11303
 
11297
 
11304
       #if ENABLED(NOZZLE_PARK_FEATURE)
11298
       #if ENABLED(NOZZLE_PARK_FEATURE)
11305
         case 27: // G27: Nozzle Park
11299
         case 27: // G27: Nozzle Park
11459
           break;
11453
           break;
11460
       #endif // Z_MIN_PROBE_REPEATABILITY_TEST
11454
       #endif // Z_MIN_PROBE_REPEATABILITY_TEST
11461
 
11455
 
11462
-      #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION)
11456
+      #if ENABLED(G26_MESH_VALIDATION)
11463
         case 49: // M49: Turn on or off G26 debug flag for verbose output
11457
         case 49: // M49: Turn on or off G26 debug flag for verbose output
11464
           gcode_M49();
11458
           gcode_M49();
11465
           break;
11459
           break;
11466
-      #endif // AUTO_BED_LEVELING_UBL && UBL_G26_MESH_VALIDATION
11460
+      #endif // G26_MESH_VALIDATION
11467
 
11461
 
11468
       #if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY)
11462
       #if ENABLED(ULTRA_LCD) && ENABLED(LCD_SET_PROGRESS_MANUALLY)
11469
         case 73: // M73: Set print progress percentage
11463
         case 73: // M73: Set print progress percentage

+ 8
- 2
Marlin/SanityCheck.h Ver arquivo

180
   #error "MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration."
180
   #error "MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration."
181
 #elif defined(UBL_MESH_NUM_X_POINTS) || defined(UBL_MESH_NUM_Y_POINTS)
181
 #elif defined(UBL_MESH_NUM_X_POINTS) || defined(UBL_MESH_NUM_Y_POINTS)
182
   #error "UBL_MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration."
182
   #error "UBL_MESH_NUM_[XY]_POINTS is now GRID_MAX_POINTS_[XY]. Please update your configuration."
183
+#elif defined(UBL_G26_MESH_VALIDATION)
184
+  #error "UBL_G26_MESH_VALIDATION is now G26_MESH_VALIDATION. Please update your configuration."
183
 #elif defined(UBL_MESH_EDIT_ENABLED)
185
 #elif defined(UBL_MESH_EDIT_ENABLED)
184
-  #error "UBL_MESH_EDIT_ENABLED is now UBL_G26_MESH_VALIDATION. Please update your configuration."
186
+  #error "UBL_MESH_EDIT_ENABLED is now G26_MESH_VALIDATION. Please update your configuration."
185
 #elif defined(UBL_MESH_EDITING)
187
 #elif defined(UBL_MESH_EDITING)
186
-  #error "UBL_MESH_EDITING is now UBL_G26_MESH_VALIDATION. Please update your configuration."
188
+  #error "UBL_MESH_EDITING is now G26_MESH_VALIDATION. Please update your configuration."
187
 #elif defined(BLTOUCH_HEATERS_OFF)
189
 #elif defined(BLTOUCH_HEATERS_OFF)
188
   #error "BLTOUCH_HEATERS_OFF is now PROBING_HEATERS_OFF. Please update your configuration."
190
   #error "BLTOUCH_HEATERS_OFF is now PROBING_HEATERS_OFF. Please update your configuration."
189
 #elif defined(BEEPER)
191
 #elif defined(BEEPER)
804
 
806
 
805
 #endif
807
 #endif
806
 
808
 
809
+#if !HAS_MESH && ENABLED(G26_MESH_VALIDATION)
810
+  #error "G26_MESH_VALIDATION requires MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, or AUTO_BED_LEVELING_UBL."
811
+#endif
812
+
807
 /**
813
 /**
808
  * LCD_BED_LEVELING requirements
814
  * LCD_BED_LEVELING requirements
809
  */
815
  */

+ 38
- 0
Marlin/bitmap_flags.h Ver arquivo

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifndef _BITMAP_FLAGS_H_
24
+#define _BITMAP_FLAGS_H_
25
+
26
+#include "macros.h"
27
+
28
+/**
29
+ * These support functions allow the use of large bit arrays of flags that take very
30
+ * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration
31
+ * to unsigned long will allow us to go to 32x32 if higher resolution meshes are needed
32
+ * in the future.
33
+ */
34
+FORCE_INLINE void bit_clear(uint16_t bits[16], const uint8_t x, const uint8_t y) { CBI(bits[y], x); }
35
+FORCE_INLINE void bit_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { SBI(bits[y], x); }
36
+FORCE_INLINE bool is_bit_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
37
+
38
+#endif // _BITMAP_FLAGS_H_

+ 1
- 0
Marlin/planner.cpp Ver arquivo

58
  *
58
  *
59
  */
59
  */
60
 
60
 
61
+#include "MarlinConfig.h"
61
 #include "planner.h"
62
 #include "planner.h"
62
 #include "stepper.h"
63
 #include "stepper.h"
63
 #include "temperature.h"
64
 #include "temperature.h"

+ 5
- 0
Marlin/types.h Ver arquivo

25
 
25
 
26
 typedef unsigned long millis_t;
26
 typedef unsigned long millis_t;
27
 
27
 
28
+typedef struct {
29
+  int8_t x_index, y_index;
30
+  float distance; // When populated, the distance from the search location
31
+} mesh_index_pair;
32
+
28
 #endif
33
 #endif

+ 0
- 13
Marlin/ubl.cpp Ver arquivo

30
   #include "temperature.h"
30
   #include "temperature.h"
31
   #include "planner.h"
31
   #include "planner.h"
32
 
32
 
33
-  /**
34
-   * These support functions allow the use of large bit arrays of flags that take very
35
-   * little RAM. Currently they are limited to being 16x16 in size. Changing the declaration
36
-   * to unsigned long will allow us to go to 32x32 if higher resolution Mesh's are needed
37
-   * in the future.
38
-   */
39
-  void bit_clear(uint16_t bits[16], const uint8_t x, const uint8_t y) { CBI(bits[y], x); }
40
-  void bit_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { SBI(bits[y], x); }
41
-  bool is_bit_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
42
-
43
   uint8_t ubl_cnt = 0;
33
   uint8_t ubl_cnt = 0;
44
 
34
 
45
   void unified_bed_leveling::echo_name() { SERIAL_PROTOCOLPGM("Unified Bed Leveling"); }
35
   void unified_bed_leveling::echo_name() { SERIAL_PROTOCOLPGM("Unified Bed Leveling"); }
70
   constexpr float unified_bed_leveling::_mesh_index_to_xpos[16],
60
   constexpr float unified_bed_leveling::_mesh_index_to_xpos[16],
71
                   unified_bed_leveling::_mesh_index_to_ypos[16];
61
                   unified_bed_leveling::_mesh_index_to_ypos[16];
72
 
62
 
73
-  bool unified_bed_leveling::g26_debug_flag = false,
74
-       unified_bed_leveling::has_control_of_lcd_panel = false;
75
-
76
   #if ENABLED(ULTIPANEL)
63
   #if ENABLED(ULTIPANEL)
77
     bool unified_bed_leveling::lcd_map_control = false;
64
     bool unified_bed_leveling::lcd_map_control = false;
78
   #endif
65
   #endif

+ 2
- 56
Marlin/ubl.h Ver arquivo

39
   #define USE_NOZZLE_AS_REFERENCE 0
39
   #define USE_NOZZLE_AS_REFERENCE 0
40
   #define USE_PROBE_AS_REFERENCE 1
40
   #define USE_PROBE_AS_REFERENCE 1
41
 
41
 
42
-  typedef struct {
43
-    int8_t x_index, y_index;
44
-    float distance; // When populated, the distance from the search location
45
-  } mesh_index_pair;
46
-
47
-  // ubl.cpp
48
-
49
-  void bit_clear(uint16_t bits[16], const uint8_t x, const uint8_t y);
50
-  void bit_set(uint16_t bits[16], const uint8_t x, const uint8_t y);
51
-  bool is_bit_set(uint16_t bits[16], const uint8_t x, const uint8_t y);
52
-
53
   // ubl_motion.cpp
42
   // ubl_motion.cpp
54
 
43
 
55
   void debug_current_and_destination(const char * const title);
44
   void debug_current_and_destination(const char * const title);
93
         static int  g29_grid_size;
82
         static int  g29_grid_size;
94
       #endif
83
       #endif
95
 
84
 
96
-      #if ENABLED(UBL_G26_MESH_VALIDATION)
97
-        static float   g26_extrusion_multiplier,
98
-                       g26_retraction_multiplier,
99
-                       g26_nozzle,
100
-                       g26_filament_diameter,
101
-                       g26_prime_length,
102
-                       g26_x_pos, g26_y_pos,
103
-                       g26_ooze_amount,
104
-                       g26_layer_height;
105
-        static int16_t g26_bed_temp,
106
-                       g26_hotend_temp,
107
-                       g26_repeats;
108
-        static int8_t  g26_prime_flag;
109
-        static bool    g26_continue_with_closest, g26_keep_heaters_on;
110
-      #endif
111
-
112
       static float measure_point_with_encoder();
85
       static float measure_point_with_encoder();
113
       static float measure_business_card_thickness(float);
86
       static float measure_business_card_thickness(float);
114
       static bool g29_parameter_parsing();
87
       static bool g29_parameter_parsing();
125
       static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
98
       static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
126
       static void smart_fill_mesh();
99
       static void smart_fill_mesh();
127
 
100
 
128
-      #if ENABLED(UBL_G26_MESH_VALIDATION)
129
-        static bool exit_from_g26();
130
-        static bool parse_G26_parameters();
131
-        static void G26_line_to_destination(const float &feed_rate);
132
-        static mesh_index_pair find_closest_circle_to_print(const float&, const float&);
133
-        static bool look_for_lines_to_connect();
134
-        static bool turn_on_heaters();
135
-        static bool prime_nozzle();
136
-        static void retract_filament(const float where[XYZE]);
137
-        static void recover_filament(const float where[XYZE]);
138
-        static void print_line_from_here_to_there(const float&, const float&, const float&, const float&, const float&, const float&);
139
-        static void move_to(const float&, const float&, const float&, const float&);
140
-        inline static void move_to(const float where[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); }
141
-      #endif
142
-
143
     public:
101
     public:
144
 
102
 
145
       static void echo_name();
103
       static void echo_name();
147
       static void save_ubl_active_state_and_disable();
105
       static void save_ubl_active_state_and_disable();
148
       static void restore_ubl_active_state_and_leave();
106
       static void restore_ubl_active_state_and_leave();
149
       static void display_map(const int);
107
       static void display_map(const int);
150
-    static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16]);
151
-    static mesh_index_pair find_furthest_invalid_mesh_point();
108
+      static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16]);
109
+      static mesh_index_pair find_furthest_invalid_mesh_point();
152
       static void reset();
110
       static void reset();
153
       static void invalidate();
111
       static void invalidate();
154
       static void set_all_mesh_points_to_value(const float);
112
       static void set_all_mesh_points_to_value(const float);
156
 
114
 
157
       static void G29() _O0;                          // O0 for no optimization
115
       static void G29() _O0;                          // O0 for no optimization
158
       static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560
116
       static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560
159
-
160
-      #if ENABLED(UBL_G26_MESH_VALIDATION)
161
-        static void G26();
162
-      #endif
163
-
164
       static int8_t storage_slot;
117
       static int8_t storage_slot;
165
 
118
 
166
       static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
119
       static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
189
                                 MESH_MIN_Y + 14 * (MESH_Y_DIST), MESH_MIN_Y + 15 * (MESH_Y_DIST)
142
                                 MESH_MIN_Y + 14 * (MESH_Y_DIST), MESH_MIN_Y + 15 * (MESH_Y_DIST)
190
                               };
143
                               };
191
 
144
 
192
-      static bool g26_debug_flag, has_control_of_lcd_panel;
193
-
194
       #if ENABLED(ULTIPANEL)
145
       #if ENABLED(ULTIPANEL)
195
         static bool lcd_map_control;
146
         static bool lcd_map_control;
196
       #endif
147
       #endif
390
         || isnan(z_values[0][0])
341
         || isnan(z_values[0][0])
391
       );
342
       );
392
     }
343
     }
393
-
394
   }; // class unified_bed_leveling
344
   }; // class unified_bed_leveling
395
 
345
 
396
   extern unified_bed_leveling ubl;
346
   extern unified_bed_leveling ubl;
397
 
347
 
398
-  #if ENABLED(UBL_G26_MESH_VALIDATION)
399
-    FORCE_INLINE void gcode_G26() { ubl.G26(); }
400
-  #endif
401
-
402
   FORCE_INLINE void gcode_G29() { ubl.G29(); }
348
   FORCE_INLINE void gcode_G29() { ubl.G29(); }
403
 
349
 
404
 #endif // AUTO_BED_LEVELING_UBL
350
 #endif // AUTO_BED_LEVELING_UBL

+ 16
- 12
Marlin/ubl_G29.cpp Ver arquivo

32
   #include "stepper.h"
32
   #include "stepper.h"
33
   #include "planner.h"
33
   #include "planner.h"
34
   #include "gcode.h"
34
   #include "gcode.h"
35
+  #include "bitmap_flags.h"
35
 
36
 
36
   #include <math.h>
37
   #include <math.h>
37
   #include "least_squares_fit.h"
38
   #include "least_squares_fit.h"
46
     float lcd_mesh_edit();
47
     float lcd_mesh_edit();
47
     void lcd_z_offset_edit_setup(float);
48
     void lcd_z_offset_edit_setup(float);
48
     extern void _lcd_ubl_output_map_lcd();
49
     extern void _lcd_ubl_output_map_lcd();
50
+    extern bool ubl_lcd_clicked();
49
     float lcd_z_offset_edit();
51
     float lcd_z_offset_edit();
50
   #endif
52
   #endif
51
 
53
 
676
       lcd_reset_alert_level();
678
       lcd_reset_alert_level();
677
       LCD_MESSAGEPGM("");
679
       LCD_MESSAGEPGM("");
678
       lcd_quick_feedback();
680
       lcd_quick_feedback();
679
-
680
-      has_control_of_lcd_panel = false;
681
+      lcd_external_control = false;
681
     #endif
682
     #endif
682
 
683
 
683
     return;
684
     return;
736
     void unified_bed_leveling::probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool close_or_far) {
737
     void unified_bed_leveling::probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool close_or_far) {
737
       mesh_index_pair location;
738
       mesh_index_pair location;
738
 
739
 
739
-      has_control_of_lcd_panel = true;
740
+      #if ENABLED(NEWPANEL)
741
+        lcd_external_control = true;
742
+      #endif
743
+
740
       save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
744
       save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
741
       DEPLOY_PROBE();
745
       DEPLOY_PROBE();
742
 
746
 
751
             lcd_quick_feedback();
755
             lcd_quick_feedback();
752
             STOW_PROBE();
756
             STOW_PROBE();
753
             while (ubl_lcd_clicked()) idle();
757
             while (ubl_lcd_clicked()) idle();
754
-            has_control_of_lcd_panel = false;
758
+            lcd_external_control = false;
755
             restore_ubl_active_state_and_leave();
759
             restore_ubl_active_state_and_leave();
756
             safe_delay(50);  // Debounce the Encoder wheel
760
             safe_delay(50);  // Debounce the Encoder wheel
757
             return;
761
             return;
909
     static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); }
913
     static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); }
910
 
914
 
911
     float unified_bed_leveling::measure_business_card_thickness(float in_height) {
915
     float unified_bed_leveling::measure_business_card_thickness(float in_height) {
912
-      has_control_of_lcd_panel = true;
916
+      lcd_external_control = true;
913
       save_ubl_active_state_and_disable();   // Disable bed level correction for probing
917
       save_ubl_active_state_and_disable();   // Disable bed level correction for probing
914
 
918
 
915
       do_blocking_move_to(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)), in_height);
919
       do_blocking_move_to(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)), in_height);
943
 
947
 
944
       in_height = current_position[Z_AXIS]; // do manual probing at lower height
948
       in_height = current_position[Z_AXIS]; // do manual probing at lower height
945
 
949
 
946
-      has_control_of_lcd_panel = false;
950
+      lcd_external_control = false;
947
 
951
 
948
       restore_ubl_active_state_and_leave();
952
       restore_ubl_active_state_and_leave();
949
 
953
 
952
 
956
 
953
     void unified_bed_leveling::manually_probe_remaining_mesh(const float &rx, const float &ry, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) {
957
     void unified_bed_leveling::manually_probe_remaining_mesh(const float &rx, const float &ry, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) {
954
 
958
 
955
-      has_control_of_lcd_panel = true;
959
+      lcd_external_control = true;
956
 
960
 
957
       save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
961
       save_ubl_active_state_and_disable();   // we don't do bed level correction because we want the raw data when we probe
958
       do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES);
962
       do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES);
976
         do_blocking_move_to_z(z_clearance);
980
         do_blocking_move_to_z(z_clearance);
977
 
981
 
978
         KEEPALIVE_STATE(PAUSED_FOR_USER);
982
         KEEPALIVE_STATE(PAUSED_FOR_USER);
979
-        has_control_of_lcd_panel = true;
983
+        lcd_external_control = true;
980
 
984
 
981
         if (do_ubl_mesh_map) display_map(g29_map_type);  // show user where we're probing
985
         if (do_ubl_mesh_map) display_map(g29_map_type);  // show user where we're probing
982
 
986
 
1008
             #if ENABLED(NEWPANEL)
1012
             #if ENABLED(NEWPANEL)
1009
               lcd_quick_feedback();
1013
               lcd_quick_feedback();
1010
               while (ubl_lcd_clicked()) idle();
1014
               while (ubl_lcd_clicked()) idle();
1011
-              has_control_of_lcd_panel = false;
1015
+              lcd_external_control = false;
1012
             #endif
1016
             #endif
1013
 
1017
 
1014
             KEEPALIVE_STATE(IN_HANDLER);
1018
             KEEPALIVE_STATE(IN_HANDLER);
1510
         new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place
1514
         new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place
1511
 
1515
 
1512
         KEEPALIVE_STATE(PAUSED_FOR_USER);
1516
         KEEPALIVE_STATE(PAUSED_FOR_USER);
1513
-        has_control_of_lcd_panel = true;
1517
+        lcd_external_control = true;
1514
 
1518
 
1515
         if (do_ubl_mesh_map) display_map(g29_map_type);  // show the user which point is being adjusted
1519
         if (do_ubl_mesh_map) display_map(g29_map_type);  // show the user which point is being adjusted
1516
 
1520
 
1531
         // The technique used here generates a race condition for the encoder click.
1535
         // The technique used here generates a race condition for the encoder click.
1532
         // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune) or here.
1536
         // It could get detected in lcd_mesh_edit (actually _lcd_mesh_fine_tune) or here.
1533
         // Let's work on specifying a proper API for the LCD ASAP, OK?
1537
         // Let's work on specifying a proper API for the LCD ASAP, OK?
1534
-        has_control_of_lcd_panel = true;
1538
+        lcd_external_control = true;
1535
 
1539
 
1536
         // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is
1540
         // this sequence to detect an ubl_lcd_clicked() debounce it and leave if it is
1537
         // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp).   This
1541
         // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp).   This
1560
 
1564
 
1561
       FINE_TUNE_EXIT:
1565
       FINE_TUNE_EXIT:
1562
 
1566
 
1563
-      has_control_of_lcd_panel = false;
1567
+      lcd_external_control = false;
1564
       KEEPALIVE_STATE(IN_HANDLER);
1568
       KEEPALIVE_STATE(IN_HANDLER);
1565
 
1569
 
1566
       if (do_ubl_mesh_map) display_map(g29_map_type);
1570
       if (do_ubl_mesh_map) display_map(g29_map_type);

+ 14
- 14
Marlin/ubl_motion.cpp Ver arquivo

38
     extern void set_current_from_destination();
38
     extern void set_current_from_destination();
39
   #endif
39
   #endif
40
 
40
 
41
-#if ENABLED(DELTA)
41
+  #if ENABLED(DELTA)
42
 
42
 
43
-  extern float delta[ABC];
43
+    extern float delta[ABC];
44
 
44
 
45
-  extern float delta_endstop_adj[ABC],
46
-               delta_radius,
47
-               delta_tower_angle_trim[ABC],
48
-               delta_tower[ABC][2],
49
-               delta_diagonal_rod,
50
-               delta_calibration_radius,
51
-               delta_diagonal_rod_2_tower[ABC],
52
-               delta_segments_per_second,
53
-               delta_clip_start_height;
45
+    extern float delta_endstop_adj[ABC],
46
+                 delta_radius,
47
+                 delta_tower_angle_trim[ABC],
48
+                 delta_tower[ABC][2],
49
+                 delta_diagonal_rod,
50
+                 delta_calibration_radius,
51
+                 delta_diagonal_rod_2_tower[ABC],
52
+                 delta_segments_per_second,
53
+                 delta_clip_start_height;
54
 
54
 
55
-  extern float delta_safe_distance_from_top();
55
+    extern float delta_safe_distance_from_top();
56
 
56
 
57
-#endif
57
+  #endif
58
 
58
 
59
 
59
 
60
   static void debug_echo_axis(const AxisEnum axis) {
60
   static void debug_echo_axis(const AxisEnum axis) {
68
 
68
 
69
     // if the title message starts with a '!' it is so important, we are going to
69
     // if the title message starts with a '!' it is so important, we are going to
70
     // ignore the status of the g26_debug_flag
70
     // ignore the status of the g26_debug_flag
71
-    if (*title != '!' && !ubl.g26_debug_flag) return;
71
+    if (*title != '!' && !g26_debug_flag) return;
72
 
72
 
73
     const float de = destination[E_AXIS] - current_position[E_AXIS];
73
     const float de = destination[E_AXIS] - current_position[E_AXIS];
74
 
74
 

+ 8
- 5
Marlin/ultralcd.cpp Ver arquivo

57
   extern void mesh_probing_done();
57
   extern void mesh_probing_done();
58
 #endif
58
 #endif
59
 
59
 
60
+#if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION)
61
+  bool lcd_external_control;
62
+#endif
63
+
60
 // Initialized by settings.load()
64
 // Initialized by settings.load()
61
 int16_t lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_speed[2];
65
 int16_t lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_speed[2];
62
 
66
 
4603
 
4607
 
4604
     lcd_buttons_update();
4608
     lcd_buttons_update();
4605
 
4609
 
4606
-    #if ENABLED(AUTO_BED_LEVELING_UBL)
4607
-      const bool UBL_CONDITION = !ubl.has_control_of_lcd_panel;
4610
+    #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION)
4611
+      const bool UBL_CONDITION = lcd_external_control;
4608
     #else
4612
     #else
4609
       constexpr bool UBL_CONDITION = true;
4613
       constexpr bool UBL_CONDITION = true;
4610
     #endif
4614
     #endif
5071
         case encrot3: ENCODER_SPIN(encrot2, encrot0); break;
5075
         case encrot3: ENCODER_SPIN(encrot2, encrot0); break;
5072
       }
5076
       }
5073
       #if ENABLED(AUTO_BED_LEVELING_UBL)
5077
       #if ENABLED(AUTO_BED_LEVELING_UBL)
5074
-        if (ubl.has_control_of_lcd_panel) {
5078
+        if (lcd_external_control) {
5075
           ubl.encoder_diff = encoderDiff;   // Make the encoder's rotation available to G29's Mesh Editor
5079
           ubl.encoder_diff = encoderDiff;   // Make the encoder's rotation available to G29's Mesh Editor
5076
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
5080
           encoderDiff = 0;                  // We are going to lie to the LCD Panel and claim the encoder
5077
                                             // knob has not turned.
5081
                                             // knob has not turned.
5087
     bool lcd_detected() { return true; }
5091
     bool lcd_detected() { return true; }
5088
   #endif
5092
   #endif
5089
 
5093
 
5090
-  #if ENABLED(AUTO_BED_LEVELING_UBL)
5091
-
5094
+  #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION)
5092
     void chirp_at_user() {
5095
     void chirp_at_user() {
5093
       #if ENABLED(LCD_USE_I2C_BUZZER)
5096
       #if ENABLED(LCD_USE_I2C_BUZZER)
5094
         lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
5097
         lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);

+ 4
- 0
Marlin/ultralcd.h Ver arquivo

27
 
27
 
28
 #if ENABLED(ULTRA_LCD)
28
 #if ENABLED(ULTRA_LCD)
29
 
29
 
30
+  #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION)
31
+    extern bool lcd_external_control;
32
+  #endif
33
+
30
   #define BUTTON_EXISTS(BN) (defined(BTN_## BN) && BTN_## BN >= 0)
34
   #define BUTTON_EXISTS(BN) (defined(BTN_## BN) && BTN_## BN >= 0)
31
   #define BUTTON_PRESSED(BN) !READ(BTN_## BN)
35
   #define BUTTON_PRESSED(BN) !READ(BTN_## BN)
32
 
36
 

Carregando…
Cancelar
Salvar