diff --git a/Marlin/Conditionals_LulzBot.h b/Marlin/Conditionals_LulzBot.h index b6a95200a..8fea819fe 100644 --- a/Marlin/Conditionals_LulzBot.h +++ b/Marlin/Conditionals_LulzBot.h @@ -13,7 +13,7 @@ * got disabled. */ -#define LULZBOT_FW_VERSION ".37" // Change this with each update +#define LULZBOT_FW_VERSION ".40" // Change this with each update #if ( \ !defined(LULZBOT_Gladiola_Mini) && \ @@ -116,6 +116,7 @@ #define LULZBOT_REPROBE_EXTENDED_RECOVERY #define LULZBOT_USE_TMC_STEALTHCHOP_Z #define LULZBOT_USE_Z_BELT + #define LULZBOT_USE_Z_BACKLASH_COMPENSATION #define LULZBOT_BAUDRATE 250000 #define LULZBOT_PRINTCOUNTER #define LULZBOT_USE_32_MICROSTEPS_ON_Z @@ -646,54 +647,6 @@ "M117 Leveling done." /* Set LCD status */ #endif - -/****************************** BACKLASH COMPENSATION **************************/ - -#if defined(LULZBOT_IS_MINI) && defined(LULZBOT_USE_Z_BELT) - //#define LULZBOT_AXIS_BACKLASH {0.00, 0.00, 0.35, 0} -#endif - -#if defined(LULZBOT_AXIS_BACKLASH) - #define SIGN(v) ((v < 0) ? -1.0 : 1.0) - #define LULZBOT_AXIS_BACKLASH_CORRECTION \ - { \ - static const float backlash[NUM_AXIS] = LULZBOT_AXIS_BACKLASH; \ - static uint8_t last_direction_bits; \ - static bool is_correction = false; \ - if(!is_correction && planner.leveling_active) { \ - uint8_t changed_dir = last_direction_bits ^ dm; \ - /* Ignore direction change if no steps are taken in that direction */ \ - if(da == 0) CBI(changed_dir, X_AXIS); \ - if(db == 0) CBI(changed_dir, Y_AXIS); \ - if(dc == 0) CBI(changed_dir, Z_AXIS); \ - if(de == 0) CBI(changed_dir, E_AXIS); \ - /* Update the direction bits */ \ - last_direction_bits ^= changed_dir; \ - /* When there is motion in an opposing direction, apply the backlash correction */ \ - if(changed_dir) { \ - long saved_position[NUM_AXIS] = { 0 }; \ - COPY(saved_position, position); \ - const long x_backlash = TEST(changed_dir, X_AXIS) ? backlash[X_AXIS] * axis_steps_per_mm[X_AXIS] * SIGN(da) : 0; \ - const long y_backlash = TEST(changed_dir, Y_AXIS) ? backlash[Y_AXIS] * axis_steps_per_mm[Y_AXIS] * SIGN(db) : 0; \ - const long z_backlash = TEST(changed_dir, Z_AXIS) ? backlash[Z_AXIS] * axis_steps_per_mm[Z_AXIS] * SIGN(dc) : 0; \ - const long e_backlash = TEST(changed_dir, E_AXIS) ? backlash[E_AXIS] * axis_steps_per_mm[E_AXIS] * SIGN(de) : 0; \ - is_correction = true; /* Avoid infinite recursion */ \ - buffer_segment( \ - (position[X_AXIS] + x_backlash)/axis_steps_per_mm[X_AXIS], \ - (position[Y_AXIS] + y_backlash)/axis_steps_per_mm[Y_AXIS], \ - (position[Z_AXIS] + z_backlash)/axis_steps_per_mm[Z_AXIS], \ - (position[E_AXIS] + e_backlash)/axis_steps_per_mm[E_AXIS_N], \ - fr_mm_s, extruder \ - ); \ - is_correction = false; \ - COPY(position, saved_position); \ - } \ - } \ - } -#else - #define LULZBOT_AXIS_BACKLASH_CORRECTION -#endif - /*************************** COMMON TOOLHEADS PARAMETERS ***********************/ #define LULZBOT_DEFAULT_EJERK 10.0 @@ -1747,6 +1700,73 @@ #define LULZBOT_BED_LEVELING_SUMMARY #endif + +/****************************** BACKLASH COMPENSATION **************************/ + +#if defined(LULZBOT_USE_Z_BACKLASH_COMPENSATION) + #define LULZBOT_BACKLASH_AUTOPROBE_RESOLUTION 0.005 + #define LULZBOT_BACKLASH_AUTOPROBE_LIMIT 0.5 + + #if ENABLED(LULZBOT_Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + #if defined(LULZBOT_Z_MIN_ENDSTOP_INVERTING) + #define LULZBOT_TEST_PROBE_PIN !READ(Z_MIN_PIN) + #else + #define LULZBOT_TEST_PROBE_PIN READ(Z_MIN_PIN) + #endif + #else + #if defined(LULZBOT_Z_MIN_PROBE_ENDSTOP_INVERTING) + #define LULZBOT_TEST_PROBE_PIN !READ(Z_MIN_PROBE) + #else + #define LULZBOT_TEST_PROBE_PIN READ(Z_MIN_PROBE) + #endif + #endif + + #define LULZBOT_BACKLASH_AUTOPROBE_DECL int32_t z_backlash_steps = 0; + #define LULZBOT_BACKLASH_AUTOPROBE_EXTERN extern int32_t z_backlash_steps; + #define LULZBOT_BACKLASH_AUTOPROBE_RESET z_backlash_steps = LULZBOT_BACKLASH_AUTOPROBE_LIMIT * planner.axis_steps_per_mm[Z_AXIS]; + + #define LULZBOT_BACKLASH_AUTOPROBE \ + { \ + float start_height = current_position[Z_AXIS]; \ + while(current_position[Z_AXIS] < (start_height + LULZBOT_BACKLASH_AUTOPROBE_LIMIT) && LULZBOT_TEST_PROBE_PIN) { \ + do_blocking_move_to_z(current_position[Z_AXIS] + LULZBOT_BACKLASH_AUTOPROBE_RESOLUTION, MMM_TO_MMS(Z_PROBE_SPEED_SLOW)); \ + } \ + const float measured_backlash_mm = current_position[Z_AXIS] - start_height; \ + z_backlash_steps = min(z_backlash_steps, measured_backlash_mm * planner.axis_steps_per_mm[Z_AXIS]); \ + } + + #define LULZBOT_BACKLASH_CORRECTION \ + { \ + static bool last_z_direction; \ + static bool is_correction = false; \ + if(!is_correction && planner.leveling_active) { \ + const bool new_z_direction = TEST(dm, Z_AXIS); \ + /* When there is motion in an opposing Z direction, apply the backlash correction */ \ + if((last_z_direction != new_z_direction) && (dc != 0)) { \ + last_z_direction = new_z_direction; \ + int32_t saved_position[NUM_AXIS], tweaked_position[XYZE]; \ + COPY( saved_position, position); \ + COPY(tweaked_position, position); \ + tweaked_position[Z_AXIS] += dc < 0 ? -z_backlash_steps : z_backlash_steps; \ + is_correction = true; /* Avoid infinite recursion */ \ + _buffer_steps(tweaked_position, fr_mm_s, extruder); \ + is_correction = false; \ + COPY(position, saved_position); \ + } \ + } \ + } + + #define LULZBOT_BACKLASH_AUTOPROBE_SUMMARY \ + SERIAL_ECHOLNPAIR("Measured Z-axis backlash: ", float(z_backlash_steps) / planner.axis_steps_per_mm[Z_AXIS]); +#else + #define LULZBOT_BACKLASH_AUTOPROBE + #define LULZBOT_BACKLASH_AUTOPROBE_DECL + #define LULZBOT_BACKLASH_AUTOPROBE_EXTERN + #define LULZBOT_BACKLASH_AUTOPROBE_RESET + #define LULZBOT_BACKLASH_CORRECTION + #define LULZBOT_BACKLASH_AUTOPROBE_SUMMARY +#endif + /******************************** MOTOR CURRENTS *******************************/ // Values for XYZ vary by printer model, values for E vary by toolhead. diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 04d7d74a5..fd3220337 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -363,6 +363,7 @@ LULZBOT_EXECUTE_IMMEDIATE_DECL LULZBOT_G29_WITH_RETRY_DECL LULZBOT_BED_LEVELING_DECL +LULZBOT_BACKLASH_AUTOPROBE_DECL bool Running = true; @@ -2275,6 +2276,7 @@ static void clean_up_after_endstop_or_probe_move() { // move down slowly to find bed //if (do_probe_move(-10, Z_PROBE_SPEED_SLOW)) return NAN; LULZBOT_DO_PROBE_MOVE(Z_PROBE_SPEED_SLOW); + LULZBOT_BACKLASH_AUTOPROBE #if MULTIPLE_PROBING > 2 probes_total += current_position[Z_AXIS]; @@ -5189,6 +5191,7 @@ void home_all_axes() { gcode_G28(true); } if (verbose_level) { LULZBOT_BED_LEVELING_SUMMARY + LULZBOT_BACKLASH_AUTOPROBE_SUMMARY SERIAL_PROTOCOLPGM("Eqn coefficients: a: "); SERIAL_PROTOCOL_F(plane_equation_coefficients[0], 8); @@ -11824,6 +11827,7 @@ void process_parsed_command( #if HAS_LEVELING case 29: // G29 Detailed Z probe, probes the bed at 3 or more points, // or provides access to the UBL System if enabled. + LULZBOT_BACKLASH_AUTOPROBE_RESET #if defined(LULZBOT_G29_COMMAND) LULZBOT_G29_COMMAND #else diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 80d79a445..7c64bfb46 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -73,6 +73,8 @@ #include "mesh_bed_leveling.h" #endif +LULZBOT_BACKLASH_AUTOPROBE_EXTERN + Planner planner; // public: @@ -787,7 +789,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const #endif if (de < 0) SBI(dm, E_AXIS); - LULZBOT_AXIS_BACKLASH_CORRECTION + LULZBOT_BACKLASH_CORRECTION const float esteps_float = de * e_factor[extruder]; const int32_t esteps = abs(esteps_float) + 0.5;