Subversion Repositories MK-Marlin

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ron 1
/**
2
 * Marlin 3D Printer Firmware
3
 * Copyright (C) 2016 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
#include "MarlinConfig.h"
24
 
25
#if ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE)
26
 
27
#include "nozzle.h"
28
 
29
#include "Marlin.h"
30
#include "point_t.h"
31
 
32
#if ENABLED(NOZZLE_CLEAN_FEATURE)
33
 
34
  /**
35
   * @brief Stroke clean pattern
36
   * @details Wipes the nozzle back and forth in a linear movement
37
   *
38
   * @param start point_t defining the starting point
39
   * @param end point_t defining the ending point
40
   * @param strokes number of strokes to execute
41
   */
42
  void Nozzle::stroke(const point_t &start, const point_t &end, const uint8_t &strokes) {
43
    #if ENABLED(NOZZLE_CLEAN_GOBACK)
44
      const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS];
45
    #endif
46
 
47
    // Move to the starting point
48
    do_blocking_move_to(start.x, start.y, start.z);
49
 
50
    // Start the stroke pattern
51
    for (uint8_t i = 0; i < (strokes >> 1); i++) {
52
      do_blocking_move_to_xy(end.x, end.y);
53
      do_blocking_move_to_xy(start.x, start.y);
54
    }
55
 
56
    #if ENABLED(NOZZLE_CLEAN_GOBACK)
57
      do_blocking_move_to(ix, iy, iz);
58
    #endif
59
  }
60
 
61
  /**
62
   * @brief Zig-zag clean pattern
63
   * @details Apply a zig-zag cleaning pattern
64
   *
65
   * @param start point_t defining the starting point
66
   * @param end point_t defining the ending point
67
   * @param strokes number of strokes to execute
68
   * @param objects number of triangles to do
69
   */
70
  void Nozzle::zigzag(const point_t &start, const point_t &end, const uint8_t &strokes, const uint8_t &objects) {
71
    const float diffx = end.x - start.x, diffy = end.y - start.y;
72
    if (!diffx || !diffy) return;
73
 
74
    #if ENABLED(NOZZLE_CLEAN_GOBACK)
75
      const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS];
76
    #endif
77
 
78
    do_blocking_move_to(start.x, start.y, start.z);
79
 
80
    const uint8_t zigs = objects << 1;
81
    const bool horiz = ABS(diffx) >= ABS(diffy);    // Do a horizontal wipe?
82
    const float P = (horiz ? diffx : diffy) / zigs;   // Period of each zig / zag
83
    const point_t *side;
84
    for (uint8_t j = 0; j < strokes; j++) {
85
      for (int8_t i = 0; i < zigs; i++) {
86
        side = (i & 1) ? &end : &start;
87
        if (horiz)
88
          do_blocking_move_to_xy(start.x + i * P, side->y);
89
        else
90
          do_blocking_move_to_xy(side->x, start.y + i * P);
91
      }
92
      for (int8_t i = zigs; i >= 0; i--) {
93
        side = (i & 1) ? &end : &start;
94
        if (horiz)
95
          do_blocking_move_to_xy(start.x + i * P, side->y);
96
        else
97
          do_blocking_move_to_xy(side->x, start.y + i * P);
98
      }
99
    }
100
 
101
    #if ENABLED(NOZZLE_CLEAN_GOBACK)
102
      do_blocking_move_to(ix, iy, iz);
103
    #endif
104
  }
105
 
106
  /**
107
   * @brief Circular clean pattern
108
   * @details Apply a circular cleaning pattern
109
   *
110
   * @param start point_t defining the middle of circle
111
   * @param strokes number of strokes to execute
112
   * @param radius radius of circle
113
   */
114
  void Nozzle::circle(const point_t &start, const point_t &middle, const uint8_t &strokes, const float &radius) {
115
    if (strokes == 0) return;
116
 
117
    #if ENABLED(NOZZLE_CLEAN_GOBACK)
118
      const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS];
119
    #endif
120
 
121
    do_blocking_move_to(start.x, start.y, start.z);
122
 
123
    for (uint8_t s = 0; s < strokes; s++)
124
      for (uint8_t i = 0; i < NOZZLE_CLEAN_CIRCLE_FN; i++)
125
        do_blocking_move_to_xy(
126
          middle.x + sin((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius,
127
          middle.y + cos((RADIANS(360) / NOZZLE_CLEAN_CIRCLE_FN) * i) * radius
128
        );
129
 
130
    // Let's be safe
131
    do_blocking_move_to_xy(start.x, start.y);
132
 
133
    #if ENABLED(NOZZLE_CLEAN_GOBACK)
134
      do_blocking_move_to(ix, iy, iz);
135
    #endif
136
  }
137
 
138
  /**
139
   * @brief Clean the nozzle
140
   * @details Starts the selected clean procedure pattern
141
   *
142
   * @param pattern one of the available patterns
143
   * @param argument depends on the cleaning pattern
144
   */
145
  void Nozzle::clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects/*=0*/) {
146
    switch (pattern) {
147
      case 1:
148
        zigzag(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes, objects);
149
        break;
150
 
151
      case 2:
152
        circle(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_CIRCLE_MIDDLE, strokes, radius);
153
        break;
154
 
155
      default:
156
        stroke(NOZZLE_CLEAN_START_POINT, NOZZLE_CLEAN_END_POINT, strokes);
157
    }
158
  }
159
 
160
#endif // NOZZLE_CLEAN_FEATURE
161
 
162
#if ENABLED(NOZZLE_PARK_FEATURE)
163
 
164
  constexpr float npp[] = NOZZLE_PARK_POINT;
165
  static_assert(COUNT(npp) == XYZ, "NOZZLE_PARK_POINT requires X, Y, and Z values.");
166
 
167
  void Nozzle::park(const uint8_t &z_action, const point_t &park/*=NOZZLE_PARK_POINT*/) {
168
    const float fr_xy = NOZZLE_PARK_XY_FEEDRATE, fr_z = NOZZLE_PARK_Z_FEEDRATE;
169
 
170
    switch (z_action) {
171
      case 1: // Go to Z-park height
172
        do_blocking_move_to_z(park.z, fr_z);
173
        break;
174
 
175
      case 2: // Raise by Z-park height
176
        do_blocking_move_to_z(MIN(current_position[Z_AXIS] + park.z, Z_MAX_POS), fr_z);
177
        break;
178
 
179
      default: // Raise to at least the Z-park height
180
        do_blocking_move_to_z(MAX(park.z, current_position[Z_AXIS]), fr_z);
181
    }
182
 
183
    do_blocking_move_to_xy(park.x, park.y, fr_xy);
184
  }
185
 
186
#endif // NOZZLE_PARK_FEATURE
187
 
188
#endif // NOZZLE_CLEAN_FEATURE || NOZZLE_PARK_FEATURE