| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -52,9 +52,9 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "../../core/debug_out.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#if NUM_Z_STEPPER_DRIVERS >= 3
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#if NUM_Z_STEPPERS >= 3
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  #define TRIPLE_Z 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  #if NUM_Z_STEPPER_DRIVERS >= 4
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  #if NUM_Z_STEPPERS >= 4
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    #define QUAD_Z 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  #endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -180,11 +180,11 @@ void GcodeSuite::G34() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      // This hack is un-done at the end of G34 - either by re-homing, or by using the probed heights of the last iteration.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      #if !HAS_Z_STEPPER_ALIGN_STEPPER_XY
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        float last_z_align_move[NUM_Z_STEPPER_DRIVERS] = ARRAY_N_1(NUM_Z_STEPPER_DRIVERS, 10000.0f);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        float last_z_align_move[NUM_Z_STEPPERS] = ARRAY_N_1(NUM_Z_STEPPERS, 10000.0f);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      #else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        float last_z_align_level_indicator = 10000.0f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      #endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      float z_measured[NUM_Z_STEPPER_DRIVERS] = { 0 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      float z_measured[NUM_Z_STEPPERS] = { 0 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            z_maxdiff = 0.0f,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            amplification = z_auto_align_amplification;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -217,9 +217,9 @@ void GcodeSuite::G34() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        float z_measured_max = -100000.0f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Probe all positions (one per Z-Stepper)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        LOOP_L_N(i, NUM_Z_STEPPERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          // iteration odd/even --> downward / upward stepper sequence
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPER_DRIVERS - 1 - i : i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPERS - 1 - i : i;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          // Safe clearance even on an incline
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          if ((iteration == 0 || i > 0) && z_probe > current_position.z) do_blocking_move_to_z(z_probe);
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -270,20 +270,20 @@ void GcodeSuite::G34() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          // This allows the actual adjustment logic to be shared by both algorithms.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          linear_fit_data lfd;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          incremental_LSF_reset(&lfd);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(i, NUM_Z_STEPPERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            SERIAL_ECHOLNPGM("PROBEPT_", i, ": ", z_measured[i]);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          finish_incremental_LSF(&lfd);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          z_measured_min = 100000.0f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(i, NUM_Z_STEPPERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y + lfd.D);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            z_measured_min = _MIN(z_measured_min, z_measured[i]);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          SERIAL_ECHOLNPGM(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            LIST_N(DOUBLE(NUM_Z_STEPPER_DRIVERS),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            LIST_N(DOUBLE(NUM_Z_STEPPERS),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              "Calculated Z1=", z_measured[0],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        " Z2=", z_measured[1],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        " Z3=", z_measured[2],
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -307,7 +307,7 @@ void GcodeSuite::G34() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        #if HAS_STATUS_MESSAGE
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          char fstr1[10];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          char msg[6 + (6 + 5) * NUM_Z_STEPPER_DRIVERS + 1]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          char msg[6 + (6 + 5) * NUM_Z_STEPPERS + 1]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            #if TRIPLE_Z
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              , fstr2[10], fstr3[10]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				              #if QUAD_Z
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -345,12 +345,12 @@ void GcodeSuite::G34() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          // Calculate mean value as a reference
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          float z_measured_mean = 0.0f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS) z_measured_mean += z_measured[zstepper];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          z_measured_mean /= NUM_Z_STEPPER_DRIVERS;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(zstepper, NUM_Z_STEPPERS) z_measured_mean += z_measured[zstepper];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          z_measured_mean /= NUM_Z_STEPPERS;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          // Calculate the sum of the absolute deviations from the mean value
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          float z_align_level_indicator = 0.0f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          LOOP_L_N(zstepper, NUM_Z_STEPPERS)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            z_align_level_indicator += ABS(z_measured[zstepper] - z_measured_mean);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          // If it's getting worse, stop and throw an error
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -365,7 +365,7 @@ void GcodeSuite::G34() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        bool success_break = true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Correct the individual stepper offsets
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        LOOP_L_N(zstepper, NUM_Z_STEPPER_DRIVERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        LOOP_L_N(zstepper, NUM_Z_STEPPERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          // Calculate current stepper move
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          float z_align_move = z_measured[zstepper] - z_measured_min;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				          const float z_align_abs = ABS(z_align_move);
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -515,9 +515,9 @@ void GcodeSuite::M422() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    #endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!WITHIN(position_index, 1, NUM_Z_STEPPER_DRIVERS)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!WITHIN(position_index, 1, NUM_Z_STEPPERS)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SERIAL_ECHOF(err_string);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SERIAL_ECHOLNPGM(" index invalid (1.." STRINGIFY(NUM_Z_STEPPER_DRIVERS) ").");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SERIAL_ECHOLNPGM(" index invalid (1.." STRINGIFY(NUM_Z_STEPPERS) ").");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -544,7 +544,7 @@ void GcodeSuite::M422() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GcodeSuite::M422_report(const bool forReplay/*=true*/) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  report_heading(forReplay, F(STR_Z_AUTO_ALIGN));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  LOOP_L_N(i, NUM_Z_STEPPERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    report_echo_start(forReplay);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SERIAL_ECHOLNPGM_P(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      PSTR("  M422 S"), i + 1,
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -553,7 +553,7 @@ void GcodeSuite::M422_report(const bool forReplay/*=true*/) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  #if HAS_Z_STEPPER_ALIGN_STEPPER_XY
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    LOOP_L_N(i, NUM_Z_STEPPERS) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      report_echo_start(forReplay);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      SERIAL_ECHOLNPGM_P(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        PSTR("  M422 W"), i + 1,
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |