From 0a52d5c03233b84a8975b6626ce374d8e2777337 Mon Sep 17 00:00:00 2001 From: InsanityAutomation Date: Wed, 22 Jul 2020 17:07:44 -0400 Subject: [PATCH] Add New G34 mode for current adjustable drivers TODO : Sanity checks, Finish DAC mode, Test on Rambo --- Marlin/Configuration_adv.h | 19 ++ Marlin/src/gcode/calibrate/G34_M422.cpp | 281 +++++++++++------------- Marlin/src/lcd/language/language_en.h | 6 +- 3 files changed, 144 insertions(+), 162 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index dbee6ebffa..355d69e440 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -3361,6 +3361,25 @@ #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 is highly recommended here as position is likely no longer accurate. #endif +/** + * Modern replacement for the Prusa TMC_Z_CALIBRATION + * Adds capability to work with any adjustable current drivers + * Implements as G34 as M915 is deprecated + */ + +//#define MECHANICAL_GANTRY_CALIBRATION +#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) + #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma + #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move + #define GANTRY_CALIBRATION_DIRECTION 1 // Set to 1 for Max or 0 for min + #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move + + //#define GANTRY_CALIBRATION_SAFE_POSITION {X_CENTER, Y_CENTER} // Safe position for nozzle + //#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM + //#define GANTRY_CALIBRATION_COMMANDS_PRE "" + //#define GANTRY_CALIBRATION_COMMANDS_POST "G28" +#endif + /** * MAX7219 Debug Matrix * diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index 8e501326b6..68b5b1b7b0 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -20,37 +20,33 @@ * */ -#include "../../inc/MarlinConfigPre.h" +#include "../../inc/MarlinConfig.h" + +#if ENABLED(Z_STEPPER_AUTO_ALIGN) + +#include "../../feature/z_stepper_align.h" #include "../gcode.h" #include "../../module/planner.h" #include "../../module/stepper.h" #include "../../module/motion.h" #include "../../module/probe.h" -#include "../../lcd/ultralcd.h" // for LCD_MESSAGEPGM - -#if HAS_LEVELING - #include "../../feature/bedlevel/bedlevel.h" -#endif #if HAS_MULTI_HOTEND #include "../../module/tool_change.h" #endif - - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -#if ENABLED(Z_STEPPER_AUTO_ALIGN) - - -#include "../../feature/z_stepper_align.h" +#if HAS_LEVELING + #include "../../feature/bedlevel/bedlevel.h" +#endif #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) #include "../../libs/least_squares_fit.h" #endif +#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) +#include "../../core/debug_out.h" + /** * G34: Z-Stepper automatic alignment * @@ -158,29 +154,22 @@ void GcodeSuite::G34() { z_maxdiff = 0.0f, amplification = z_auto_align_amplification; + // These are needed after the for-loop + uint8_t iteration; + bool err_break = false; + float z_measured_min; + #if DISABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) bool adjustment_reverse = false; #endif - #if HAS_DISPLAY - PGM_P const msg_iteration = GET_TEXT(MSG_ITERATION); - const uint8_t iter_str_len = strlen_P(msg_iteration); - #endif - - // Final z and iteration values will be used after breaking the loop - float z_measured_min; - uint8_t iteration = 0; - bool err_break = false; // To break out of nested loops - while (iteration < z_auto_align_iterations) { + // 'iteration' is declared above and is also used after the for-loop. + // *not* the same as LOOP_L_N(iteration, z_auto_align_iterations) + for (iteration = 0; iteration < z_auto_align_iterations; ++iteration) { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions."); - const int iter = iteration + 1; - SERIAL_ECHOLNPAIR("\nG34 Iteration: ", iter); - #if HAS_DISPLAY - char str[iter_str_len + 2 + 1]; - sprintf_P(str, msg_iteration, iter); - ui.set_status(str); - #endif + SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1)); + ui.set_status("\nITERATION: ", int(iteration + 1)); // Initialize minimum value z_measured_min = 100000.0f; @@ -202,8 +191,8 @@ void GcodeSuite::G34() { // current_position.z has been manually altered in the "dirty trick" above. const float z_probed_height = probe.probe_at_point(z_stepper_align.xy[iprobe], raise_after, 0, true, false); if (isnan(z_probed_height)) { - SERIAL_ECHOLNPGM("Probing failed"); - LCD_MESSAGEPGM(MSG_LCD_PROBING_FAILED); + SERIAL_ECHOLNPGM(MSG_LCD_PROBING_FAILED); + ui.set_status_P(MSG_LCD_PROBING_FAILED) err_break = true; break; } @@ -262,27 +251,13 @@ void GcodeSuite::G34() { , " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) #endif ); - #if HAS_DISPLAY - char fstr1[10]; - #if NUM_Z_STEPPER_DRIVERS == 2 - char msg[6 + (6 + 5) * 1 + 1]; - #else - char msg[6 + (6 + 5) * 3 + 1], fstr2[10], fstr3[10]; + ui.set_status("\n" + "DIFFERENCE Z1-Z2=", ABS(z_measured[0] - z_measured[1]) + #if NUM_Z_STEPPER_DRIVERS == 3 + , " Z2-Z3=", ABS(z_measured[1] - z_measured[2]) + , " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) #endif - sprintf_P(msg, - PSTR("Diffs Z1-Z2=%s" - #if NUM_Z_STEPPER_DRIVERS == 3 - " Z2-Z3=%s" - " Z3-Z1=%s" - #endif - ), dtostrf(ABS(z_measured[0] - z_measured[1]), 1, 3, fstr1) - #if NUM_Z_STEPPER_DRIVERS == 3 - , dtostrf(ABS(z_measured[1] - z_measured[2]), 1, 3, fstr2) - , dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3) - #endif - ); - ui.set_status(msg); - #endif + ); #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) // Check if the applied corrections go in the correct direction. @@ -301,8 +276,8 @@ void GcodeSuite::G34() { // If it's getting worse, stop and throw an error if (last_z_align_level_indicator < z_align_level_indicator * 0.7f) { - SERIAL_ECHOLNPGM("Decreasing Accuracy Detected."); - LCD_MESSAGEPGM(MSG_DECREASING_ACCURACY); + SERIAL_ECHOLNPGM(DECREASING_ACCURACY); + ui.set_status_P(DECREASING_ACCURACY); err_break = true; break; } @@ -326,8 +301,8 @@ void GcodeSuite::G34() { // Check for less accuracy compared to last move if (last_z_align_move[zstepper] < z_align_abs * 0.7f) { - SERIAL_ECHOLNPGM("Decreasing Accuracy Detected."); - LCD_MESSAGEPGM(MSG_DECREASING_ACCURACY); + SERIAL_ECHOLNPGM(DECREASING_ACCURACY); + ui.set_status_P(DECREASING_ACCURACY); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " last_z_align_move = ", last_z_align_move[zstepper]); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("> Z", int(zstepper + 1), " z_align_abs = ", z_align_abs); adjustment_reverse = !adjustment_reverse; @@ -367,12 +342,11 @@ void GcodeSuite::G34() { if (success_break) { SERIAL_ECHOLNPGM("Target accuracy achieved."); - LCD_MESSAGEPGM(MSG_ACCURACY_ACHIEVED); + ui.set_status_P(PGM_P("Target accuracy achieved.")); break; } - iteration++; - } // while (iteration < z_auto_align_iterations) + } // for (iteration) if (err_break) SERIAL_ECHOLNPGM("G34 aborted."); @@ -511,132 +485,123 @@ void GcodeSuite::M422() { } #elif ENABLED(MECHANICAL_GANTRY_CALIBRATION) - - #include "../../module/endstops.h" - void GcodeSuite::G34() { - if (homing_needed()) return; + if (axis_unhomed_error()) return; TEMPORARY_SOFT_ENDSTOP_STATE(false); TEMPORARY_BED_LEVELING_STATE(false); - TemporaryGlobalEndstopsState unlock_z(false); #ifdef GANTRY_CALIBRATION_COMMANDS_PRE gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_PRE)); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Sub Commands Processed"); #endif - #ifdef GANTRY_CALIBRATION_SAFE_POSITION - // Move XY to safe position - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Parking XY"); - const xy_pos_t safe_pos = GANTRY_CALIBRATION_SAFE_POSITION; - do_blocking_move_to(safe_pos, MMM_TO_MMS(GANTRY_CALIBRATION_XY_PARK_FEEDRATE)); - #endif - - const float move_distance = parser.intval('Z', GANTRY_CALIBRATION_EXTRA_HEIGHT), - zpounce = ( - #if GANTRY_CALIBRATION_DIRECTION == 1 - (Z_MAX_POS) - move_distance - #else - (Z_MIN_POS) + move_distance - #endif - ), - zgrind = ( - #if GANTRY_CALIBRATION_DIRECTION == 1 - (Z_MAX_POS) + move_distance - #else - (Z_MIN_POS) - move_distance - #endif - ); - - // Move Z to pounce position - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Setting Z Pounce"); - do_blocking_move_to_z(zpounce, MMM_TO_MMS(HOMING_FEEDRATE_Z)); - // Store current motor settings, then apply reduced value - - #define _REDUCE_CURRENT ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_DAC, HAS_MOTOR_CURRENT_I2C, HAS_TRINAMIC_CONFIG) - #if _REDUCE_CURRENT - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Reducing Current"); + #if DAC_STEPPER_CURRENT + const float target_current = parserfloatval('S', GANTRY_CALIBRATION_CURRENT); + const float previous_current = dac_amps(Z_AXIS, target_current); + else + const int16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); #endif - #if HAS_MOTOR_CURRENT_SPI - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); - const uint32_t previous_current = stepper.motor_current_setting[Z_AXIS]; - stepper.set_digipot_current(Z_AXIS, target_current); + #if HAS_DIGIPOTSS + const uint32_t previous_current = motor_current_setting[Z_AXIS]; + stepper.digipot_current(Z_AXIS, target_current); #elif HAS_MOTOR_CURRENT_PWM - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); - const uint32_t previous_current = stepper.motor_current_setting[Z_AXIS]; - stepper.set_digipot_current(1, target_current); - #elif HAS_MOTOR_CURRENT_DAC - const float target_current = parser.floatval('S', GANTRY_CALIBRATION_CURRENT); - const float previous_current = dac_amps(Z_AXIS, target_current); - stepper_dac.set_current_value(Z_AXIS, target_current); - #elif ENABLED(HAS_MOTOR_CURRENT_I2C) - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); + const uint32_t previous_current = motor_current_setting[Z_AXIS]; + stepper.digipot_current(1, target_current); + #if DAC_STEPPER_CURRENT + dac_current_raw(Z_AXIS, target_current); + #elif ENABLED(HAS_I2C_DIGIPOT) previous_current = dac_amps(Z_AXIS); - digipot_i2c.set_current(Z_AXIS, target_current) + digipot_i2c_set_current(Z_AXIS, target_current) #elif HAS_TRINAMIC_CONFIG - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); static uint16_t previous_current_arr[NUM_Z_STEPPER_DRIVERS]; #if AXIS_IS_TMC(Z) - previous_current_arr[0] = stepperZ.getMilliamps(); - stepperZ.rms_current(target_current); - #endif - #if AXIS_IS_TMC(Z2) - previous_current_arr[1] = stepperZ2.getMilliamps(); - stepperZ2.rms_current(target_current); - #endif - #if AXIS_IS_TMC(Z3) - previous_current_arr[2] = stepperZ3.getMilliamps(); - stepperZ3.rms_current(target_current); - #endif - #if AXIS_IS_TMC(Z4) - previous_current_arr[3] = stepperZ4.getMilliamps(); - stepperZ4.rms_current(target_current); - #endif + previous_current_arr[0] = stepperZ.getMilliamps(); + stepperZ.rms_current(target_current); + #endif + #if AXIS_IS_TMC(Z2) + previous_current_arr[1] = stepperZ2.getMilliamps(); + stepperZ2.rms_current(target_current); + #endif + #if AXIS_IS_TMC(Z3) + previous_current_arr[2] = stepperZ3.getMilliamps(); + stepperZ3.rms_current(target_current); + #endif + #if AXIS_IS_TMC(Z4) + previous_current_arr[3] = stepperZ4.getMilliamps(); + stepperZ4.rms_current(target_current); + #endif #endif + // Move XY to safe position + #ifdef GANTRY_CALIBRATION_SAFE_POSITION + xy_pos_t safe_pos = GANTRY_CALIBRATION_SAFE_POSITION; + current_position[X_AXIS] = safe_pos[X_AXIS]; + current_position[Y_AXIS] = safe_pos[Y_AXIS]; + do_blocking_move_to(current_position, MMM_TO_MMS(GANTRY_CALIBRATION_XY_PARK_FEEDRATE); + planner.synchronize(); + #endif + + const uint16_t move_distance = parser.intval('Z', GANTRY_CALIBRATION_EXTRA_HEIGHT); + + // Move Z to pounce position + #if GANTRY_CALIBRATION_DIRECTION == 1 + current_position[Z_AXIS] = (Z_MAX_POS - move_distance); + #else + current_position[Z_AXIS] = (Z_MIN_POS + move_distance); + #endif + + do_blocking_move_to(current_position, MMM_TO_MMS(HOMING_FEEDRATE_Z); + planner.synchronize(); + // Do Final Z move to adjust - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Final Z Move"); - do_blocking_move_to_z(zgrind, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE)); - - // Back off end plate, back to normal motion range - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Backoff"); - do_blocking_move_to_z(zpounce, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE)); - - // Reset current to original values - - #if _REDUCE_CURRENT - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore Current"); + #if GANTRY_CALIBRATION_DIRECTION == 1 + current_position[Z_AXIS] = (Z_MAX_POS + move_distance); + #else + current_position[Z_AXIS] = (Z_MIN_POS - move_distance); #endif - #if HAS_MOTOR_CURRENT_SPI - stepper.set_digipot_current(Z_AXIS, previous_current); + do_blocking_move_to(current_position, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE); + planner.synchronize(); + + // Back off end plate, back to normal motion range + #if GANTRY_CALIBRATION_DIRECTION == 1 + current_position[Z_AXIS] = (Z_MAX_POS - move_distance); + #else + current_position[Z_AXIS] = (Z_MIN_POS + move_distance); + #endif + + do_blocking_move_to(current_position, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE); + planner.synchronize(); + + // Reset current to original values + #if HAS_DIGIPOTSS + stepper.digipot_current(Z_AXIS, previous_current); #elif HAS_MOTOR_CURRENT_PWM - stepper.set_digipot_current(1, previous_current); - #elif HAS_MOTOR_CURRENT_DAC - stepper_dac.set_current_value(Z_AXIS, previous_current); - #elif ENABLED(HAS_MOTOR_CURRENT_I2C) - digipot_i2c.set_current(Z_AXIS, previous_current) + stepper.digipot_current(1, previous_current); + #if DAC_STEPPER_CURRENT + dac_current_raw(Z_AXIS, previous_current); + #elif ENABLED(HAS_I2C_DIGIPOT) + digipot_i2c_set_current(Z_AXIS, previous_current) #elif HAS_TRINAMIC_CONFIG + static uint16_t previous_current_arr[NUM_Z_STEPPER_DRIVERS]; #if AXIS_IS_TMC(Z) - stepperZ.rms_current(previous_current_arr[0]); - #endif - #if AXIS_IS_TMC(Z2) - stepperZ2.rms_current(previous_current_arr[1]); - #endif - #if AXIS_IS_TMC(Z3) - stepperZ3.rms_current(previous_current_arr[2]); - #endif - #if AXIS_IS_TMC(Z4) - stepperZ4.rms_current(previous_current_arr[3]); - #endif + stepperZ.rms_current(previous_current_arr[0]); + #endif + #if AXIS_IS_TMC(Z2) + stepperZ2.rms_current(previous_current_arr[1]); + #endif + #if AXIS_IS_TMC(Z3) + stepperZ3.rms_current(previous_current_arr[2]); + #endif + #if AXIS_IS_TMC(Z4) + stepperZ4.rms_current(previous_current_arr[3]); + #endif #endif #ifdef GANTRY_CALIBRATION_COMMANDS_POST - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Running Post Commands"); gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_POST)); #endif } diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 307e23657f..f19edc90d9 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -26,6 +26,7 @@ * * LCD Menu Messages * See also https://marlinfw.org/docs/development/lcd_language.html + * */ #define en 1234 @@ -67,9 +68,7 @@ namespace Language_en { PROGMEM Language_Str MSG_AUTO_HOME_Z = _UxGT("Home Z"); PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Auto Z-Align"); PROGMEM Language_Str MSG_ASSISTED_TRAMMING = _UxGT("Assisted Tramming"); - PROGMEM Language_Str MSG_ITERATION = _UxGT("G34 Iteration: %i"); - PROGMEM Language_Str MSG_DECREASING_ACCURACY = _UxGT("Accuracy Decreasing!"); - PROGMEM Language_Str MSG_ACCURACY_ACHIEVED = _UxGT("Accuracy Achieved"); + PROGMEM Language_Str DECREASING_ACCURACY = _UxGT("Decreasing accuracy detected."); PROGMEM Language_Str MSG_LEVEL_BED_HOMING = _UxGT("Homing XYZ"); PROGMEM Language_Str MSG_LEVEL_BED_WAITING = _UxGT("Click to Begin"); PROGMEM Language_Str MSG_LEVEL_BED_NEXT_POINT = _UxGT("Next Point"); @@ -368,7 +367,6 @@ namespace Language_en { PROGMEM Language_Str MSG_PAUSING = _UxGT("Pausing..."); PROGMEM Language_Str MSG_PAUSE_PRINT = _UxGT("Pause Print"); PROGMEM Language_Str MSG_RESUME_PRINT = _UxGT("Resume Print"); - PROGMEM Language_Str MSG_HOST_START_PRINT = _UxGT("Host Start"); PROGMEM Language_Str MSG_STOP_PRINT = _UxGT("Stop Print"); PROGMEM Language_Str MSG_PRINTING_OBJECT = _UxGT("Printing Object"); PROGMEM Language_Str MSG_CANCEL_OBJECT = _UxGT("Cancel Object");