🏗️ Support for up to 6 linear axes (#19112)
Co-authored-by: Scott Lahteine <github@thinkyhead.com>
This commit is contained in:
		
				
					committed by
					
						
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							d3c56a76e7
						
					
				
				
					commit
					c1fca91103
				
			@@ -323,42 +323,44 @@ void GcodeSuite::G28() {
 | 
			
		||||
 | 
			
		||||
    #define _UNSAFE(A) (homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(A##_AXIS))))
 | 
			
		||||
 | 
			
		||||
    const bool homeZ = parser.seen_test('Z'),
 | 
			
		||||
               LINEAR_AXIS_LIST( // Other axes should be homed before Z safe-homing
 | 
			
		||||
                 needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false // UNUSED
 | 
			
		||||
    const bool homeZ = TERN0(HAS_Z_AXIS, parser.seen_test('Z')),
 | 
			
		||||
               LINEAR_AXIS_LIST(              // Other axes should be homed before Z safe-homing
 | 
			
		||||
                 needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false, // UNUSED
 | 
			
		||||
                 needI = _UNSAFE(I), needJ = _UNSAFE(J), needK = _UNSAFE(K)
 | 
			
		||||
               ),
 | 
			
		||||
               LINEAR_AXIS_LIST( // Home each axis if needed or flagged
 | 
			
		||||
               LINEAR_AXIS_LIST(              // Home each axis if needed or flagged
 | 
			
		||||
                 homeX = needX || parser.seen_test('X'),
 | 
			
		||||
                 homeY = needY || parser.seen_test('Y'),
 | 
			
		||||
                 homeZZ = homeZ // UNUSED
 | 
			
		||||
                 homeZZ = homeZ,
 | 
			
		||||
                 homeI = needI || parser.seen_test(AXIS4_NAME), homeJ = needJ || parser.seen_test(AXIS5_NAME), homeK = needK || parser.seen_test(AXIS6_NAME),
 | 
			
		||||
               ),
 | 
			
		||||
               // Home-all if all or none are flagged
 | 
			
		||||
               home_all = true LINEAR_AXIS_GANG(&& homeX == homeX, && homeX == homeY, && homeX == homeZ),
 | 
			
		||||
               LINEAR_AXIS_LIST(doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ);
 | 
			
		||||
 | 
			
		||||
   UNUSED(needZ);
 | 
			
		||||
   UNUSED(homeZZ);
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(HOME_Z_FIRST)
 | 
			
		||||
 | 
			
		||||
      if (doZ) homeaxis(Z_AXIS);
 | 
			
		||||
               home_all = LINEAR_AXIS_GANG(   // Home-all if all or none are flagged
 | 
			
		||||
                    homeX == homeX, && homeY == homeX, && homeZ == homeX,
 | 
			
		||||
                 && homeI == homeX, && homeJ == homeX, && homeK == homeX
 | 
			
		||||
               ),
 | 
			
		||||
               LINEAR_AXIS_LIST(
 | 
			
		||||
                 doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ,
 | 
			
		||||
                 doI = home_all || homeI, doJ = home_all || homeJ, doK = home_all || homeK
 | 
			
		||||
               );
 | 
			
		||||
 | 
			
		||||
    #if HAS_Z_AXIS
 | 
			
		||||
      UNUSED(needZ); UNUSED(homeZZ);
 | 
			
		||||
    #else
 | 
			
		||||
      constexpr bool doZ = false;
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    TERN_(HOME_Z_FIRST, if (doZ) homeaxis(Z_AXIS));
 | 
			
		||||
 | 
			
		||||
    const float z_homing_height = parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT;
 | 
			
		||||
 | 
			
		||||
    if (z_homing_height && (0 LINEAR_AXIS_GANG(|| doX, || doY, || TERN0(Z_SAFE_HOMING, doZ)))) {
 | 
			
		||||
    if (z_homing_height && (0 LINEAR_AXIS_GANG(|| doX, || doY, || TERN0(Z_SAFE_HOMING, doZ), || doI, || doJ, || doK))) {
 | 
			
		||||
      // Raise Z before homing any other axes and z is not already high enough (never lower z)
 | 
			
		||||
      if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) by ", z_homing_height);
 | 
			
		||||
      do_z_clearance(z_homing_height);
 | 
			
		||||
      TERN_(BLTOUCH, bltouch.init());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #if ENABLED(QUICK_HOME)
 | 
			
		||||
 | 
			
		||||
      if (doX && doY) quick_home_xy();
 | 
			
		||||
 | 
			
		||||
    #endif
 | 
			
		||||
    TERN_(QUICK_HOME, if (doX && doY) quick_home_xy());
 | 
			
		||||
 | 
			
		||||
    // Home Y (before X)
 | 
			
		||||
    if (ENABLED(HOME_Y_BEFORE_X) && (doY || TERN0(CODEPENDENT_XY_HOMING, doX)))
 | 
			
		||||
@@ -397,7 +399,7 @@ void GcodeSuite::G28() {
 | 
			
		||||
    TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(slow_homing));
 | 
			
		||||
 | 
			
		||||
    // Home Z last if homing towards the bed
 | 
			
		||||
    #if DISABLED(HOME_Z_FIRST)
 | 
			
		||||
    #if HAS_Z_AXIS && DISABLED(HOME_Z_FIRST)
 | 
			
		||||
      if (doZ) {
 | 
			
		||||
        #if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
 | 
			
		||||
          stepper.set_all_z_lock(false);
 | 
			
		||||
@@ -409,6 +411,16 @@ void GcodeSuite::G28() {
 | 
			
		||||
      }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    #if LINEAR_AXES >= 4
 | 
			
		||||
      if (doI) homeaxis(I_AXIS);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 5
 | 
			
		||||
      if (doJ) homeaxis(J_AXIS);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 6
 | 
			
		||||
      if (doK) homeaxis(K_AXIS);
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    sync_plan_position();
 | 
			
		||||
 | 
			
		||||
  #endif
 | 
			
		||||
@@ -480,6 +492,15 @@ void GcodeSuite::G28() {
 | 
			
		||||
    #if HAS_CURRENT_HOME(Y2)
 | 
			
		||||
      stepperY2.rms_current(tmc_save_current_Y2);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_CURRENT_HOME(I)
 | 
			
		||||
      stepperI.rms_current(tmc_save_current_I);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_CURRENT_HOME(J)
 | 
			
		||||
      stepperJ.rms_current(tmc_save_current_J);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_CURRENT_HOME(K)
 | 
			
		||||
      stepperK.rms_current(tmc_save_current_K);
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif // HAS_HOMING_CURRENT
 | 
			
		||||
 | 
			
		||||
  ui.refresh();
 | 
			
		||||
@@ -498,11 +519,13 @@ void GcodeSuite::G28() {
 | 
			
		||||
    // Set L6470 absolute position registers to counts
 | 
			
		||||
    // constexpr *might* move this to PROGMEM.
 | 
			
		||||
    // If not, this will need a PROGMEM directive and an accessor.
 | 
			
		||||
    #define _EN_ITEM(N) , E_AXIS
 | 
			
		||||
    static constexpr AxisEnum L64XX_axis_xref[MAX_L64XX] = {
 | 
			
		||||
      X_AXIS, Y_AXIS, Z_AXIS,
 | 
			
		||||
      X_AXIS, Y_AXIS, Z_AXIS, Z_AXIS,
 | 
			
		||||
      E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS
 | 
			
		||||
      LINEAR_AXIS_LIST(X_AXIS, Y_AXIS, Z_AXIS, I_AXIS, J_AXIS, K_AXIS),
 | 
			
		||||
      X_AXIS, Y_AXIS, Z_AXIS, Z_AXIS, Z_AXIS
 | 
			
		||||
      REPEAT(E_STEPPERS, _EN_ITEM)
 | 
			
		||||
    };
 | 
			
		||||
    #undef _EN_ITEM
 | 
			
		||||
    for (uint8_t j = 1; j <= L64XX::chain[0]; j++) {
 | 
			
		||||
      const uint8_t cv = L64XX::chain[j];
 | 
			
		||||
      L64xxManager.set_param((L64XX_axis_t)cv, L6470_ABS_POS, stepper.position(L64XX_axis_xref[cv]));
 | 
			
		||||
 
 | 
			
		||||
@@ -73,11 +73,23 @@
 | 
			
		||||
#if BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
 | 
			
		||||
  #define HAS_X_CENTER 1
 | 
			
		||||
#endif
 | 
			
		||||
#if BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
 | 
			
		||||
#if HAS_Y_AXIS && BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
 | 
			
		||||
  #define HAS_Y_CENTER 1
 | 
			
		||||
#endif
 | 
			
		||||
#if LINEAR_AXES >= 4 && BOTH(CALIBRATION_MEASURE_IMIN, CALIBRATION_MEASURE_IMAX)
 | 
			
		||||
  #define HAS_I_CENTER 1
 | 
			
		||||
#endif
 | 
			
		||||
#if LINEAR_AXES >= 5 && BOTH(CALIBRATION_MEASURE_JMIN, CALIBRATION_MEASURE_JMAX)
 | 
			
		||||
  #define HAS_J_CENTER 1
 | 
			
		||||
#endif
 | 
			
		||||
#if LINEAR_AXES >= 6 && BOTH(CALIBRATION_MEASURE_KMIN, CALIBRATION_MEASURE_KMAX)
 | 
			
		||||
  #define HAS_K_CENTER 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES };
 | 
			
		||||
enum side_t : uint8_t {
 | 
			
		||||
  TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES,
 | 
			
		||||
  LIST_N(DOUBLE(SUB3(LINEAR_AXES)), IMINIMUM, IMAXIMUM, JMINIMUM, JMAXIMUM, KMINIMUM, KMAXIMUM)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static constexpr xyz_pos_t true_center CALIBRATION_OBJECT_CENTER;
 | 
			
		||||
static constexpr xyz_float_t dimensions CALIBRATION_OBJECT_DIMENSIONS;
 | 
			
		||||
@@ -105,7 +117,7 @@ struct measurements_t {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline void calibration_move() {
 | 
			
		||||
  do_blocking_move_to(current_position, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL));
 | 
			
		||||
  do_blocking_move_to((xyz_pos_t)current_position, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -174,7 +186,7 @@ float measuring_movement(const AxisEnum axis, const int dir, const bool stop_sta
 | 
			
		||||
  destination = current_position;
 | 
			
		||||
  for (float travel = 0; travel < limit; travel += step) {
 | 
			
		||||
    destination[axis] += dir * step;
 | 
			
		||||
    do_blocking_move_to(destination, mms);
 | 
			
		||||
    do_blocking_move_to((xyz_pos_t)destination, mms);
 | 
			
		||||
    planner.synchronize();
 | 
			
		||||
    if (read_calibration_pin() == stop_state) break;
 | 
			
		||||
  }
 | 
			
		||||
@@ -209,7 +221,7 @@ inline float measure(const AxisEnum axis, const int dir, const bool stop_state,
 | 
			
		||||
  // Move back to the starting position
 | 
			
		||||
  destination = current_position;
 | 
			
		||||
  destination[axis] = start_pos;
 | 
			
		||||
  do_blocking_move_to(destination, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL));
 | 
			
		||||
  do_blocking_move_to((xyz_pos_t)destination, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL));
 | 
			
		||||
  return measured_pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -230,7 +242,15 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
 | 
			
		||||
  park_above_object(m, uncertainty);
 | 
			
		||||
 | 
			
		||||
  switch (side) {
 | 
			
		||||
    #if AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
    #if AXIS_CAN_CALIBRATE(X)
 | 
			
		||||
      case RIGHT: dir = -1;
 | 
			
		||||
      case LEFT:  axis = X_AXIS; break;
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 2 && AXIS_CAN_CALIBRATE(Y)
 | 
			
		||||
      case BACK:  dir = -1;
 | 
			
		||||
      case FRONT: axis = Y_AXIS; break;
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
      case TOP: {
 | 
			
		||||
        const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
 | 
			
		||||
        m.obj_center.z = measurement - dimensions.z / 2;
 | 
			
		||||
@@ -238,13 +258,17 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    #endif
 | 
			
		||||
    #if AXIS_CAN_CALIBRATE(X)
 | 
			
		||||
      case RIGHT: dir = -1;
 | 
			
		||||
      case LEFT:  axis = X_AXIS; break;
 | 
			
		||||
    #if LINEAR_AXES >= 4 && AXIS_CAN_CALIBRATE(I)
 | 
			
		||||
      case IMINIMUM: dir = -1;
 | 
			
		||||
      case IMAXIMUM: axis = I_AXIS; break;
 | 
			
		||||
    #endif
 | 
			
		||||
    #if AXIS_CAN_CALIBRATE(Y)
 | 
			
		||||
      case BACK:  dir = -1;
 | 
			
		||||
      case FRONT: axis = Y_AXIS; break;
 | 
			
		||||
    #if LINEAR_AXES >= 5 && AXIS_CAN_CALIBRATE(J)
 | 
			
		||||
      case JMINIMUM: dir = -1;
 | 
			
		||||
      case JMAXIMUM: axis = J_AXIS; break;
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 6 && AXIS_CAN_CALIBRATE(K)
 | 
			
		||||
      case KMINIMUM: dir = -1;
 | 
			
		||||
      case KMAXIMUM: axis = K_AXIS; break;
 | 
			
		||||
    #endif
 | 
			
		||||
    default: return;
 | 
			
		||||
  }
 | 
			
		||||
@@ -289,14 +313,23 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
 | 
			
		||||
    probe_side(m, uncertainty, TOP);
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_RIGHT, probe_side(m, uncertainty, RIGHT, probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_FRONT, probe_side(m, uncertainty, FRONT, probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_LEFT,  probe_side(m, uncertainty, LEFT,  probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_BACK,  probe_side(m, uncertainty, BACK,  probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_RIGHT, probe_side(m, uncertainty, RIGHT,    probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_FRONT, probe_side(m, uncertainty, FRONT,    probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_LEFT,  probe_side(m, uncertainty, LEFT,     probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_BACK,  probe_side(m, uncertainty, BACK,     probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_IMIN,  probe_side(m, uncertainty, IMINIMUM, probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_IMAX,  probe_side(m, uncertainty, IMAXIMUM, probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_JMIN,  probe_side(m, uncertainty, JMINIMUM, probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_JMAX,  probe_side(m, uncertainty, JMAXIMUM, probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_KMIN,  probe_side(m, uncertainty, KMINIMUM, probe_top_at_edge));
 | 
			
		||||
  TERN_(CALIBRATION_MEASURE_KMAX,  probe_side(m, uncertainty, KMAXIMUM, probe_top_at_edge));
 | 
			
		||||
 | 
			
		||||
  // Compute the measured center of the calibration object.
 | 
			
		||||
  TERN_(HAS_X_CENTER, m.obj_center.x = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2);
 | 
			
		||||
  TERN_(HAS_Y_CENTER, m.obj_center.y = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2);
 | 
			
		||||
  TERN_(HAS_X_CENTER, m.obj_center.x = (m.obj_side[LEFT]     + m.obj_side[RIGHT])    / 2);
 | 
			
		||||
  TERN_(HAS_Y_CENTER, m.obj_center.y = (m.obj_side[FRONT]    + m.obj_side[BACK])     / 2);
 | 
			
		||||
  TERN_(HAS_I_CENTER, m.obj_center.i = (m.obj_side[IMINIMUM] + m.obj_side[IMAXIMUM]) / 2);
 | 
			
		||||
  TERN_(HAS_J_CENTER, m.obj_center.j = (m.obj_side[JMINIMUM] + m.obj_side[JMAXIMUM]) / 2);
 | 
			
		||||
  TERN_(HAS_K_CENTER, m.obj_center.k = (m.obj_side[KMINIMUM] + m.obj_side[KMAXIMUM]) / 2);
 | 
			
		||||
 | 
			
		||||
  // Compute the outside diameter of the nozzle at the height
 | 
			
		||||
  // at which it makes contact with the calibration object
 | 
			
		||||
@@ -310,14 +343,17 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
 | 
			
		||||
  LINEAR_AXIS_CODE(
 | 
			
		||||
    m.pos_error.x = TERN0(HAS_X_CENTER, true_center.x - m.obj_center.x),
 | 
			
		||||
    m.pos_error.y = TERN0(HAS_Y_CENTER, true_center.y - m.obj_center.y),
 | 
			
		||||
    m.pos_error.z = true_center.z - m.obj_center.z
 | 
			
		||||
    m.pos_error.z = true_center.z - m.obj_center.z,
 | 
			
		||||
    m.pos_error.i = TERN0(HAS_I_CENTER, true_center.i - m.obj_center.i),
 | 
			
		||||
    m.pos_error.j = TERN0(HAS_J_CENTER, true_center.j - m.obj_center.j),
 | 
			
		||||
    m.pos_error.k = TERN0(HAS_K_CENTER, true_center.k - m.obj_center.k)
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLED(CALIBRATION_REPORTING)
 | 
			
		||||
  inline void report_measured_faces(const measurements_t &m) {
 | 
			
		||||
    SERIAL_ECHOLNPGM("Sides:");
 | 
			
		||||
    #if AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
    #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
      SERIAL_ECHOLNPAIR("  Top: ", m.obj_side[TOP]);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if ENABLED(CALIBRATION_MEASURE_LEFT)
 | 
			
		||||
@@ -326,11 +362,37 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
 | 
			
		||||
    #if ENABLED(CALIBRATION_MEASURE_RIGHT)
 | 
			
		||||
      SERIAL_ECHOLNPAIR("  Right: ", m.obj_side[RIGHT]);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if ENABLED(CALIBRATION_MEASURE_FRONT)
 | 
			
		||||
      SERIAL_ECHOLNPAIR("  Front: ", m.obj_side[FRONT]);
 | 
			
		||||
    #if HAS_Y_AXIS
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_FRONT)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  Front: ", m.obj_side[FRONT]);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_BACK)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  Back: ", m.obj_side[BACK]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if ENABLED(CALIBRATION_MEASURE_BACK)
 | 
			
		||||
      SERIAL_ECHOLNPAIR("  Back: ", m.obj_side[BACK]);
 | 
			
		||||
    #if LINEAR_AXES >= 4
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_IMIN)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_I_MIN ": ", m.obj_side[IMINIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_IMAX)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_I_MAX ": ", m.obj_side[IMAXIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 5
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_JMIN)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_J_MIN ": ", m.obj_side[JMINIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_JMAX)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_J_MAX ": ", m.obj_side[JMAXIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 6
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_KMIN)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_K_MIN ": ", m.obj_side[KMINIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_KMAX)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_K_MAX ": ", m.obj_side[KMAXIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    SERIAL_EOL();
 | 
			
		||||
  }
 | 
			
		||||
@@ -344,6 +406,15 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.obj_center.y);
 | 
			
		||||
    #endif
 | 
			
		||||
    SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.obj_center.z);
 | 
			
		||||
    #if HAS_I_CENTER
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_I_STR, m.obj_center.i);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_J_CENTER
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_J_STR, m.obj_center.j);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_K_CENTER
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_K_STR, m.obj_center.k);
 | 
			
		||||
    #endif
 | 
			
		||||
    SERIAL_EOL();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -357,7 +428,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  Right: ", m.backlash[RIGHT]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if AXIS_CAN_CALIBRATE(Y)
 | 
			
		||||
    #if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y)
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_FRONT)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  Front: ", m.backlash[FRONT]);
 | 
			
		||||
      #endif
 | 
			
		||||
@@ -365,9 +436,33 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  Back: ", m.backlash[BACK]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
    #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
      SERIAL_ECHOLNPAIR("  Top: ", m.backlash[TOP]);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 4 AXIS_CAN_CALIBRATE(I)
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_IMIN)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_I_MIN ": ", m.backlash[IMINIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_IMAX)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_I_MAX ": ", m.backlash[IMAXIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 5 AXIS_CAN_CALIBRATE(J)
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_JMIN)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_J_MIN ": ", m.backlash[JMINIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_JMAX)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_J_MAX ": ", m.backlash[JMAXIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    #if LINEAR_AXES >= 6 AXIS_CAN_CALIBRATE(K)
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_KMIN)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_K_MIN ": ", m.backlash[KMINIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if ENABLED(CALIBRATION_MEASURE_KMAX)
 | 
			
		||||
        SERIAL_ECHOLNPAIR("  " STR_K_MAX ": ", m.backlash[KMAXIMUM]);
 | 
			
		||||
      #endif
 | 
			
		||||
    #endif
 | 
			
		||||
    SERIAL_EOL();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -375,29 +470,37 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
 | 
			
		||||
    SERIAL_CHAR('T');
 | 
			
		||||
    SERIAL_ECHO(active_extruder);
 | 
			
		||||
    SERIAL_ECHOLNPGM(" Positional Error:");
 | 
			
		||||
    #if HAS_X_CENTER
 | 
			
		||||
    #if HAS_X_CENTER && AXIS_CAN_CALIBRATE(X)
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_X_STR, m.pos_error.x);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_Y_CENTER
 | 
			
		||||
    #if HAS_Y_CENTER && AXIS_CAN_CALIBRATE(Y)
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.pos_error.y);
 | 
			
		||||
    #endif
 | 
			
		||||
    if (AXIS_CAN_CALIBRATE(Z)) SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
 | 
			
		||||
    #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_I_CENTER && AXIS_CAN_CALIBRATE(I)
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_I_STR, m.pos_error.i);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_J_CENTER && AXIS_CAN_CALIBRATE(J)
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_J_STR, m.pos_error.j);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_K_CENTER && AXIS_CAN_CALIBRATE(K)
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_Z_STR, m.pos_error.z);
 | 
			
		||||
    #endif
 | 
			
		||||
    SERIAL_EOL();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void report_measured_nozzle_dimensions(const measurements_t &m) {
 | 
			
		||||
    SERIAL_ECHOLNPGM("Nozzle Tip Outer Dimensions:");
 | 
			
		||||
    #if HAS_X_CENTER || HAS_Y_CENTER
 | 
			
		||||
      #if HAS_X_CENTER
 | 
			
		||||
        SERIAL_ECHOLNPAIR_P(SP_X_STR, m.nozzle_outer_dimension.x);
 | 
			
		||||
      #endif
 | 
			
		||||
      #if HAS_Y_CENTER
 | 
			
		||||
        SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.nozzle_outer_dimension.y);
 | 
			
		||||
      #endif
 | 
			
		||||
    #else
 | 
			
		||||
      UNUSED(m);
 | 
			
		||||
    #if HAS_X_CENTER
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_X_STR, m.nozzle_outer_dimension.x);
 | 
			
		||||
    #endif
 | 
			
		||||
    #if HAS_Y_CENTER
 | 
			
		||||
      SERIAL_ECHOLNPAIR_P(SP_Y_STR, m.nozzle_outer_dimension.y);
 | 
			
		||||
    #endif
 | 
			
		||||
    SERIAL_EOL();
 | 
			
		||||
    UNUSED(m);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #if HAS_HOTEND_OFFSET
 | 
			
		||||
@@ -446,8 +549,33 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
 | 
			
		||||
        backlash.distance_mm.y = m.backlash[BACK];
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP];
 | 
			
		||||
    #endif
 | 
			
		||||
      TERN_(HAS_Z_AXIS, if (AXIS_CAN_CALIBRATE(Z)) backlash.distance_mm.z = m.backlash[TOP]);
 | 
			
		||||
 | 
			
		||||
      #if HAS_I_CENTER
 | 
			
		||||
        backlash.distance_mm.i = (m.backlash[IMINIMUM] + m.backlash[IMAXIMUM]) / 2;
 | 
			
		||||
      #elif ENABLED(CALIBRATION_MEASURE_IMIN)
 | 
			
		||||
        backlash.distance_mm.i = m.backlash[IMINIMUM];
 | 
			
		||||
      #elif ENABLED(CALIBRATION_MEASURE_IMAX)
 | 
			
		||||
        backlash.distance_mm.i = m.backlash[IMAXIMUM];
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      #if HAS_J_CENTER
 | 
			
		||||
        backlash.distance_mm.j = (m.backlash[JMINIMUM] + m.backlash[JMAXIMUM]) / 2;
 | 
			
		||||
      #elif ENABLED(CALIBRATION_MEASURE_JMIN)
 | 
			
		||||
        backlash.distance_mm.j = m.backlash[JMINIMUM];
 | 
			
		||||
      #elif ENABLED(CALIBRATION_MEASURE_JMAX)
 | 
			
		||||
        backlash.distance_mm.j = m.backlash[JMAXIMUM];
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
      #if HAS_K_CENTER
 | 
			
		||||
        backlash.distance_mm.k = (m.backlash[KMINIMUM] + m.backlash[KMAXIMUM]) / 2;
 | 
			
		||||
      #elif ENABLED(CALIBRATION_MEASURE_KMIN)
 | 
			
		||||
        backlash.distance_mm.k = m.backlash[KMINIMUM];
 | 
			
		||||
      #elif ENABLED(CALIBRATION_MEASURE_KMAX)
 | 
			
		||||
        backlash.distance_mm.k = m.backlash[KMAXIMUM];
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
    #endif // BACKLASH_GCODE
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #if ENABLED(BACKLASH_GCODE)
 | 
			
		||||
@@ -458,7 +586,8 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
 | 
			
		||||
      TEMPORARY_BACKLASH_CORRECTION(all_on);
 | 
			
		||||
      TEMPORARY_BACKLASH_SMOOTHING(0.0f);
 | 
			
		||||
      const xyz_float_t move = LINEAR_AXIS_ARRAY(
 | 
			
		||||
        AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3
 | 
			
		||||
        AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3,
 | 
			
		||||
        AXIS_CAN_CALIBRATE(I) * 3, AXIS_CAN_CALIBRATE(J) * 3, AXIS_CAN_CALIBRATE(K) * 3
 | 
			
		||||
      );
 | 
			
		||||
      current_position += move; calibration_move();
 | 
			
		||||
      current_position -= move; calibration_move();
 | 
			
		||||
@@ -487,11 +616,7 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
 | 
			
		||||
  TEMPORARY_BACKLASH_CORRECTION(all_on);
 | 
			
		||||
  TEMPORARY_BACKLASH_SMOOTHING(0.0f);
 | 
			
		||||
 | 
			
		||||
  #if HAS_MULTI_HOTEND
 | 
			
		||||
    set_nozzle(m, extruder);
 | 
			
		||||
  #else
 | 
			
		||||
    UNUSED(extruder);
 | 
			
		||||
  #endif
 | 
			
		||||
  TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder));
 | 
			
		||||
 | 
			
		||||
  probe_sides(m, uncertainty);
 | 
			
		||||
 | 
			
		||||
@@ -510,6 +635,10 @@ inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const
 | 
			
		||||
  if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) update_measurements(m, Y_AXIS);
 | 
			
		||||
                           if (AXIS_CAN_CALIBRATE(Z)) update_measurements(m, Z_AXIS);
 | 
			
		||||
 | 
			
		||||
  TERN_(HAS_I_CENTER, update_measurements(m, I_AXIS));
 | 
			
		||||
  TERN_(HAS_J_CENTER, update_measurements(m, J_AXIS));
 | 
			
		||||
  TERN_(HAS_K_CENTER, update_measurements(m, K_AXIS));
 | 
			
		||||
 | 
			
		||||
  sync_plan_position();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,10 @@ void GcodeSuite::M425() {
 | 
			
		||||
      LINEAR_AXIS_CODE(
 | 
			
		||||
        case X_AXIS: return AXIS_CAN_CALIBRATE(X),
 | 
			
		||||
        case Y_AXIS: return AXIS_CAN_CALIBRATE(Y),
 | 
			
		||||
        case Z_AXIS: return AXIS_CAN_CALIBRATE(Z)
 | 
			
		||||
        case Z_AXIS: return AXIS_CAN_CALIBRATE(Z),
 | 
			
		||||
        case I_AXIS: return AXIS_CAN_CALIBRATE(I),
 | 
			
		||||
        case J_AXIS: return AXIS_CAN_CALIBRATE(J),
 | 
			
		||||
        case K_AXIS: return AXIS_CAN_CALIBRATE(K),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user