Просмотр исходного кода

Added circle pattern for nozzle cleaning feature

Marek Pikuła 7 лет назад
Родитель
Сommit
6836b94eea
4 измененных файлов: 270 добавлений и 120 удалений
  1. 12
    2
      Marlin/Configuration.h
  2. 2
    1
      Marlin/Marlin_main.cpp
  3. 236
    0
      Marlin/nozzle.cpp
  4. 20
    117
      Marlin/nozzle.h

+ 12
- 2
Marlin/Configuration.h Просмотреть файл

@@ -96,7 +96,7 @@
96 96
 //
97 97
 // Marlin now allow you to have a vendor boot image to be displayed on machine
98 98
 // start. When SHOW_CUSTOM_BOOTSCREEN is defined Marlin will first show your
99
-// custom boot image and them the default Marlin boot image is shown.
99
+// custom boot image and then the default Marlin boot image is shown.
100 100
 //
101 101
 // We suggest for you to take advantage of this new feature and keep the Marlin
102 102
 // boot image unmodified. For an example have a look at the bq Hephestos 2
@@ -1000,6 +1000,9 @@
1000 1000
 //                       |________|_________|_________|
1001 1001
 //                           T1        T2        T3
1002 1002
 //
1003
+//   P2: This starts a circular pattern with circle with middle in
1004
+//       NOZZLE_CLEAN_CIRCLE_MIDDLE radius of R and stroke count of S.
1005
+//       Before starting the circle nozzle goes to NOZZLE_CLEAN_START_POINT.
1003 1006
 //
1004 1007
 // Caveats: End point Z should use the same value as Start point Z.
1005 1008
 //
@@ -1011,7 +1014,7 @@
1011 1014
 #if ENABLED(NOZZLE_CLEAN_FEATURE)
1012 1015
   // Default number of pattern repetitions
1013 1016
   #define NOZZLE_CLEAN_STROKES  12
1014
-  
1017
+
1015 1018
   // Default number of triangles
1016 1019
   #define NOZZLE_CLEAN_TRIANGLES  3
1017 1020
 
@@ -1019,6 +1022,13 @@
1019 1022
   #define NOZZLE_CLEAN_START_POINT { 30, 30, (Z_MIN_POS + 1)}
1020 1023
   #define NOZZLE_CLEAN_END_POINT   {100, 60, (Z_MIN_POS + 1)}
1021 1024
 
1025
+  // Circular pattern radius
1026
+  #define NOZZLE_CLEAN_CIRCLE_RADIUS 6.5
1027
+  // Circular pattern circle fragments number
1028
+  #define NOZZLE_CLEAN_CIRCLE_FN 10
1029
+  // Middle point of circle
1030
+  #define NOZZLE_CLEAN_CIRCLE_MIDDLE NOZZLE_CLEAN_START_POINT
1031
+
1022 1032
   // Moves the nozzle to the initial position
1023 1033
   #define NOZZLE_CLEAN_GOBACK
1024 1034
 #endif

+ 2
- 1
Marlin/Marlin_main.cpp Просмотреть файл

@@ -3164,8 +3164,9 @@ inline void gcode_G4() {
3164 3164
     const uint8_t pattern = code_seen('P') ? code_value_ushort() : 0,
3165 3165
                   strokes = code_seen('S') ? code_value_ushort() : NOZZLE_CLEAN_STROKES,
3166 3166
                   objects = code_seen('T') ? code_value_ushort() : NOZZLE_CLEAN_TRIANGLES;
3167
+    const float radius = code_seen('R') ? code_value_float() : NOZZLE_CLEAN_CIRCLE_RADIUS;
3167 3168
 
3168
-    Nozzle::clean(pattern, strokes, objects);
3169
+    Nozzle::clean(pattern, strokes, radius, objects);
3169 3170
   }
3170 3171
 #endif
3171 3172
 

+ 236
- 0
Marlin/nozzle.cpp Просмотреть файл

@@ -0,0 +1,236 @@
1
+#include "nozzle.h"
2
+
3
+#include "Marlin.h"
4
+#include "point_t.h"
5
+
6
+/**
7
+  * @brief Stroke clean pattern
8
+  * @details Wipes the nozzle back and forth in a linear movement
9
+  *
10
+  * @param start point_t defining the starting point
11
+  * @param end point_t defining the ending point
12
+  * @param strokes number of strokes to execute
13
+  */
14
+void Nozzle::stroke(
15
+  __attribute__((unused)) point_t const &start,
16
+  __attribute__((unused)) point_t const &end,
17
+  __attribute__((unused)) uint8_t const &strokes
18
+) {
19
+  #if ENABLED(NOZZLE_CLEAN_FEATURE)
20
+
21
+    #if ENABLED(NOZZLE_CLEAN_GOBACK)
22
+      // Store the current coords
23
+      point_t const initial = {
24
+        current_position[X_AXIS],
25
+        current_position[Y_AXIS],
26
+        current_position[Z_AXIS],
27
+        current_position[E_AXIS]
28
+      };
29
+    #endif // NOZZLE_CLEAN_GOBACK
30
+
31
+    // Move to the starting point
32
+    do_blocking_move_to_xy(start.x, start.y);
33
+    do_blocking_move_to_z(start.z);
34
+
35
+    // Start the stroke pattern
36
+    for (uint8_t i = 0; i < (strokes >>1); i++) {
37
+      do_blocking_move_to_xy(end.x, end.y);
38
+      do_blocking_move_to_xy(start.x, start.y);
39
+    }
40
+
41
+    #if ENABLED(NOZZLE_CLEAN_GOBACK)
42
+      // Move the nozzle to the initial point
43
+      do_blocking_move_to(initial.x, initial.y, initial.z);
44
+    #endif // NOZZLE_CLEAN_GOBACK
45
+
46
+  #endif // NOZZLE_CLEAN_FEATURE
47
+}
48
+
49
+/**
50
+  * @brief Zig-zag clean pattern
51
+  * @details Apply a zig-zag cleanning pattern
52
+  *
53
+  * @param start point_t defining the starting point
54
+  * @param end point_t defining the ending point
55
+  * @param strokes number of strokes to execute
56
+  * @param objects number of objects to create
57
+  */
58
+void Nozzle::zigzag(
59
+  __attribute__((unused)) point_t const &start,
60
+  __attribute__((unused)) point_t const &end,
61
+  __attribute__((unused)) uint8_t const &strokes,
62
+  __attribute__((unused)) uint8_t const &objects
63
+) {
64
+  #if ENABLED(NOZZLE_CLEAN_FEATURE)
65
+    float A = fabs(end.y - start.y); // [twice the] Amplitude
66
+    float P = fabs(end.x - start.x) / (objects << 1); // Period
67
+
68
+    // Don't allow impossible triangles
69
+    if (A <= 0.0f || P <= 0.0f ) return;
70
+
71
+    #if ENABLED(NOZZLE_CLEAN_GOBACK)
72
+      // Store the current coords
73
+      point_t const initial = {
74
+        current_position[X_AXIS],
75
+        current_position[Y_AXIS],
76
+        current_position[Z_AXIS],
77
+        current_position[E_AXIS]
78
+      };
79
+    #endif // NOZZLE_CLEAN_GOBACK
80
+
81
+    for (uint8_t j = 0; j < strokes; j++) {
82
+      for (uint8_t i = 0; i < (objects << 1); i++) {
83
+        float const x = start.x + i * P;
84
+        float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
85
+
86
+        do_blocking_move_to_xy(x, y);
87
+        if (i == 0) do_blocking_move_to_z(start.z);
88
+      }
89
+
90
+      for (int i = (objects << 1); i > -1; i--) {
91
+        float const x = start.x + i * P;
92
+        float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
93
+
94
+        do_blocking_move_to_xy(x, y);
95
+      }
96
+    }
97
+
98
+    #if ENABLED(NOZZLE_CLEAN_GOBACK)
99
+      // Move the nozzle to the initial point
100
+      do_blocking_move_to_z(initial.z);
101
+      do_blocking_move_to_xy(initial.x, initial.y);
102
+    #endif // NOZZLE_CLEAN_GOBACK
103
+
104
+  #endif // NOZZLE_CLEAN_FEATURE
105
+}
106
+
107
+
108
+/**
109
+  * @brief Circular clean pattern
110
+  * @details Apply a circular cleaning pattern
111
+  *
112
+  * @param start point_t defining the middle of circle
113
+  * @param strokes number of strokes to execute
114
+  * @param radius radius of circle
115
+  */
116
+void Nozzle::circle(
117
+  __attribute__((unused)) point_t const &start,
118
+  __attribute__((unused)) point_t const &middle,
119
+  __attribute__((unused)) uint8_t const &strokes,
120
+  __attribute__((unused)) float const &radius
121
+) {
122
+  #if ENABLED(NOZZLE_CLEAN_FEATURE)
123
+    if (strokes == 0) return;
124
+
125
+    #if ENABLED(NOZZLE_CLEAN_GOBACK)
126
+      // Store the current coords
127
+      point_t const initial = {
128
+        current_position[X_AXIS],
129
+        current_position[Y_AXIS],
130
+        current_position[Z_AXIS],
131
+        current_position[E_AXIS]
132
+      };
133
+    #endif // NOZZLE_CLEAN_GOBACK
134
+
135
+    if (start.z <= current_position[Z_AXIS]) {
136
+      // Order of movement is pretty darn important here
137
+      do_blocking_move_to_xy(start.x, start.y);
138
+      do_blocking_move_to_z(start.z);
139
+    } else {
140
+      do_blocking_move_to_z(start.z);
141
+      do_blocking_move_to_xy(start.x, start.y);
142
+    }
143
+
144
+    float x, y;
145
+    for (uint8_t s = 0; s < strokes; s++) {
146
+      for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++) {
147
+        x = middle.x + sin((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius;
148
+        y = middle.y + cos((M_2_PI / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius;
149
+
150
+        do_blocking_move_to_xy(x, y);
151
+      }
152
+    }
153
+
154
+    // Let's be safe
155
+    do_blocking_move_to_xy(start.x, start.y);
156
+
157
+    #if ENABLED(NOZZLE_CLEAN_GOBACK)
158
+      // Move the nozzle to the initial point
159
+      if (start.z <= initial.z) {
160
+        // As above order is important
161
+        do_blocking_move_to_z(initial.z);
162
+        do_blocking_move_to_xy(initial.x, initial.y);
163
+      } else {
164
+        do_blocking_move_to_xy(initial.x, initial.y);
165
+        do_blocking_move_to_z(initial.z);
166
+      }
167
+    #endif // NOZZLE_CLEAN_GOBACK
168
+
169
+  #endif // NOZZLE_CLEAN_FEATURE
170
+}
171
+
172
+/**
173
+  * @brief Clean the nozzle
174
+  * @details Starts the selected clean procedure pattern
175
+  *
176
+  * @param pattern one of the available patterns
177
+  * @param argument depends on the cleaning pattern
178
+  */
179
+void Nozzle::clean(
180
+  __attribute__((unused)) uint8_t const &pattern,
181
+  __attribute__((unused)) uint8_t const &strokes,
182
+  __attribute__((unused)) float const &radius,
183
+  __attribute__((unused)) uint8_t const &objects
184
+) {
185
+  #if ENABLED(NOZZLE_CLEAN_FEATURE)
186
+    #if ENABLED(DELTA)
187
+      if (current_position[Z_AXIS] > delta_clip_start_height)
188
+        do_blocking_move_to_z(delta_clip_start_height);
189
+    #endif
190
+    switch (pattern) {
191
+      case 1:
192
+        Nozzle::zigzag(
193
+          NOZZLE_CLEAN_START_POINT,
194
+          NOZZLE_CLEAN_END_POINT, strokes, objects);
195
+        break;
196
+
197
+      case 2:
198
+        Nozzle::circle(
199
+          NOZZLE_CLEAN_START_POINT,
200
+          NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius);
201
+        break;
202
+
203
+      default:
204
+        Nozzle::stroke(
205
+          NOZZLE_CLEAN_START_POINT,
206
+          NOZZLE_CLEAN_END_POINT, strokes);
207
+    }
208
+  #endif // NOZZLE_CLEAN_FEATURE
209
+}
210
+
211
+void Nozzle::park(
212
+  __attribute__((unused)) uint8_t const &z_action
213
+) {
214
+  #if ENABLED(NOZZLE_PARK_FEATURE)
215
+    float const z = current_position[Z_AXIS];
216
+    point_t const park = NOZZLE_PARK_POINT;
217
+
218
+    switch(z_action) {
219
+      case 1: // force Z-park height
220
+        do_blocking_move_to_z(park.z);
221
+        break;
222
+
223
+      case 2: // Raise by Z-park height
224
+        do_blocking_move_to_z(
225
+          (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z);
226
+        break;
227
+
228
+      default: // Raise to Z-park height if lower
229
+        if (current_position[Z_AXIS] < park.z)
230
+          do_blocking_move_to_z(park.z);
231
+    }
232
+
233
+    do_blocking_move_to_xy(park.x, park.y);
234
+
235
+  #endif // NOZZLE_PARK_FEATURE
236
+}

+ 20
- 117
Marlin/nozzle.h Просмотреть файл

@@ -53,40 +53,11 @@ class Nozzle {
53 53
       __attribute__((unused)) point_t const &start,
54 54
       __attribute__((unused)) point_t const &end,
55 55
       __attribute__((unused)) uint8_t const &strokes
56
-    ) __attribute__((optimize ("Os"))) {
57
-      #if ENABLED(NOZZLE_CLEAN_FEATURE)
58
-
59
-        #if ENABLED(NOZZLE_CLEAN_GOBACK)
60
-          // Store the current coords
61
-          point_t const initial = {
62
-            current_position[X_AXIS],
63
-            current_position[Y_AXIS],
64
-            current_position[Z_AXIS],
65
-            current_position[E_AXIS]
66
-          };
67
-        #endif // NOZZLE_CLEAN_GOBACK
68
-
69
-        // Move to the starting point
70
-        do_blocking_move_to_xy(start.x, start.y);
71
-        do_blocking_move_to_z(start.z);
72
-
73
-        // Start the stroke pattern
74
-        for (uint8_t i = 0; i < (strokes >>1); i++) {
75
-          do_blocking_move_to_xy(end.x, end.y);
76
-          do_blocking_move_to_xy(start.x, start.y);
77
-        }
78
-
79
-        #if ENABLED(NOZZLE_CLEAN_GOBACK)
80
-          // Move the nozzle to the initial point
81
-          do_blocking_move_to(initial.x, initial.y, initial.z);
82
-        #endif // NOZZLE_CLEAN_GOBACK
83
-
84
-      #endif // NOZZLE_CLEAN_FEATURE
85
-    }
56
+    ) __attribute__((optimize ("Os")));
86 57
 
87 58
     /**
88 59
      * @brief Zig-zag clean pattern
89
-     * @details Apply a zig-zag cleanning pattern
60
+     * @details Apply a zig-zag cleaning pattern
90 61
      *
91 62
      * @param start point_t defining the starting point
92 63
      * @param end point_t defining the ending point
@@ -98,49 +69,22 @@ class Nozzle {
98 69
       __attribute__((unused)) point_t const &end,
99 70
       __attribute__((unused)) uint8_t const &strokes,
100 71
       __attribute__((unused)) uint8_t const &objects
101
-    ) __attribute__((optimize ("Os"))) {
102
-      #if ENABLED(NOZZLE_CLEAN_FEATURE)
103
-        float A = nozzle_clean_horizontal ? nozzle_clean_height : nozzle_clean_length; // [twice the] Amplitude
104
-        float P = ( nozzle_clean_horizontal ? nozzle_clean_length : nozzle_clean_height ) / (objects << 1); // Period
105
-
106
-        // Don't allow impossible triangles
107
-        if (A <= 0.0f || P <= 0.0f ) return;
108
-
109
-        #if ENABLED(NOZZLE_CLEAN_GOBACK)
110
-          // Store the current coords
111
-          point_t const initial = {
112
-            current_position[X_AXIS],
113
-            current_position[Y_AXIS],
114
-            current_position[Z_AXIS],
115
-            current_position[E_AXIS]
116
-          };
117
-        #endif // NOZZLE_CLEAN_GOBACK
118
-
119
-        for (uint8_t j = 0; j < strokes; j++) {
120
-          for (uint8_t i = 0; i < (objects << 1); i++) {
121
-            float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)) );
122
-            float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)) );
123
-
124
-            do_blocking_move_to_xy(x, y);
125
-            if (i == 0) do_blocking_move_to_z(start.z);
126
-          }
127
-
128
-          for (int i = (objects << 1); i > -1; i--) {
129
-            float const x = start.x + ( nozzle_clean_horizontal ? i * P : (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)) );
130
-            float const y = start.y + (!nozzle_clean_horizontal ? i * P : (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)) );
131
-
132
-            do_blocking_move_to_xy(x, y);
133
-          }
134
-        }
135
-
136
-        #if ENABLED(NOZZLE_CLEAN_GOBACK)
137
-          // Move the nozzle to the initial point
138
-          do_blocking_move_to_z(initial.z);
139
-          do_blocking_move_to_xy(initial.x, initial.y);
140
-        #endif // NOZZLE_CLEAN_GOBACK
72
+    ) __attribute__((optimize ("Os")));
141 73
 
142
-      #endif // NOZZLE_CLEAN_FEATURE
143
-    }
74
+    /**
75
+     * @brief Circular clean pattern
76
+     * @details Apply a circular cleaning pattern
77
+     *
78
+     * @param start point_t defining the middle of circle
79
+     * @param strokes number of strokes to execute
80
+     * @param radius radius of circle
81
+     */
82
+    static void circle(
83
+      __attribute__((unused)) point_t const &start,
84
+      __attribute__((unused)) point_t const &middle,
85
+      __attribute__((unused)) uint8_t const &strokes,
86
+      __attribute__((unused)) float const &radius
87
+    ) __attribute__((optimize ("Os")));
144 88
 
145 89
   public:
146 90
     /**
@@ -153,54 +97,13 @@ class Nozzle {
153 97
     static void clean(
154 98
       __attribute__((unused)) uint8_t const &pattern,
155 99
       __attribute__((unused)) uint8_t const &strokes,
100
+      __attribute__((unused)) float const &radius,
156 101
       __attribute__((unused)) uint8_t const &objects = 0
157
-    ) __attribute__((optimize ("Os"))) {
158
-      #if ENABLED(NOZZLE_CLEAN_FEATURE)
159
-        #if ENABLED(DELTA)
160
-          if (current_position[Z_AXIS] > delta_clip_start_height)
161
-            do_blocking_move_to_z(delta_clip_start_height);
162
-        #endif
163
-        switch (pattern) {
164
-          case 1:
165
-            Nozzle::zigzag(
166
-              NOZZLE_CLEAN_START_POINT,
167
-              NOZZLE_CLEAN_END_POINT, strokes, objects);
168
-            break;
169
-
170
-          default:
171
-            Nozzle::stroke(
172
-              NOZZLE_CLEAN_START_POINT,
173
-              NOZZLE_CLEAN_END_POINT, strokes);
174
-        }
175
-      #endif // NOZZLE_CLEAN_FEATURE
176
-    }
102
+    ) __attribute__((optimize ("Os")));
177 103
 
178 104
     static void park(
179 105
       __attribute__((unused)) uint8_t const &z_action
180
-    ) __attribute__((optimize ("Os"))) {
181
-      #if ENABLED(NOZZLE_PARK_FEATURE)
182
-        float const z = current_position[Z_AXIS];
183
-        point_t const park = NOZZLE_PARK_POINT;
184
-
185
-        switch(z_action) {
186
-          case 1: // force Z-park height
187
-            do_blocking_move_to_z(park.z);
188
-            break;
189
-
190
-          case 2: // Raise by Z-park height
191
-            do_blocking_move_to_z(
192
-              (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z);
193
-            break;
194
-
195
-          default: // Raise to Z-park height if lower
196
-            if (current_position[Z_AXIS] < park.z)
197
-              do_blocking_move_to_z(park.z);
198
-        }
199
-
200
-        do_blocking_move_to_xy(park.x, park.y);
201
-
202
-      #endif // NOZZLE_PARK_FEATURE
203
-    }
106
+    ) __attribute__((optimize ("Os")));
204 107
 };
205 108
 
206 109
 #endif

Загрузка…
Отмена
Сохранить