From c711701626d9309f391065b99aa78115a4d7f177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Br=C3=A1zio?= Date: Thu, 14 Jul 2016 16:29:04 +0100 Subject: [PATCH] Implements a nozzle parking command (G27) --- .travis.yml | 10 +- Marlin/Configuration.h | 24 +++++ Marlin/Marlin_main.cpp | 27 +++++- Marlin/nozzle.h | 203 +++++++++++++++++++++++++---------------- 4 files changed, 179 insertions(+), 85 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4d003a95df..5d7b7b6f7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -211,10 +211,16 @@ script: - opt_enable PRINTCOUNTER - build_marlin # - # Test CLEAN_NOZZLE_FEATURE + # Test NOZZLE_PARK_FEATURE # - restore_configs - - opt_enable AUTO_BED_LEVELING_FEATURE CLEAN_NOZZLE_FEATURE FIX_MOUNTED_PROBE + - opt_enable NOZZLE_PARK_FEATURE + - build_marlin + # + # Test NOZZLE_CLEAN_FEATURE + # + - restore_configs + - opt_enable AUTO_BED_LEVELING_FEATURE NOZZLE_CLEAN_FEATURE FIX_MOUNTED_PROBE - build_marlin # # diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 96cb580689..27be90b7c0 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -787,6 +787,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l #define PREHEAT_2_TEMP_BED 110 #define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 +// +// Nozzle Park -- EXPERIMENTAL +// +// When enabled allows the user to define a special XYZ position, inside the +// machine's topology, to park the nozzle when idle or when receiving the G27 +// command. +// +// The "P" paramenter controls what is the action applied to the Z axis: +// P0: (Default) If current Z-pos is lower than Z-park then the nozzle will +// be raised to reach Z-park height. +// +// P1: No matter the current Z-pos, the nozzle will be raised/lowered to +// reach Z-park height. +// +// P2: The nozzle height will be raised by Z-park amount but never going over +// the machine's limit of Z_MAX_POS. +// +//#define NOZZLE_PARK_FEATURE + +#if ENABLED(NOZZLE_PARK_FEATURE) + // Specify a park position as { X, Y, Z } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } +#endif + // // Clean Nozzle Feature -- EXPERIMENTAL // diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 5091c421c4..9960c02f21 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -2736,9 +2736,12 @@ inline void gcode_G4() { #endif //FWRETRACT -#if ENABLED(NOZZLE_CLEAN_FEATURE) && ENABLED(AUTO_BED_LEVELING_FEATURE) +#if ENABLED(NOZZLE_CLEAN_FEATURE) && HAS_BED_PROBE #include "nozzle.h" + /** + * G12: Clean the nozzle + */ inline void gcode_G12() { // Don't allow nozzle cleaning without homing first if (axis_unhomed_error(true, true, true)) { return; } @@ -2795,6 +2798,20 @@ inline void gcode_G4() { #endif // QUICK_HOME +#if ENABLED(NOZZLE_PARK_FEATURE) + #include "nozzle.h" + + /** + * G27: Park the nozzle + */ + inline void gcode_G27() { + // Don't allow nozzle parking without homing first + if (axis_unhomed_error(true, true, true)) { return; } + uint8_t const z_action = code_seen('P') ? code_value_ushort() : 0; + Nozzle::park(z_action); + } +#endif // NOZZLE_PARK_FEATURE + /** * G28: Home all axes according to settings * @@ -6884,7 +6901,7 @@ void process_next_command() { #if ENABLED(NOZZLE_CLEAN_FEATURE) && HAS_BED_PROBE case 12: - gcode_G12(); // G12: Clean Nozzle + gcode_G12(); // G12: Nozzle Clean break; #endif // NOZZLE_CLEAN_FEATURE @@ -6898,6 +6915,12 @@ void process_next_command() { break; #endif // INCH_MODE_SUPPORT + #if ENABLED(NOZZLE_PARK_FEATURE) + case 27: // G27: Nozzle Park + gcode_G27(); + break; + #endif // NOZZLE_PARK_FEATURE + case 28: // G28: Home all axes, one at a time gcode_G28(); break; diff --git a/Marlin/nozzle.h b/Marlin/nozzle.h index 02771a5164..3e9ae879c9 100644 --- a/Marlin/nozzle.h +++ b/Marlin/nozzle.h @@ -30,8 +30,6 @@ * @brief Nozzle class * * @todo: Do not ignore the end.z value and allow XYZ movements - * @todo: Currently this feature needs HAS_BED_PROBE to be active - * due to the do_blocking_move_to*() functions. */ class Nozzle { private: @@ -43,34 +41,40 @@ class Nozzle { * @param end point_t defining the ending point * @param strokes number of strokes to execute */ - static void stroke(point_t const &start, point_t const &end, uint8_t const &strokes) - __attribute__ ((optimize ("Os"))) { - - #if ENABLED(NOZZLE_CLEAN_PARK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif - - // Move to the starting point - do_blocking_move_to_xy(start.x, start.y); - do_blocking_move_to_z(start.z); - - // Start the stroke pattern - for (uint8_t i = 0; i < (strokes >>1); i++) { - do_blocking_move_to_xy(end.x, end.y); + static void stroke( + __attribute__((unused)) point_t const &start, + __attribute__((unused)) point_t const &end, + __attribute__((unused)) uint8_t const &strokes + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + + #if ENABLED(NOZZLE_CLEAN_PARK) + // Store the current coords + point_t const initial = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; + #endif // NOZZLE_CLEAN_PARK + + // Move to the starting point do_blocking_move_to_xy(start.x, start.y); - } + do_blocking_move_to_z(start.z); - #if ENABLED(NOZZLE_CLEAN_PARK) - // Move the nozzle to the initial point - do_blocking_move_to_z(initial.z); - do_blocking_move_to_xy(initial.x, initial.y); - #endif + // Start the stroke pattern + for (uint8_t i = 0; i < (strokes >>1); i++) { + do_blocking_move_to_xy(end.x, end.y); + do_blocking_move_to_xy(start.x, start.y); + } + + #if ENABLED(NOZZLE_CLEAN_PARK) + // Move the nozzle to the initial point + do_blocking_move_to_z(initial.z); + do_blocking_move_to_xy(initial.x, initial.y); + #endif // NOZZLE_CLEAN_PARK + + #endif // NOZZLE_CLEAN_FEATURE } /** @@ -82,47 +86,53 @@ class Nozzle { * @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 &strokes, uint8_t const &objects) - __attribute__ ((optimize ("Os"))) { - float A = fabs(end.y - start.y); // [twice the] Amplitude - float P = fabs(end.x - start.x) / (objects << 1); // Period - - // Don't allow impossible triangles - if (A <= 0.0f || P <= 0.0f ) return; - - #if ENABLED(NOZZLE_CLEAN_PARK) - // Store the current coords - point_t const initial = { - current_position[X_AXIS], - current_position[Y_AXIS], - current_position[Z_AXIS], - current_position[E_AXIS] - }; - #endif - - 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); + static void zigzag( + __attribute__((unused)) point_t const &start, + __attribute__((unused)) point_t const &end, + __attribute__((unused)) uint8_t const &strokes, + __attribute__((unused)) uint8_t const &objects + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + float A = fabs(end.y - start.y); // [twice the] Amplitude + float P = fabs(end.x - start.x) / (objects << 1); // Period + + // Don't allow impossible triangles + if (A <= 0.0f || P <= 0.0f ) return; + + #if ENABLED(NOZZLE_CLEAN_PARK) + // Store the current coords + point_t const initial = { + current_position[X_AXIS], + current_position[Y_AXIS], + current_position[Z_AXIS], + current_position[E_AXIS] + }; + #endif // NOZZLE_CLEAN_PARK + + 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); + } } - 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)); + #if ENABLED(NOZZLE_CLEAN_PARK) + // Move the nozzle to the initial point + do_blocking_move_to_z(initial.z); + do_blocking_move_to_xy(initial.x, initial.y); + #endif // NOZZLE_CLEAN_PARK - do_blocking_move_to_xy(x, y); - } - } - - #if ENABLED(NOZZLE_CLEAN_PARK) - // Move the nozzle to the initial point - do_blocking_move_to_z(initial.z); - do_blocking_move_to_xy(initial.x, initial.y); - #endif + #endif // NOZZLE_CLEAN_FEATURE } public: @@ -133,21 +143,52 @@ class Nozzle { * @param pattern one of the available patterns * @param argument depends on the cleaning pattern */ - static void clean(uint8_t const &pattern, - uint8_t const &strokes, uint8_t const &objects = 0) - __attribute__ ((optimize ("Os"))) { - switch (pattern) { - case 1: - Nozzle::zigzag( - NOZZLE_CLEAN_START_PT, - NOZZLE_CLEAN_END_PT, strokes, objects); - break; - - default: - Nozzle::stroke( - NOZZLE_CLEAN_START_PT, - NOZZLE_CLEAN_END_PT, strokes); - } + static void clean( + __attribute__((unused)) uint8_t const &pattern, + __attribute__((unused)) uint8_t const &strokes, + __attribute__((unused)) uint8_t const &objects = 0 + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_CLEAN_FEATURE) + switch (pattern) { + case 1: + Nozzle::zigzag( + NOZZLE_CLEAN_START_PT, + NOZZLE_CLEAN_END_PT, strokes, objects); + break; + + default: + Nozzle::stroke( + NOZZLE_CLEAN_START_PT, + NOZZLE_CLEAN_END_PT, strokes); + } + #endif // NOZZLE_CLEAN_FEATURE + } + + static void park( + __attribute__((unused)) uint8_t const &z_action + ) __attribute__((optimize ("Os"))) { + #if ENABLED(NOZZLE_PARK_FEATURE) + float const z = current_position[Z_AXIS]; + point_t const park = NOZZLE_PARK_POINT; + + switch(z_action) { + case 1: // force Z-park height + do_blocking_move_to_z(park.z); + break; + + case 2: // Raise by Z-park height + do_blocking_move_to_z( + (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z); + break; + + default: // Raise to Z-park height if lower + if (current_position[Z_AXIS] < park.z) + do_blocking_move_to_z(park.z); + } + + do_blocking_move_to_xy(park.x, park.y); + + #endif // NOZZLE_PARK_FEATURE } };