diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 6c170ccf3..c455c50a6 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -801,15 +801,20 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l // "strokes" i.e. back-and-forth movements between the starting and end // points. // -// P1: This starts a zig-zag pattern between (Xs, Ys) and (Xe, Ye), "S" -// defines the number of zig-zag triangles to be done. Each "side" -// cannot be less than 5mm. As an example "G12 P1 S3" will execute: -// -// /| /| /| (Xe, Ye) -// / | / | / | -// / | / | / | -// (Xs, Ys) / |/ |/ | -// +// P1: This starts a zig-zag pattern between (X0, Y0) and (X1, Y1), "T" +// defines the number of zig-zag triangles to be done. "S" defines the +// number of strokes aka one back-and-forth movement. As an example +// sending "G12 P1 S1 T3" will execute: +// +// -- +// | (X0, Y1) | /\ /\ /\ | (X1, Y1) +// | | / \ / \ / \ | +// A | | / \ / \ / \ | +// | | / \ / \ / \ | +// | (X0, Y0) | / \/ \/ \ | (X1, Y0) +// -- +--------------------------------+ +// |________|_________|_________| +// T1 T2 T3 // // Caveats: End point Z should use the same value as Start point Z. // @@ -820,8 +825,8 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l #if ENABLED(CLEAN_NOZZLE_FEATURE) #define CLEAN_NOZZLE_STROKES 12 - #define CLEAN_NOZZLE_START_PT { 30, 30, (Z_MIN_POS + 1), 0} - #define CLEAN_NOZZLE_END_PT {100, 60, (Z_MIN_POS + 1), 0} + #define CLEAN_NOZZLE_START_PT { 30, 30, (Z_MIN_POS + 5), 0} + #define CLEAN_NOZZLE_END_PT {100, 60, (Z_MIN_POS + 5), 0} // { X, Y, Z, E} #endif diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index ac7c5f19e..835b20fcd 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -2718,7 +2718,7 @@ inline void gcode_G4() { #endif //FWRETRACT #if ENABLED(CLEAN_NOZZLE_FEATURE) && ENABLED(AUTO_BED_LEVELING_FEATURE) - #include "clean_nozzle.h" + #include "nozzle.h" inline void gcode_G12() { // Don't allow nozzle cleaning without homing first @@ -2729,8 +2729,9 @@ inline void gcode_G4() { uint8_t const pattern = code_seen('P') ? code_value_ushort() : 0; uint8_t const strokes = code_seen('S') ? code_value_ushort() : CLEAN_NOZZLE_STROKES; + uint8_t const objects = code_seen('T') ? code_value_ushort() : 3; - CleanNozzle::start(pattern, strokes); + Nozzle::clean(pattern, strokes, objects); } #endif diff --git a/Marlin/clean_nozzle.h b/Marlin/nozzle.h similarity index 61% rename from Marlin/clean_nozzle.h rename to Marlin/nozzle.h index 9670605b0..796d18b34 100644 --- a/Marlin/clean_nozzle.h +++ b/Marlin/nozzle.h @@ -27,13 +27,13 @@ #include "point_t.h" /** - * @brief CleanNozzle class + * @brief Nozzle class * * @todo: Do not ignore the end.z value and allow XYZ movements * @todo: Currently this feature needs AUTO_BED_LEVELING_FEATURE to be active * due to the do_blocking_move_to*() functions. */ -class CleanNozzle { +class Nozzle { private: /** * @brief Stroke clean pattern @@ -62,26 +62,46 @@ class CleanNozzle { * * @param start point_t defining the starting point * @param end point_t defining the ending point - * @param triangles number of triangles to execute + * @param strokes number of strokes to execute + * @param objects number of objects to create */ - static void zigzag(point_t const &start, point_t const &end, uint8_t const &triangles) + static void zigzag(point_t const &start, + point_t const &end, uint8_t const &strokes, uint8_t const &objects) __attribute__ ((optimize ("Os"))) { - // Move to the starting point - do_blocking_move_to_xy(start.x, start.y); - do_blocking_move_to_z(start.z); + float A = fabs(end.y - start.y); // [twice the] Amplitude + float P = fabs(end.x - start.x) / (objects << 1); // Period - // Calculate the triangle side - float const a = fabs(end.x - start.x) / triangles; + // Don't allow impossible triangles + if (A <= 0.0f || P <= 0.0f ) return; - // Don't allow the sides (a, b) to be smaller than 5mm - if (a < 5 || fabs(end.y - start.y) < 5) return; + // Store the current coords + point_t const home = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; - // Start the zig-zag pattern - for (uint8_t i = 0; i < triangles; i++) { - float const x = start.x + (a * (i + 1)); - do_blocking_move_to_xy(x, end.y); - do_blocking_move_to_y(start.y); + for (uint8_t j = 0; j < strokes; j++) { + for (uint8_t i = 0; i < (objects << 1); i++) { + float const x = start.x + i * P; + float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)); + + do_blocking_move_to_xy(x, y); + if (i == 0) do_blocking_move_to_z(start.z); + } + + for (int i = (objects << 1); i > -1; i--) { + float const x = start.x + i * P; + float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P)); + + do_blocking_move_to_xy(x, y); + } } + + // Move to home/start position + do_blocking_move_to_z(home.z); + do_blocking_move_to_xy(home.x, home.y); } public: @@ -92,19 +112,20 @@ class CleanNozzle { * @param pattern one of the available patterns * @param argument depends on the cleaning pattern */ - static void start(uint8_t const &pattern, uint8_t const &argument) + static void clean(uint8_t const &pattern, + uint8_t const &strokes, uint8_t const &objects = 0) __attribute__ ((optimize ("Os"))) { switch (pattern) { case 1: - CleanNozzle::zigzag( + Nozzle::zigzag( CLEAN_NOZZLE_START_PT, - CLEAN_NOZZLE_END_PT, argument); + CLEAN_NOZZLE_END_PT, strokes, objects); break; default: - CleanNozzle::stroke( + Nozzle::stroke( CLEAN_NOZZLE_START_PT, - CLEAN_NOZZLE_END_PT, argument); + CLEAN_NOZZLE_END_PT, strokes); } } };