Browse Source

Implements a nozzle parking command (G27)

João Brázio 8 years ago
parent
commit
c711701626
4 changed files with 179 additions and 85 deletions
  1. 8
    2
      .travis.yml
  2. 24
    0
      Marlin/Configuration.h
  3. 25
    2
      Marlin/Marlin_main.cpp
  4. 122
    81
      Marlin/nozzle.h

+ 8
- 2
.travis.yml View File

@@ -211,10 +211,16 @@ script:
211 211
   - opt_enable PRINTCOUNTER
212 212
   - build_marlin
213 213
   #
214
-  # Test CLEAN_NOZZLE_FEATURE
214
+  # Test NOZZLE_PARK_FEATURE
215 215
   #
216 216
   - restore_configs
217
-  - opt_enable AUTO_BED_LEVELING_FEATURE CLEAN_NOZZLE_FEATURE FIX_MOUNTED_PROBE
217
+  - opt_enable NOZZLE_PARK_FEATURE
218
+  - build_marlin
219
+  #
220
+  # Test NOZZLE_CLEAN_FEATURE
221
+  #
222
+  - restore_configs
223
+  - opt_enable AUTO_BED_LEVELING_FEATURE NOZZLE_CLEAN_FEATURE FIX_MOUNTED_PROBE
218 224
   - build_marlin
219 225
   #
220 226
   #

+ 24
- 0
Marlin/Configuration.h View File

@@ -788,6 +788,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
788 788
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
789 789
 
790 790
 //
791
+// Nozzle Park -- EXPERIMENTAL
792
+//
793
+// When enabled allows the user to define a special XYZ position, inside the
794
+// machine's topology, to park the nozzle when idle or when receiving the G27
795
+// command.
796
+//
797
+// The "P" paramenter controls what is the action applied to the Z axis:
798
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
799
+//        be raised to reach Z-park height.
800
+//
801
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
802
+//        reach Z-park height.
803
+//
804
+//    P2: The nozzle height will be raised by Z-park amount but never going over
805
+//        the machine's limit of Z_MAX_POS.
806
+//
807
+//#define NOZZLE_PARK_FEATURE
808
+
809
+#if ENABLED(NOZZLE_PARK_FEATURE)
810
+  // Specify a park position as { X, Y, Z }
811
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
812
+#endif
813
+
814
+//
791 815
 // Clean Nozzle Feature -- EXPERIMENTAL
792 816
 //
793 817
 // When enabled allows the user to send G12 to start the nozzle cleaning

+ 25
- 2
Marlin/Marlin_main.cpp View File

@@ -2736,9 +2736,12 @@ inline void gcode_G4() {
2736 2736
 
2737 2737
 #endif //FWRETRACT
2738 2738
 
2739
-#if ENABLED(NOZZLE_CLEAN_FEATURE) && ENABLED(AUTO_BED_LEVELING_FEATURE)
2739
+#if ENABLED(NOZZLE_CLEAN_FEATURE) && HAS_BED_PROBE
2740 2740
   #include "nozzle.h"
2741 2741
 
2742
+  /**
2743
+   * G12: Clean the nozzle
2744
+   */
2742 2745
   inline void gcode_G12() {
2743 2746
     // Don't allow nozzle cleaning without homing first
2744 2747
     if (axis_unhomed_error(true, true, true)) { return; }
@@ -2795,6 +2798,20 @@ inline void gcode_G4() {
2795 2798
 
2796 2799
 #endif // QUICK_HOME
2797 2800
 
2801
+#if ENABLED(NOZZLE_PARK_FEATURE)
2802
+  #include "nozzle.h"
2803
+
2804
+  /**
2805
+   * G27: Park the nozzle
2806
+   */
2807
+  inline void gcode_G27() {
2808
+    // Don't allow nozzle parking without homing first
2809
+    if (axis_unhomed_error(true, true, true)) { return; }
2810
+    uint8_t const z_action = code_seen('P') ? code_value_ushort() : 0;
2811
+    Nozzle::park(z_action);
2812
+  }
2813
+#endif // NOZZLE_PARK_FEATURE
2814
+
2798 2815
 /**
2799 2816
  * G28: Home all axes according to settings
2800 2817
  *
@@ -6884,7 +6901,7 @@ void process_next_command() {
6884 6901
 
6885 6902
       #if ENABLED(NOZZLE_CLEAN_FEATURE) && HAS_BED_PROBE
6886 6903
         case 12:
6887
-          gcode_G12(); // G12: Clean Nozzle
6904
+          gcode_G12(); // G12: Nozzle Clean
6888 6905
           break;
6889 6906
       #endif // NOZZLE_CLEAN_FEATURE
6890 6907
 
@@ -6898,6 +6915,12 @@ void process_next_command() {
6898 6915
           break;
6899 6916
       #endif // INCH_MODE_SUPPORT
6900 6917
 
6918
+      #if ENABLED(NOZZLE_PARK_FEATURE)
6919
+        case 27: // G27: Nozzle Park
6920
+          gcode_G27();
6921
+          break;
6922
+      #endif // NOZZLE_PARK_FEATURE
6923
+
6901 6924
       case 28: // G28: Home all axes, one at a time
6902 6925
         gcode_G28();
6903 6926
         break;

+ 122
- 81
Marlin/nozzle.h View File

@@ -30,8 +30,6 @@
30 30
  * @brief Nozzle class
31 31
  *
32 32
  * @todo: Do not ignore the end.z value and allow XYZ movements
33
- * @todo: Currently this feature needs HAS_BED_PROBE to be active
34
- *  due to the do_blocking_move_to*() functions.
35 33
  */
36 34
 class Nozzle {
37 35
   private:
@@ -43,34 +41,40 @@ class Nozzle {
43 41
      * @param end point_t defining the ending point
44 42
      * @param strokes number of strokes to execute
45 43
      */
46
-    static void stroke(point_t const &start, point_t const &end, uint8_t const &strokes)
47
-    __attribute__ ((optimize ("Os"))) {
48
-
49
-      #if ENABLED(NOZZLE_CLEAN_PARK)
50
-        // Store the current coords
51
-        point_t const initial = {
52
-          current_position[X_AXIS],
53
-          current_position[Y_AXIS],
54
-          current_position[Z_AXIS],
55
-          current_position[E_AXIS]
56
-        };
57
-      #endif
58
-
59
-      // Move to the starting point
60
-      do_blocking_move_to_xy(start.x, start.y);
61
-      do_blocking_move_to_z(start.z);
62
-
63
-      // Start the stroke pattern
64
-      for (uint8_t i = 0; i < (strokes >>1); i++) {
65
-        do_blocking_move_to_xy(end.x, end.y);
44
+    static void stroke(
45
+      __attribute__((unused)) point_t const &start,
46
+      __attribute__((unused)) point_t const &end,
47
+      __attribute__((unused)) uint8_t const &strokes
48
+    ) __attribute__((optimize ("Os"))) {
49
+      #if ENABLED(NOZZLE_CLEAN_FEATURE)
50
+
51
+        #if ENABLED(NOZZLE_CLEAN_PARK)
52
+          // Store the current coords
53
+          point_t const initial = {
54
+            current_position[X_AXIS],
55
+            current_position[Y_AXIS],
56
+            current_position[Z_AXIS],
57
+            current_position[E_AXIS]
58
+          };
59
+        #endif // NOZZLE_CLEAN_PARK
60
+
61
+        // Move to the starting point
66 62
         do_blocking_move_to_xy(start.x, start.y);
67
-      }
63
+        do_blocking_move_to_z(start.z);
68 64
 
69
-      #if ENABLED(NOZZLE_CLEAN_PARK)
70
-        // Move the nozzle to the initial point
71
-        do_blocking_move_to_z(initial.z);
72
-        do_blocking_move_to_xy(initial.x, initial.y);
73
-      #endif
65
+        // Start the stroke pattern
66
+        for (uint8_t i = 0; i < (strokes >>1); i++) {
67
+          do_blocking_move_to_xy(end.x, end.y);
68
+          do_blocking_move_to_xy(start.x, start.y);
69
+        }
70
+
71
+        #if ENABLED(NOZZLE_CLEAN_PARK)
72
+          // Move the nozzle to the initial point
73
+          do_blocking_move_to_z(initial.z);
74
+          do_blocking_move_to_xy(initial.x, initial.y);
75
+        #endif // NOZZLE_CLEAN_PARK
76
+
77
+      #endif // NOZZLE_CLEAN_FEATURE
74 78
     }
75 79
 
76 80
     /**
@@ -82,47 +86,53 @@ class Nozzle {
82 86
      * @param strokes number of strokes to execute
83 87
      * @param objects number of objects to create
84 88
      */
85
-    static void zigzag(point_t const &start,
86
-      point_t const &end, uint8_t const &strokes, uint8_t const &objects)
87
-    __attribute__ ((optimize ("Os"))) {
88
-      float A = fabs(end.y - start.y); // [twice the] Amplitude
89
-      float P = fabs(end.x - start.x) / (objects << 1); // Period
90
-
91
-      // Don't allow impossible triangles
92
-      if (A <= 0.0f || P <= 0.0f ) return;
93
-
94
-      #if ENABLED(NOZZLE_CLEAN_PARK)
95
-        // Store the current coords
96
-        point_t const initial = {
97
-          current_position[X_AXIS],
98
-          current_position[Y_AXIS],
99
-          current_position[Z_AXIS],
100
-          current_position[E_AXIS]
101
-        };
102
-      #endif
103
-
104
-      for (uint8_t j = 0; j < strokes; j++) {
105
-        for (uint8_t i = 0; i < (objects << 1); i++) {
106
-          float const x = start.x + i * P;
107
-          float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
108
-
109
-          do_blocking_move_to_xy(x, y);
110
-          if (i == 0) do_blocking_move_to_z(start.z);
89
+    static void zigzag(
90
+      __attribute__((unused)) point_t const &start,
91
+      __attribute__((unused)) point_t const &end,
92
+      __attribute__((unused)) uint8_t const &strokes,
93
+      __attribute__((unused)) uint8_t const &objects
94
+    ) __attribute__((optimize ("Os"))) {
95
+      #if ENABLED(NOZZLE_CLEAN_FEATURE)
96
+        float A = fabs(end.y - start.y); // [twice the] Amplitude
97
+        float P = fabs(end.x - start.x) / (objects << 1); // Period
98
+
99
+        // Don't allow impossible triangles
100
+        if (A <= 0.0f || P <= 0.0f ) return;
101
+
102
+        #if ENABLED(NOZZLE_CLEAN_PARK)
103
+          // Store the current coords
104
+          point_t const initial = {
105
+            current_position[X_AXIS],
106
+            current_position[Y_AXIS],
107
+            current_position[Z_AXIS],
108
+            current_position[E_AXIS]
109
+          };
110
+        #endif // NOZZLE_CLEAN_PARK
111
+
112
+        for (uint8_t j = 0; j < strokes; j++) {
113
+          for (uint8_t i = 0; i < (objects << 1); i++) {
114
+            float const x = start.x + i * P;
115
+            float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
116
+
117
+            do_blocking_move_to_xy(x, y);
118
+            if (i == 0) do_blocking_move_to_z(start.z);
119
+          }
120
+
121
+          for (int i = (objects << 1); i > -1; i--) {
122
+            float const x = start.x + i * P;
123
+            float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
124
+
125
+            do_blocking_move_to_xy(x, y);
126
+          }
111 127
         }
112 128
 
113
-        for (int i = (objects << 1); i > -1; i--) {
114
-          float const x = start.x + i * P;
115
-          float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
129
+        #if ENABLED(NOZZLE_CLEAN_PARK)
130
+          // Move the nozzle to the initial point
131
+          do_blocking_move_to_z(initial.z);
132
+          do_blocking_move_to_xy(initial.x, initial.y);
133
+        #endif // NOZZLE_CLEAN_PARK
116 134
 
117
-          do_blocking_move_to_xy(x, y);
118
-        }
119
-      }
120
-
121
-      #if ENABLED(NOZZLE_CLEAN_PARK)
122
-        // Move the nozzle to the initial point
123
-        do_blocking_move_to_z(initial.z);
124
-        do_blocking_move_to_xy(initial.x, initial.y);
125
-      #endif
135
+      #endif // NOZZLE_CLEAN_FEATURE
126 136
     }
127 137
 
128 138
   public:
@@ -133,21 +143,52 @@ class Nozzle {
133 143
      * @param pattern one of the available patterns
134 144
      * @param argument depends on the cleaning pattern
135 145
      */
136
-    static void clean(uint8_t const &pattern,
137
-      uint8_t const &strokes, uint8_t const &objects = 0)
138
-    __attribute__ ((optimize ("Os"))) {
139
-      switch (pattern) {
140
-        case 1:
141
-          Nozzle::zigzag(
142
-            NOZZLE_CLEAN_START_PT,
143
-            NOZZLE_CLEAN_END_PT, strokes, objects);
144
-          break;
145
-
146
-        default:
147
-          Nozzle::stroke(
148
-            NOZZLE_CLEAN_START_PT,
149
-            NOZZLE_CLEAN_END_PT, strokes);
150
-      }
146
+    static void clean(
147
+      __attribute__((unused)) uint8_t const &pattern,
148
+      __attribute__((unused)) uint8_t const &strokes,
149
+      __attribute__((unused)) uint8_t const &objects = 0
150
+    ) __attribute__((optimize ("Os"))) {
151
+      #if ENABLED(NOZZLE_CLEAN_FEATURE)
152
+        switch (pattern) {
153
+          case 1:
154
+            Nozzle::zigzag(
155
+              NOZZLE_CLEAN_START_PT,
156
+              NOZZLE_CLEAN_END_PT, strokes, objects);
157
+            break;
158
+
159
+          default:
160
+            Nozzle::stroke(
161
+              NOZZLE_CLEAN_START_PT,
162
+              NOZZLE_CLEAN_END_PT, strokes);
163
+        }
164
+      #endif // NOZZLE_CLEAN_FEATURE
165
+    }
166
+
167
+    static void park(
168
+      __attribute__((unused)) uint8_t const &z_action
169
+    ) __attribute__((optimize ("Os"))) {
170
+      #if ENABLED(NOZZLE_PARK_FEATURE)
171
+        float const z = current_position[Z_AXIS];
172
+        point_t const park = NOZZLE_PARK_POINT;
173
+
174
+        switch(z_action) {
175
+          case 1: // force Z-park height
176
+            do_blocking_move_to_z(park.z);
177
+            break;
178
+
179
+          case 2: // Raise by Z-park height
180
+            do_blocking_move_to_z(
181
+              (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z);
182
+            break;
183
+
184
+          default: // Raise to Z-park height if lower
185
+            if (current_position[Z_AXIS] < park.z)
186
+              do_blocking_move_to_z(park.z);
187
+        }
188
+
189
+        do_blocking_move_to_xy(park.x, park.y);
190
+
191
+      #endif // NOZZLE_PARK_FEATURE
151 192
     }
152 193
 };
153 194
 

Loading…
Cancel
Save