diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 4aada14685..617b11fb33 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -815,7 +815,9 @@ #endif // Check for stuck or disconnected endstops during homing moves. -#define DETECT_BROKEN_ENDSTOP +#if DISABLED(TazPro, MiniV2) + #define DETECT_BROKEN_ENDSTOP +#endif //============================================================================= //============================== Movement Settings ============================ @@ -858,7 +860,18 @@ * Override with M203 * X, Y, Z, E0 [, E1[, E2...]] */ -#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 40 } + +#if ENABLED(Mini) + #define Z_FEEDRATE 5 +#elif ENABLED(MiniV2) + #define Z_FEEDRATE 300 +#elif ENABLED(Taz6) + #define Z_FEEDRATE 5 +#elif ANY(Workhorse, TazPro) + #define Z_FEEDRATE 30 +#endif + +#define DEFAULT_MAX_FEEDRATE { 300, 300, Z_FEEDRATE, 40 } #define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2 #if ENABLED(LIMITED_MAX_FR_EDITING) @@ -1444,7 +1457,7 @@ * Turn on with the command 'M111 S32'. * NOTE: Requires a lot of PROGMEM! */ -//#define DEBUG_LEVELING_FEATURE +#define DEBUG_LEVELING_FEATURE #if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL) // Gradually reduce leveling correction until a set height is reached, diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 136a4dadb2..b0d37da0f0 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -182,8 +182,8 @@ * and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set * below 2. */ - #define WATCH_TEMP_PERIOD 40 // Seconds - #define WATCH_TEMP_INCREASE 10 // Degrees Celsius + #define WATCH_TEMP_PERIOD 50 // Seconds + #define WATCH_TEMP_INCREASE 5 // Degrees Celsius #endif /** @@ -638,7 +638,7 @@ */ #if ANY(MiniV2, TazPro) - #define SENSORLESS_BACKOFF_MM { 2, 2 } // (mm) Backoff from endstops before sensorless homing + #define SENSORLESS_BACKOFF_MM { 4, 4 } // (mm) Backoff from endstops before sensorless homing #else #define HOMING_BACKOFF_POST_MM { 2, 2, 16 } // (mm) Backoff from endstops after homing #define QUICK_HOME // If G28 contains XY do a diagonal move first @@ -781,6 +781,37 @@ #define HOME_AFTER_G34 #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) + + #if ENABLED(Mini) + #define GANTRY_CALIBRATION_CURRENT 900 // Default calibration current in ma - PWM + #elif ANY(Taz6, Workhorse) + #define GANTRY_CALIBRATION_CURRENT 120 // Default calibration current in ma - DIGIPOTSS + #elif ANY(MiniV2, TazPro) + #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma - TMC + #endif + #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move + #if ENABLED(MiniV2) + #define GANTRY_CALIBRATION_DIRECTION 0 // Set to 1 for Max or 0 for min + #else + #define GANTRY_CALIBRATION_DIRECTION 1 // Set to 1 for Max or 0 for min + #endif + + #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move + + #define GANTRY_CALIBRATION_SAFE_POSITION {X_CENTER, Y_MIN} // 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 + // // Add the G35 command to read bed corners to help adjust screws. Requires a bed probe. // @@ -3286,21 +3317,51 @@ /** * User-defined menu items that execute custom GCode */ -#define CUSTOM_USER_MENUS +#if DISABLED(TazPro) + #define CUSTOM_USER_MENUS +#endif #if ENABLED(CUSTOM_USER_MENUS) #define CUSTOM_USER_MENU_TITLE "Tool Heads" - #define USER_SCRIPT_DONE "Tool Changed" + #define USER_SCRIPT_DONE "M117 Tool Changed" #define USER_SCRIPT_AUDIBLE_FEEDBACK //#define USER_SCRIPT_RETURN // Return to status screen after a script + #if ANY(Taz6, Mini) + #define DEFAULT_PID "P28.79I1.91D108.51" + #else + #define DEFAULT_PID "P21.0I1.78D61.93" + #endif + + #if ANY(Taz6, Workhorse) + #define E_CURRENT_Aero "150" + #define E_CURRENT_Std "135" + #define E_CURRENT_Moar "135" + #define E_CURRENT_BMG "150" + #elif ENABLED(Mini) + #define E_CURRENT_Aero "1300" + #define E_CURRENT_Std "1350" + #define E_CURRENT_Moar "1250" + #define E_CURRENT_BMG "1350" + #else + #define E_CURRENT_Aero "1100" + #define E_CURRENT_Std "960" + #define E_CURRENT_Moar "960" + #define E_CURRENT_BMG "1100" + #endif + #define USER_DESC_1 "Aerostruder" - #define USER_GCODE_1 "M92E420\nM907E875\nM500" + #define USER_GCODE_1 "M92E420\nM206X0Y0\nM301" DEFAULT_PID "\nM907E" E_CURRENT_Aero "\nM500" #define USER_DESC_2 "Moarstruder" - #define USER_GCODE_2 "M92E819\nM907E750\nM500" + #define USER_GCODE_2 "M92E819\nM206X0Y0\nM301" DEFAULT_PID "\nM907E" E_CURRENT_Moar "\nM500" - #define USER_DESC_3 "Standard" - #define USER_GCODE_3 "M92E814\nM907E750\nM500" + #if NONE(Workhorse, MiniV2) + #define USER_DESC_3 "Standard" + #define USER_GCODE_3 "M92E814\nM206X0Y0\nM301" DEFAULT_PID "\nM907E" E_CURRENT_Std "\nM500" + #endif + + #define USER_DESC_4 "Mosquito BMG-M" + #define USER_GCODE_4 "M92E415\nM206X-5Y-12\nM301P148.07I26.58D206.21\nM907E" E_CURRENT_BMG "\nM500" #endif /** diff --git a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp index 69a66420f8..1f3b80c02f 100644 --- a/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp +++ b/Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp @@ -1548,6 +1548,9 @@ * numbers for those locations should be 0. */ #ifdef VALIDATE_MESH_TILT + #if ENABLED(Z_SAFE_HOMING) + constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT , Z_SAFE_HOMING_Y_POINT }; + #endif auto d_from = []{ DEBUG_ECHOPGM("D from "); }; auto normed = [&](const xy_pos_t &pos, const float &zadd) { return normal.x * pos.x + normal.y * pos.y + zadd; diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index f25fe32b07..03d2c60268 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -285,8 +285,8 @@ G29_TYPE GcodeSuite::G29() { G29_RETURN(false); } - const float rx = RAW_X_POSITION(parser.linearval('X', NAN)), - ry = RAW_Y_POSITION(parser.linearval('Y', NAN)); + const float rx = (parser.linearval('X', NAN)), + ry = (parser.linearval('Y', NAN)); int8_t i = parser.byteval('I', -1), j = parser.byteval('J', -1); if (!isnan(rx) && !isnan(ry)) { @@ -377,16 +377,20 @@ G29_TYPE GcodeSuite::G29() { } else { probe_position_lf.set( - parser.seenval('L') ? RAW_X_POSITION(parser.value_linear_units()) : x_min, - parser.seenval('F') ? RAW_Y_POSITION(parser.value_linear_units()) : y_min + parser.seenval('L') ? (parser.value_linear_units()) : x_min, + parser.seenval('F') ? (parser.value_linear_units()) : y_min ); probe_position_rb.set( - parser.seenval('R') ? RAW_X_POSITION(parser.value_linear_units()) : x_max, - parser.seenval('B') ? RAW_Y_POSITION(parser.value_linear_units()) : y_max + parser.seenval('R') ? (parser.value_linear_units()) : x_max, + parser.seenval('B') ? (parser.value_linear_units()) : y_max ); } if (!probe.good_bounds(probe_position_lf, probe_position_rb)) { + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Left : ", probe_position_lf.x); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Right : ", probe_position_rb.x); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Front : ", probe_position_lf.y); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Back : ", probe_position_rb.y); SERIAL_ECHOLNPGM("? (L,R,F,B) out of bounds."); G29_RETURN(false); } diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 78695bc05b..982060d292 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -119,20 +119,22 @@ // Disallow Z homing if X or Y homing is needed if (axis_unhomed_error(_BV(X_AXIS) | _BV(Y_AXIS))) return; - sync_plan_position(); /** * Move the Z probe (or just the nozzle) to the safe homing point * (Z is already at the right height) */ - destination.set(safe_homing_xy, current_position.z); + //update_workspace_offset(X_AXIS); + //update_workspace_offset(Y_AXIS); + destination.set((xy_float_t){ Z_SAFE_HOMING_X_POINT - home_offset[X_AXIS], Z_SAFE_HOMING_Y_POINT - home_offset[Y_AXIS] }, current_position.z); + //destination.set((xy_float_t){ Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }, current_position.z); TERN_(HOMING_Z_WITH_PROBE, destination -= probe.offset_xy); - if (position_is_reachable(destination)) { + if (DEBUGGING(LEVELING)) DEBUG_POS("home_z_safely", destination); - if (DEBUGGING(LEVELING)) DEBUG_POS("home_z_safely", destination); + if (position_is_reachable(destination)) { // This causes the carriage on Dual X to unpark TERN_(DUAL_X_CARRIAGE, active_extruder_parked = false); diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp index 3360dc050f..59a3ac9dc4 100644 --- a/Marlin/src/gcode/calibrate/G34_M422.cpp +++ b/Marlin/src/gcode/calibrate/G34_M422.cpp @@ -22,31 +22,32 @@ #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" - -#if HAS_MULTI_HOTEND - #include "../../module/tool_change.h" -#endif +#include "../../module/endstops.h" #if HAS_LEVELING #include "../../feature/bedlevel/bedlevel.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_MULTI_HOTEND + #include "../../module/tool_change.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 * @@ -169,6 +170,7 @@ void GcodeSuite::G34() { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions."); SERIAL_ECHOLNPAIR("\nITERATION: ", int(iteration + 1)); + ui.set_status("\nITERATION: ", int(iteration + 1)); // Initialize minimum value z_measured_min = 100000.0f; @@ -190,7 +192,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."); + SERIAL_ECHOLNPGM(MSG_LCD_PROBING_FAILED); + ui.set_status_P(MSG_LCD_PROBING_FAILED) err_break = true; break; } @@ -249,6 +252,13 @@ void GcodeSuite::G34() { , " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) #endif ); + 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 + ); #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS) // Check if the applied corrections go in the correct direction. @@ -267,7 +277,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."); + SERIAL_ECHOLNPGM(DECREASING_ACCURACY); + ui.set_status_P(DECREASING_ACCURACY); err_break = true; break; } @@ -291,7 +302,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."); + 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; @@ -329,7 +341,11 @@ void GcodeSuite::G34() { if (err_break) break; - if (success_break) { SERIAL_ECHOLNPGM("Target accuracy achieved."); break; } + if (success_break) { + SERIAL_ECHOLNPGM("Target accuracy achieved."); + ui.set_status_P(PGM_P("Target accuracy achieved.")); + break; + } } // for (iteration) @@ -469,4 +485,137 @@ void GcodeSuite::M422() { pos_dest[position_index] = pos; } +#elif ENABLED(MECHANICAL_GANTRY_CALIBRATION) + void GcodeSuite::G34() { + + 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)); + #endif + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Sub Commands Processed"); + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Parking XY"); + // 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 + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Setting Z Pounce"); + 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(); + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Reducing Current"); + // Store current motor settings, then apply reduced value + #if HAS_DIGIPOTSS + const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); + const uint32_t previous_current = stepper.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.digipot_current(1, target_current); + #elif DAC_STEPPER_CURRENT + const float target_current = parser.floatval('S', GANTRY_CALIBRATION_CURRENT); + const float previous_current = dac_amps(Z_AXIS, target_current); + dac_current_raw(Z_AXIS, target_current); + #elif ENABLED(HAS_I2C_DIGIPOT) + const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); + previous_current = dac_amps(Z_AXIS); + 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 + #endif + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Final Z Move"); + // Do Final Z move to adjust + #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(); + + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Backoff"); + // 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(); + + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore Current"); + // Reset current to original values + #if HAS_DIGIPOTSS + stepper.digipot_current(Z_AXIS, previous_current); + #elif HAS_MOTOR_CURRENT_PWM + stepper.digipot_current(1, previous_current); + #elif 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 + #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 + #endif + + + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Running Post Commands"); + #ifdef GANTRY_CALIBRATION_COMMANDS_POST + gcode.process_subcommands_now_P(PSTR(GANTRY_CALIBRATION_COMMANDS_POST)); + #endif + } + #endif // Z_STEPPER_AUTO_ALIGN diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 840df54f6a..bc1a43e83b 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -335,7 +335,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) { case 33: G33(); break; // G33: Delta Auto-Calibration #endif - #if ENABLED(Z_STEPPER_AUTO_ALIGN) + #if ANY(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) case 34: G34(); break; // G34: Z Stepper automatic alignment using probe #endif diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index e04cd637eb..175bca8881 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -462,11 +462,12 @@ private: TERN_(DELTA_AUTO_CALIBRATION, static void G33()); - #if ENABLED(Z_STEPPER_AUTO_ALIGN) + #if ANY(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) static void G34(); - static void M422(); #endif + TERN_(Z_STEPPER_AUTO_ALIGN, static void M422()); + TERN_(ASSISTED_TRAMMING, static void G35()); TERN_(G38_PROBE_TARGET, static void G38(const int8_t subcode)); diff --git a/Marlin/src/gcode/geometry/M206_M428.cpp b/Marlin/src/gcode/geometry/M206_M428.cpp index 2a007427a7..689651fd9d 100644 --- a/Marlin/src/gcode/geometry/M206_M428.cpp +++ b/Marlin/src/gcode/geometry/M206_M428.cpp @@ -41,6 +41,12 @@ void GcodeSuite::M206() { if (parser.seen(XYZ_CHAR(i))) set_home_offset((AxisEnum)i, parser.value_linear_units()); + if (!parser.seen_any()) { + SERIAL_ECHOLNPAIR("M206X : ", home_offset[X_AXIS]); + SERIAL_ECHOLNPAIR("M206Y : ", home_offset[Y_AXIS]); + SERIAL_ECHOLNPAIR("M206Z : ", home_offset[Z_AXIS]); + } + #if ENABLED(MORGAN_SCARA) if (parser.seen('T')) set_home_offset(A_AXIS, parser.value_float()); // Theta if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index f9b65c8bf4..6c810408e8 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -426,7 +426,7 @@ #elif defined(CHAMBER_HEATER_PIN) #error "CHAMBER_HEATER_PIN is now HEATER_CHAMBER_PIN. Please update your configuration and/or pins." #elif defined(TMC_Z_CALIBRATION) - #error "TMC_Z_CALIBRATION has been deprecated in favor of Z_STEPPER_AUTO_ALIGN. Please update your configuration." + #error "TMC_Z_CALIBRATION has been deprecated in favor of MECHANICAL_GANTRY_CALIBRATION. Please update your configuration." #elif defined(Z_MIN_PROBE_ENDSTOP) #error "Z_MIN_PROBE_ENDSTOP is no longer required. Please remove it from Configuration.h." #elif defined(DUAL_NOZZLE_DUPLICATION_MODE) @@ -2711,6 +2711,28 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #endif #endif +#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) + #if NONE(DAC_STEPPER_CURRENT, HAS_DIGIPOTSS, DAC_STEPPER_CURRENT, HAS_TRINAMIC_CONFIG, HAS_MOTOR_CURRENT_PWM) + #error "It is highly reccomended to have adjustable current drivers to prevent damage. Disable this line to continue anyway." + #else + #ifndef GANTRY_CALIBRATION_CURRENT + #error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_CURRENT to be set." + #endif + #ifndef GANTRY_CALIBRATION_EXTRA_HEIGHT + #error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_EXTRA_HEIGHT to be set." + #endif + #ifndef GANTRY_CALIBRATION_DIRECTION + #error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_DIRECTION to be set." + #endif + #ifndef GANTRY_CALIBRATION_FEEDRATE + #error "MECHANICAL_GANTRY_CALIBRATION Requires GANTRY_CALIBRATION_FEEDRATE to be set." + #endif + #endif + #if defined(GANTRY_CALIBRATION_SAFE_POSITION) && !defined(GANTRY_CALIBRATION_XY_PARK_FEEDRATE) + #error "GANTRY_CALIBRATION_SAFE_POSITION Requires GANTRY_CALIBRATION_XY_PARK_FEEDRATE to be set." + #endif +#endif + #if ENABLED(PRINTCOUNTER) && DISABLED(EEPROM_SETTINGS) #error "PRINTCOUNTER requires EEPROM_SETTINGS. Please update your Configuration." #endif diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 9f6178ae50..f3adb8b067 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -67,6 +67,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 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"); diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp index 622cd091c0..024768f213 100644 --- a/Marlin/src/lcd/menu/menu_motion.cpp +++ b/Marlin/src/lcd/menu/menu_motion.cpp @@ -340,7 +340,7 @@ void menu_motion() { // // Auto Z-Align // - #if ENABLED(Z_STEPPER_AUTO_ALIGN) + #if ANY(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION) GCODES_ITEM(MSG_AUTO_Z_ALIGN, PSTR("G34")); #endif diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h index 38ce980dae..4400904d4b 100644 --- a/Marlin/src/module/motion.h +++ b/Marlin/src/module/motion.h @@ -78,10 +78,6 @@ extern xyz_pos_t cartes; #define XY_PROBE_FEEDRATE_MM_S PLANNER_XY_FEEDRATE() #endif -#if ENABLED(Z_SAFE_HOMING) - constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }; -#endif - /** * Feed rates are often configured with mm/m * but the planner and stepper like mm/s units. diff --git a/Marlin/src/module/probe.h b/Marlin/src/module/probe.h index 14036a18d9..8de33657b1 100644 --- a/Marlin/src/module/probe.h +++ b/Marlin/src/module/probe.h @@ -153,6 +153,9 @@ public: #else _MAX((X_MIN_BED) + (PROBING_MARGIN_LEFT), (X_MIN_POS) + offset_xy.x) #endif + #if ENABLED(NOZZLE_AS_PROBE) + - home_offset[X_AXIS] + #endif ); } static inline float max_x() { @@ -162,6 +165,9 @@ public: #else _MIN((X_MAX_BED) - (PROBING_MARGIN_RIGHT), (X_MAX_POS) + offset_xy.x) #endif + #if ENABLED(NOZZLE_AS_PROBE) + - home_offset[X_AXIS] + #endif ); } static inline float min_y() { @@ -171,6 +177,9 @@ public: #else _MAX((Y_MIN_BED) + (PROBING_MARGIN_FRONT), (Y_MIN_POS) + offset_xy.y) #endif + #if ENABLED(NOZZLE_AS_PROBE) + - home_offset[Y_AXIS] + #endif ); } static inline float max_y() { @@ -180,6 +189,9 @@ public: #else _MIN((Y_MAX_BED) - (PROBING_MARGIN_BACK), (Y_MAX_POS) + offset_xy.y) #endif + #if ENABLED(NOZZLE_AS_PROBE) + - home_offset[Y_AXIS] + #endif ); } diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index f1ab0fca69..6227c249d0 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -37,7 +37,7 @@ */ // Change EEPROM version if the structure changes -#define EEPROM_VERSION "V81" +#define EEPROM_VERSION "V82" #define EEPROM_OFFSET 100 // Check the integrity of data offsets. @@ -363,7 +363,11 @@ typedef struct SettingsDataStruct { // // HAS_MOTOR_CURRENT_PWM // - uint32_t motor_current_setting[3]; // M907 X Z E + #if HAS_DIGIPOTSS + uint32_t motor_current_setting[COUNT(stepper.motor_current_setting)]; + #else + uint32_t motor_current_setting[3]; // M907 X Z E + #endif // // CNC_COORDINATE_SYSTEMS @@ -1269,7 +1273,7 @@ void MarlinSettings::postprocess() { { _FIELD_TEST(motor_current_setting); - #if HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_PWM || HAS_DIGIPOTSS EEPROM_WRITE(stepper.motor_current_setting); #else const uint32_t no_current[3] = { 0 }; @@ -2100,10 +2104,14 @@ void MarlinSettings::postprocess() { // Motor Current PWM // { - uint32_t motor_current_setting[3]; + #if HAS_DIGIPOTSS + uint32_t motor_current_setting[] = DIGIPOT_MOTOR_CURRENT; + #else + uint32_t motor_current_setting[3]; // M907 X Z E + #endif _FIELD_TEST(motor_current_setting); EEPROM_READ(motor_current_setting); - #if HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_PWM || HAS_DIGIPOTSS if (!validating) COPY(stepper.motor_current_setting, motor_current_setting); #endif @@ -2786,6 +2794,14 @@ void MarlinSettings::reset() { stepper.digipot_current(q, (stepper.motor_current_setting[q] = tmp_motor_current_setting[q])); #endif + // + // DIGIPOTS + // + #if HAS_DIGIPOTSS + static constexpr uint32_t tmp_motor_current_setting[] = DIGIPOT_MOTOR_CURRENT; + LOOP_L_N(q, COUNT(tmp_motor_current_setting)) + stepper.digipot_current(q, tmp_motor_current_setting[q]); + #endif // // CNC Coordinate System // @@ -3693,6 +3709,13 @@ void MarlinSettings::reset() { , SP_Z_STR, stepper.motor_current_setting[1] , SP_E_STR, stepper.motor_current_setting[2] ); + #elif HASDIGIPOTSS + CONFIG_ECHO_HEADING("Stepper motor currents:"); + CONFIG_ECHO_START(); + LOOP_L_N(q, COUNT(stepper.motor_current_setting)) { + SERIAL_ECHOPAIR_P( "M907 ", axis_codes[q]); + SERIAL_ECHOLN_P(stepper.motor_current_setting[q]); + } #endif /** diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index c9d87486f8..baae1c0ba6 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -83,7 +83,7 @@ Stepper stepper; // Singleton #define BABYSTEPPING_EXTRA_DIR_WAIT -#if HAS_MOTOR_CURRENT_PWM +#if HAS_MOTOR_CURRENT_PWM || HAS_DIGIPOTSS bool Stepper::initialized; // = false #endif @@ -144,6 +144,9 @@ Stepper stepper; // Singleton #if HAS_MOTOR_CURRENT_PWM uint32_t Stepper::motor_current_setting[3]; // Initialized by settings.load() +#elif HAS_DIGIPOTSS + constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; + uint32_t Stepper::motor_current_setting[COUNT(digipot_count)]; // Initialized by settings.load() #endif // private: @@ -2591,7 +2594,7 @@ void Stepper::init() { set_directions(); #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM - TERN_(HAS_MOTOR_CURRENT_PWM, initialized = true); + initialized = true; digipot_init(); #endif } @@ -2965,18 +2968,18 @@ void Stepper::report_positions() { #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM void Stepper::digipot_current(const uint8_t driver, const int16_t current) { + if (WITHIN(driver, 0, COUNT(motor_current_setting) - 1)) + motor_current_setting[driver] = current; // update motor_current_setting + + if (!initialized) return; #if HAS_DIGIPOTSS - const uint8_t digipot_ch[] = DIGIPOT_CHANNELS; digitalPotWrite(digipot_ch[driver], current); #elif HAS_MOTOR_CURRENT_PWM - if (!initialized) return; - if (WITHIN(driver, 0, COUNT(motor_current_setting) - 1)) - motor_current_setting[driver] = current; // update motor_current_setting #define _WRITE_CURRENT_PWM(P) analogWrite(pin_t(MOTOR_CURRENT_PWM_## P ##_PIN), 255L * current / (MOTOR_CURRENT_PWM_RANGE)) switch (driver) { @@ -3015,14 +3018,12 @@ void Stepper::report_positions() { #if HAS_DIGIPOTSS - static const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT; - SPI.begin(); SET_OUTPUT(DIGIPOTSS_PIN); - LOOP_L_N(i, COUNT(digipot_motor_current)) { + LOOP_L_N(i, COUNT(motor_current_setting)) { //digitalPotWrite(digipot_ch[i], digipot_motor_current[i]); - digipot_current(i, digipot_motor_current[i]); + digipot_current(i, motor_current_setting[i]); } #elif HAS_MOTOR_CURRENT_PWM diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 3b68553689..51f7c489d7 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -249,8 +249,12 @@ class Stepper { #ifndef PWM_MOTOR_CURRENT #define PWM_MOTOR_CURRENT DEFAULT_PWM_MOTOR_CURRENT #endif - static uint32_t motor_current_setting[3]; static bool initialized; + static uint32_t motor_current_setting[3]; + #elif HAS_DIGIPOTSS + static bool initialized; + static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT; + static uint32_t motor_current_setting[COUNT(digipot_count)]; // Initialized by settings.load() #endif private: @@ -587,7 +591,7 @@ class Stepper { static int32_t _eval_bezier_curve(const uint32_t curr_step); #endif - #if HAS_DIGIPOTSS || HAS_MOTOR_CURRENT_PWM + #if HAS_MOTOR_CURRENT_PWM || HAS_DIGIPOTSS static void digipot_init(); #endif diff --git a/buildroot/share/PlatformIO/scripts/common-dependencies.py b/buildroot/share/PlatformIO/scripts/common-dependencies.py index 6c1b571bf1..def3bf40c2 100644 --- a/buildroot/share/PlatformIO/scripts/common-dependencies.py +++ b/buildroot/share/PlatformIO/scripts/common-dependencies.py @@ -9,10 +9,33 @@ try: import configparser except ImportError: import ConfigParser as configparser -from platformio.managers.package import PackageManager +try: + # PIO < 4.4 + from platformio.managers.package import PackageManager +except ImportError: + # PIO >= 4.4 + from platformio.package.meta import PackageSpec as PackageManager Import("env") +#print(env.Dump()) + +try: + verbose = int(env.GetProjectOption('custom_verbose')) +except: + verbose = 0 + +def blab(str): + if verbose: + print(str) + +def parse_pkg_uri(spec): + if PackageManager.__name__ == 'PackageSpec': + return PackageManager(spec).name + else: + name, _, _ = PackageManager.parse_pkg_uri(spec) + return name + FEATURE_CONFIG = {} def add_to_feat_cnf(feature, flines): @@ -56,7 +79,7 @@ def get_all_known_libs(): if not 'lib_deps' in feat: continue for dep in feat['lib_deps']: - name, _, _ = PackageManager.parse_pkg_uri(dep) + name = parse_pkg_uri(dep) known_libs.append(name) return known_libs @@ -64,7 +87,7 @@ def get_all_env_libs(): env_libs = [] lib_deps = env.GetProjectOption('lib_deps') for dep in lib_deps: - name, _, _ = PackageManager.parse_pkg_uri(dep) + name = parse_pkg_uri(dep) env_libs.append(name) return env_libs @@ -79,7 +102,8 @@ def force_ignore_unused_libs(): known_libs = get_all_known_libs() diff = (list(set(known_libs) - set(env_libs))) lib_ignore = env.GetProjectOption('lib_ignore') + diff - print("Ignore libraries:", lib_ignore) + if verbose: + print("Ignore libraries:", lib_ignore) set_env_field('lib_ignore', lib_ignore) def apply_features_config(): @@ -91,25 +115,25 @@ def apply_features_config(): feat = FEATURE_CONFIG[feature] if 'lib_deps' in feat and len(feat['lib_deps']): - print("Adding lib_deps for %s... " % feature) + blab("Adding lib_deps for %s... " % feature) # feat to add deps_to_add = {} for dep in feat['lib_deps']: - name, _, _ = PackageManager.parse_pkg_uri(dep) + name = parse_pkg_uri(dep) deps_to_add[name] = dep # Does the env already have the dependency? deps = env.GetProjectOption('lib_deps') for dep in deps: - name, _, _ = PackageManager.parse_pkg_uri(dep) + name = parse_pkg_uri(dep) if name in deps_to_add: del deps_to_add[name] # Are there any libraries that should be ignored? lib_ignore = env.GetProjectOption('lib_ignore') for dep in deps: - name, _, _ = PackageManager.parse_pkg_uri(dep) + name = parse_pkg_uri(dep) if name in deps_to_add: del deps_to_add[name] @@ -119,11 +143,11 @@ def apply_features_config(): set_env_field('lib_deps', deps + list(deps_to_add.values())) if 'extra_scripts' in feat: - print("Running extra_scripts for %s... " % feature) + blab("Running extra_scripts for %s... " % feature) env.SConscript(feat['extra_scripts'], exports="env") if 'src_filter' in feat: - print("Adding src_filter for %s... " % feature) + blab("Adding src_filter for %s... " % feature) src_filter = ' '.join(env.GetProjectOption('src_filter')) # first we need to remove the references to the same folder my_srcs = re.findall( r'[+-](<.*?>)', feat['src_filter']) @@ -137,7 +161,7 @@ def apply_features_config(): env.Replace(SRC_FILTER=src_filter) if 'lib_ignore' in feat: - print("Adding lib_ignore for %s... " % feature) + blab("Adding lib_ignore for %s... " % feature) lib_ignore = env.GetProjectOption('lib_ignore') + [feat['lib_ignore']] set_env_field('lib_ignore', lib_ignore) @@ -147,41 +171,49 @@ def apply_features_config(): ENV_BUILD_PATH = os.path.join(env.Dictionary('PROJECT_BUILD_DIR'), env['PIOENV']) GCC_PATH_CACHE = os.path.join(ENV_BUILD_PATH, ".gcc_path") def search_compiler(): + try: + filepath = env.GetProjectOption('custom_gcc') + blab('Getting compiler from env') + return filepath + except: + pass + if os.path.exists(GCC_PATH_CACHE): - print('Getting g++ path from cache') + blab('Getting g++ path from cache') with open(GCC_PATH_CACHE, 'r') as f: return f.read() - # PlatformIO inserts the toolchain bin folder on the front of the $PATH # Find the current platform compiler by searching the $PATH + # which will be in a platformio toolchain bin folder + path_regex = re.escape(env['PROJECT_PACKAGES_DIR']) + gcc = "g++" if env['PLATFORM'] == 'win32': path_separator = ';' - path_regex = re.escape(env['PROJECT_PACKAGES_DIR']) + r'.*\\bin' - gcc = "g++.exe" + path_regex += r'.*\\bin' + gcc += ".exe" else: path_separator = ':' - path_regex = re.escape(env['PROJECT_PACKAGES_DIR']) + r'.*/bin' - gcc = "g++" + path_regex += r'/.+/bin' # Search for the compiler - for path in env['ENV']['PATH'].split(path_separator): - if not re.search(path_regex, path, re.IGNORECASE): + for pathdir in env['ENV']['PATH'].split(path_separator): + if not re.search(path_regex, pathdir, re.IGNORECASE): continue - for file in os.listdir(path): - if not file.endswith(gcc): + for filepath in os.listdir(pathdir): + if not filepath.endswith(gcc): continue # Cache the g++ path to no search always if os.path.exists(ENV_BUILD_PATH): - print('Caching g++ for current env') + blab('Caching g++ for current env') with open(GCC_PATH_CACHE, 'w+') as f: - f.write(file) + f.write(filepath) - return file + return filepath - file = env.get('CXX') - print("Couldn't find a compiler! Fallback to", file) - return file + filepath = env.get('CXX') + blab("Couldn't find a compiler! Fallback to %s" % filepath) + return filepath # # Use the compiler to get a list of all enabled features @@ -191,7 +223,6 @@ def load_marlin_features(): return # Process defines - #print(env.Dump()) build_flags = env.get('BUILD_FLAGS') build_flags = env.ParseFlagsExtended(build_flags) @@ -209,7 +240,7 @@ def load_marlin_features(): cmd += ['-w -dM -E -x c++ buildroot/share/PlatformIO/scripts/common-dependencies.h'] cmd = ' '.join(cmd) - print(cmd) + blab(cmd) define_list = subprocess.check_output(cmd, shell=True).splitlines() marlin_features = {} for define in define_list: diff --git a/platformio.ini b/platformio.ini index 74e078586b..47a0925ea7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -295,6 +295,7 @@ EXT_SOLENOID|MANUAL_SOLENOID_CONTROL = src_filter=+ HAS_CUTTER = src_filter=+ + EXPERIMENTAL_I2CBUS = src_filter=+ + Z_STEPPER_AUTO_ALIGN = src_filter=+ + +MECHANICAL_GANTRY_CALIBRATION = src_filter=+ G26_MESH_VALIDATION = src_filter=+ ASSISTED_TRAMMING = src_filter=+ HAS_MESH = src_filter=+