@ -1200,22 +1200,24 @@ static void retract_z_probe() {
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					} 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					enum  ProbeAction  {  ProbeEngageRetract ,  ProbeEngage ,  ProbeStay ,  ProbeRetract  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					/// Probe bed height at position (x,y), returns the measured z value
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					static  float  probe_pt ( float  x ,  float  y ,  float  z_before ,  int  retract_action = 0 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					static  float  probe_pt ( float  x ,  float  y ,  float  z_before ,  ProbeAction  retract_action = ProbeEngageRetract )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  // move to right place
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  do_blocking_move_to ( current_position [ X_AXIS ] ,  current_position [ Y_AXIS ] ,  z_before ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  do_blocking_move_to ( x  -  X_PROBE_OFFSET_FROM_EXTRUDER ,  y  -  Y_PROBE_OFFSET_FROM_EXTRUDER ,  current_position [ Z_AXIS ] ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifndef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					   if  ( ( retract_action = = 0 )  | |  ( retract_action = = 1 ) )  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					     engage_z_probe ( ) ;    // Engage Z Servo endstop if available
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  // Z_PROBE_SLED  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					   # ifndef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  ( retract_action  = =  ProbeEngageRetract  | |  retract_action  = =  ProbeEngage )  engage_z_probe ( ) ;  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  run_z_probe ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  float  measured_z  =  current_position [ Z_AXIS ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifndef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  if  ( ( retract_action = = 0 )  | |  ( retract_action = = 3 ) )  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					     retract_z_probe ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  // Z_PROBE_SLED
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  # ifndef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  ( retract_action  = =  ProbeEngageRetract  | |  retract_action  = =  ProbeRetract )   retract_z_probe ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					   # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  SERIAL_PROTOCOLPGM ( MSG_BED ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  SERIAL_PROTOCOLPGM ( "  x:  " ) ; 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -1376,6 +1378,11 @@ void refresh_cmd_timeout(void)
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  //FWRETRACT
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifdef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  # ifndef SLED_DOCKING_OFFSET 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # define SLED_DOCKING_OFFSET 0 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					//
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					// Method to dock/undock a sled designed by Charles Bell.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					//
 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -1719,25 +1726,96 @@ void process_commands()
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      break ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifdef ENABLE_AUTO_BED_LEVELING 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # if Z_MIN_PIN == -1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling!!! Z_MIN_PIN must point to a valid hardware pin." 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					   /**
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *  Enhanced  G29  Auto  Bed  Leveling  Probe  Routine 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *  Parameters  With  AUTO_BED_LEVELING_GRID : 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *   P   Set  the  size  of  the  grid  that  will  be  probed  ( P  x  P  points ) . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *      Example :  " G29 P4 " 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *   V   Set  the  verbose  level  ( 0 - 4 ) .  Example :  " G29 V3 " 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *   T   Generate  a  Bed  Topology  Report .  Example :  " G29 P5 T "  for  a  detailed  report . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *      This  is  useful  for  manual  bed  leveling  and  finding  flaws  in  the  bed  ( to 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *      assist  with  part  placement ) . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *   F   Set  the  Front  limit  of  the  probing  grid 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *   B   Set  the  Back  limit  of  the  probing  grid 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *   L   Set  the  Left  limit  of  the  probing  grid 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *   R   Set  the  Right  limit  of  the  probing  grid 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *  Global  Parameters : 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *  E / e  By  default  G29  engages  /  disengages  the  probe  for  each  point . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *      Include  " E "  to  engage  and  disengage  the  probe  just  once . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *      There ' s  no  extra  effect  if  you  have  a  fixed  probe . 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    *      Usage :  " G29 E "  or  " G29 e " 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    * 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    */ 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    case  29 :  // G29 Detailed Z-Probe, probes the bed at 3 or more points.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    	     // Override probing area by providing [F]ront [B]ack [L]eft [R]ight Grid[P]oints values
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            # if Z_MIN_PIN == -1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            # error "You must have a Z_MIN endstop in order to enable Auto Bed Leveling feature!!! Z_MIN_PIN must point to a valid hardware pin." 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // Use one of these defines to specify the origin
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // for a topographical map to be printed for your bed.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # define ORIGIN_BACK_LEFT   1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # define ORIGIN_FRONT_RIGHT 2 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # define ORIGIN_BACK_RIGHT  3 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # define ORIGIN_FRONT_LEFT  4 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # define TOPO_ORIGIN        ORIGIN_FRONT_LEFT 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // Prevent user from running a G29 without first homing in X and Y
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( !  ( axis_known_position [ X_AXIS ]  & &  axis_known_position [ Y_AXIS ] )  ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      if  ( ! ( axis_known_position [ X_AXIS ]  & &  axis_known_position [ Y_AXIS ] ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        LCD_MESSAGEPGM ( MSG_POSITION_UNKNOWN ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        SERIAL_ECHO_START ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        SERIAL_ECHOLNPGM ( MSG_POSITION_UNKNOWN ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        break ;  // abort G29, since we don't know where we are
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifdef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            dock_sled ( false ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  // Z_PROBE_SLED
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      bool  enhanced_g29  =  code_seen ( ' E ' )  | |  code_seen ( ' e ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # ifdef AUTO_BED_LEVELING_GRID 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // Example Syntax:  G29 N4 V2 E T
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  verbose_level  =  1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        bool  topo_flag  =  code_seen ( ' T ' )  | |  code_seen ( ' t ' ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( code_seen ( ' V ' )  | |  code_seen ( ' v ' ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          verbose_level  =  code_value ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( verbose_level  <  0  | |  verbose_level  >  4 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLPGM ( " ?Verbose Level not plausible (0-4). \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            break ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( verbose_level  >  0 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLPGM ( " Enhanced G29 Auto_Bed_Leveling Code V1.25: \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLPGM ( " Full support at http://3dprintboard.com \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( verbose_level  >  2 )  topo_flag  =  true ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  auto_bed_leveling_grid_points  =  code_seen ( ' P ' )  ?  code_value_long ( )  :  AUTO_BED_LEVELING_GRID_POINTS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( auto_bed_leveling_grid_points  <  2  | |  auto_bed_leveling_grid_points  >  AUTO_BED_LEVELING_GRID_POINTS )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOLPGM ( " ?Number of probed points not plausible (2 minimum). \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          break ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  left_probe_bed_position  =  code_seen ( ' L ' )  ?  code_value_long ( )  :  LEFT_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  right_probe_bed_position  =  code_seen ( ' R ' )  ?  code_value_long ( )  :  RIGHT_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  back_probe_bed_position  =  code_seen ( ' B ' )  ?  code_value_long ( )  :  BACK_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  front_probe_bed_position  =  code_seen ( ' F ' )  ?  code_value_long ( )  :  FRONT_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # ifdef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        dock_sled ( false ) ;  // engage (un-dock) the probe
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      st_synchronize ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      //vector_3 corrected_position = plan_get_position_mm();
 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -1752,22 +1830,12 @@ void process_commands()
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      setup_for_endstop_move ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      feedrate  =  homing_feedrate [ Z_AXIS ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifdef AUTO_BED_LEVELING_GRID 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // probe at the points of a lattice grid
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            int  left_probe_bed_position = LEFT_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            int  right_probe_bed_position = RIGHT_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            int  back_probe_bed_position = BACK_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            int  front_probe_bed_position = FRONT_PROBE_BED_POSITION ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            int  auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( code_seen ( ' L ' ) )  left_probe_bed_position = ( int ) code_value ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( code_seen ( ' R ' ) )  right_probe_bed_position = ( int ) code_value ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( code_seen ( ' B ' ) )  back_probe_bed_position = ( int ) code_value ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( code_seen ( ' F ' ) )  front_probe_bed_position = ( int ) code_value ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( code_seen ( ' P ' ) )  auto_bed_leveling_grid_points = ( int ) code_value ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            int  xGridSpacing  =  ( right_probe_bed_position  -  left_probe_bed_position )  /  ( auto_bed_leveling_grid_points - 1 ) ;  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            int  yGridSpacing  =  ( back_probe_bed_position  -  front_probe_bed_position )  /  ( auto_bed_leveling_grid_points - 1 ) ;  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # ifdef AUTO_BED_LEVELING_GRID 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // probe at the points of a lattice grid
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  xGridSpacing  =  ( right_probe_bed_position  -  left_probe_bed_position )  /  ( auto_bed_leveling_grid_points  -  1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  yGridSpacing  =  ( back_probe_bed_position  -  front_probe_bed_position )  /  ( auto_bed_leveling_grid_points  -  1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // solve the plane equation ax + by + d = z
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // A is the matrix with rows [x y 1] for all the probed points
 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -1775,125 +1843,155 @@ void process_commands()
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // the normal vector to the plane is formed by the coefficients of the plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // "A" matrix of the linear system of equations
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            double  eqnAMatrix [ auto_bed_leveling_grid_points * auto_bed_leveling_grid_points * 3 ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // "B" vector of Z points
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            double  eqnBVector [ auto_bed_leveling_grid_points * auto_bed_leveling_grid_points ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  abl2  =  auto_bed_leveling_grid_points  *  auto_bed_leveling_grid_points ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        double  eqnAMatrix [ abl2  *  3 ] ,  // "A" matrix of the linear system of equations
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					               eqnBVector [ abl2 ] ,      // "B" vector of Z points
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					               mean  =  0.0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        int  probePointCounter  =  0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        bool  zig  =  true ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            for  ( int  yProbe = front_probe_bed_position ;  yProbe  < =  back_probe_bed_position ;  yProbe  + =  yGridSpacing ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        for  ( int  yProbe  =  front_probe_bed_position ;  yProbe  < =  back_probe_bed_position ;  yProbe  + =  yGridSpacing )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          int  xProbe ,  xInc ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( zig ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                xProbe  =  left_probe_bed_position ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                //xEnd = right_probe_bed_position;
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                xInc  =  xGridSpacing ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                zig  =  false ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              }  else  // zag
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                xProbe  =  right_probe_bed_position ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                //xEnd = left_probe_bed_position;
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                xInc  =  - xGridSpacing ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                zig  =  true ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            xProbe  =  left_probe_bed_position ,  xInc  =  xGridSpacing ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            xProbe  =  right_probe_bed_position ,  xInc  =  - xGridSpacing ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              for  ( int  xCount = 0 ;  xCount  <  auto_bed_leveling_grid_points ;  xCount + + ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                float  z_before ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                if  ( probePointCounter  = =  0 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  // raise before probing
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  z_before  =  Z_RAISE_BEFORE_PROBING ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                }  else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          // If topo_flag is set then don't zig-zag. Just scan in one direction.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          // This gets the probe points in more readable order.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( ! topo_flag )  zig  =  ! zig ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          for  ( int  xCount  =  0 ;  xCount  <  auto_bed_leveling_grid_points ;  xCount + + )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // raise extruder
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  z_before  =  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            float  z_before  =  probePointCounter  = =  0  ?  Z_RAISE_BEFORE_PROBING  :  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  measured_z ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // Enhanced G29 - Do not retract servo between probes
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            ProbeAction  act ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( enhanced_g29 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              if  ( yProbe  = =  front_probe_bed_position  & &  xCount  = =  0 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                act  =  ProbeEngage ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              else  if  ( yProbe  = =  front_probe_bed_position  +  ( yGridSpacing  *  ( auto_bed_leveling_grid_points  -  1 ) )  & &  xCount  = =  auto_bed_leveling_grid_points  -  1 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                act  =  ProbeRetract ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                act  =  ProbeStay ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              act  =  ProbeEngageRetract ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                float  measured_z ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                //Enhanced G29 - Do not retract servo between probes
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                if  ( code_seen ( ' E ' )  | |  code_seen ( ' e ' )  ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                   { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                   if  ( ( yProbe = = FRONT_PROBE_BED_POSITION )  & &  ( xCount = = 0 ) ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                       { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                        measured_z  =  probe_pt ( xProbe ,  yProbe ,  z_before , 1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                       }  else  if  ( ( yProbe = = FRONT_PROBE_BED_POSITION  +  ( yGridSpacing  *  ( AUTO_BED_LEVELING_GRID_POINTS - 1 ) ) )  & &  ( xCount  = =  AUTO_BED_LEVELING_GRID_POINTS - 1 ) ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                         { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                         measured_z  =  probe_pt ( xProbe ,  yProbe ,  z_before , 3 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                         }  else  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                           measured_z  =  probe_pt ( xProbe ,  yProbe ,  z_before , 2 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                         } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    }  else  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    measured_z  =  probe_pt ( xProbe ,  yProbe ,  z_before ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            measured_z  =  probe_pt ( xProbe ,  yProbe ,  z_before ,  act ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            mean  + =  measured_z ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            eqnBVector [ probePointCounter ]  =  measured_z ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            eqnAMatrix [ probePointCounter  +  0  *  abl2 ]  =  xProbe ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            eqnAMatrix [ probePointCounter  +  1  *  abl2 ]  =  yProbe ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            eqnAMatrix [ probePointCounter  +  2  *  abl2 ]  =  1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                eqnAMatrix [ probePointCounter  +  0 * auto_bed_leveling_grid_points * auto_bed_leveling_grid_points ]  =  xProbe ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                eqnAMatrix [ probePointCounter  +  1 * auto_bed_leveling_grid_points * auto_bed_leveling_grid_points ]  =  yProbe ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                eqnAMatrix [ probePointCounter  +  2 * auto_bed_leveling_grid_points * auto_bed_leveling_grid_points ]  =  1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            probePointCounter + + ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            xProbe  + =  xInc ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          }  //xProbe
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        }  //yProbe
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        clean_up_after_endstop_move ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // solve lsq problem
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             double  * plane_equation_coefficients  =  qr_solve ( a uto_bed_leveling_grid_points* auto_bed_leveling_grid_points  ,  3 ,  eqnAMatrix ,  eqnBVector ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        double  * plane_equation_coefficients  =  qr_solve ( a bl2 ,  3 ,  eqnAMatrix ,  eqnBVector ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        mean  / =  abl2 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( verbose_level )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOLPGM ( " Eqn coefficients: a:  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOL ( plane_equation_coefficients [ 0 ] ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOLPGM ( "  b:  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOL ( plane_equation_coefficients [ 1 ] ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOLPGM ( "  d:  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOLLN ( plane_equation_coefficients [ 2 ] ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( verbose_level  >  2 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLPGM ( " Mean of sampled points:  " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOL_F ( mean ,  6 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLPGM ( "   \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( topo_flag )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            set_bed_level_equation_lsq ( plane_equation_coefficients ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          int  xx ,  yy ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOLPGM ( "   \n Bed Height Topography:  \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # if TOPO_ORIGIN == ORIGIN_FRONT_LEFT 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            for  ( yy  =  auto_bed_leveling_grid_points  -  1 ;  yy  > =  0 ;  yy - - ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            for  ( yy  =  0 ;  yy  <  auto_bed_leveling_grid_points ;  yy + + ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              # if TOPO_ORIGIN == ORIGIN_BACK_RIGHT 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                for  ( xx  =  auto_bed_leveling_grid_points  -  1 ;  xx  > =  0 ;  xx - - ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              # else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                for  ( xx  =  0 ;  xx  <  auto_bed_leveling_grid_points ;  xx + + ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  int  ind  = 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    # if TOPO_ORIGIN == ORIGIN_BACK_RIGHT || TOPO_ORIGIN == ORIGIN_FRONT_LEFT 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      yy  *  auto_bed_leveling_grid_points  +  xx 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    # elif TOPO_ORIGIN == ORIGIN_BACK_LEFT 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      xx  *  auto_bed_leveling_grid_points  +  yy 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    # elif TOPO_ORIGIN == ORIGIN_FRONT_RIGHT 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                      abl2  -  xx  *  auto_bed_leveling_grid_points  -  yy  -  1 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  float  diff  =  eqnBVector [ ind ]  -  mean ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  if  ( diff  > =  0.0 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    SERIAL_PROTOCOLPGM ( "  + " ) ;    // Watch column alignment in Pronterface
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  else 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                    SERIAL_PROTOCOLPGM ( "  - " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                  SERIAL_PROTOCOL_F ( diff ,  5 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                }  // xx
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					                SERIAL_PROTOCOLPGM ( " \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            }  // yy
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLPGM ( " \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        }  //topo_flag
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        set_bed_level_equation_lsq ( plane_equation_coefficients ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        free ( plane_equation_coefficients ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# else  // AUTO_BED_LEVELING_GRID not defined
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       # else  //  ! AUTO_BED_LEVELING_GRID
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // Probe at 3 arbitrary points
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // Enhanced G29
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        float  z_at_pt_1 ,  z_at_pt_2 ,  z_at_pt_3 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( code_seen ( ' E ' )  | |  code_seen ( ' e ' ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              // probe 1               
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              z_at_pt_1  =  probe_pt ( ABL_PROBE_PT_1_X ,  ABL_PROBE_PT_1_Y ,  Z_RAISE_BEFORE_PROBING , 1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              // probe 2
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              z_at_pt_2  =  probe_pt ( ABL_PROBE_PT_2_X ,  ABL_PROBE_PT_2_Y ,  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS , 2 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              // probe 3
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              z_at_pt_3  =  probe_pt ( ABL_PROBE_PT_3_X ,  ABL_PROBE_PT_3_Y ,  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS , 3 ) ;  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        if  ( enhanced_g29 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          // Basic Enhanced G29
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z_at_pt_1  =  probe_pt ( ABL_PROBE_PT_1_X ,  ABL_PROBE_PT_1_Y ,  Z_RAISE_BEFORE_PROBING ,  ProbeEngage ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z_at_pt_2  =  probe_pt ( ABL_PROBE_PT_2_X ,  ABL_PROBE_PT_2_Y ,  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS ,  ProbeStay ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z_at_pt_3  =  probe_pt ( ABL_PROBE_PT_3_X ,  ABL_PROBE_PT_3_Y ,  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS ,  ProbeRetract ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        else  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              // probe 1
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z_at_pt_1  =  probe_pt ( ABL_PROBE_PT_1_X ,  ABL_PROBE_PT_1_Y ,  Z_RAISE_BEFORE_PROBING ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              // probe 2
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z_at_pt_2  =  probe_pt ( ABL_PROBE_PT_2_X ,  ABL_PROBE_PT_2_Y ,  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              // probe 3
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z_at_pt_3  =  probe_pt ( ABL_PROBE_PT_3_X ,  ABL_PROBE_PT_3_Y ,  current_position [ Z_AXIS ]  +  Z_RAISE_BETWEEN_PROBINGS ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        clean_up_after_endstop_move ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        set_bed_level_equation_3pts ( z_at_pt_1 ,  z_at_pt_2 ,  z_at_pt_3 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # endif  // !AUTO_BED_LEVELING_GRID
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  // AUTO_BED_LEVELING_GRID
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      st_synchronize ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      if  ( verbose_level  >  0 ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        plan_bed_level_matrix . debug ( "   \n \n Bed Level Correction Matrix: " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // The following code correct the Z height difference from z-probe position and hotend tip position.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // When the bed is uneven, this height must be corrected.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            real_z  =  float ( st_get_position ( Z_AXIS ) ) / axis_steps_per_unit [ Z_AXIS ] ;   //get the real Z (since the auto bed leveling is already correcting the plane)
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      real_z  =  float ( st_get_position ( Z_AXIS ) )   /   axis_steps_per_unit [ Z_AXIS ] ;   //get the real Z (since the auto bed leveling is already correcting the plane)
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      x_tmp  =  current_position [ X_AXIS ]  +  X_PROBE_OFFSET_FROM_EXTRUDER ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      y_tmp  =  current_position [ Y_AXIS ]  +  Y_PROBE_OFFSET_FROM_EXTRUDER ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      z_tmp  =  current_position [ Z_AXIS ] ; 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -1901,11 +1999,13 @@ void process_commands()
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      apply_rotation_xyz ( plan_bed_level_matrix ,  x_tmp ,  y_tmp ,  z_tmp ) ;          //Apply the correction sending the probe offset
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      current_position [ Z_AXIS ]  =  z_tmp  -  real_z  +  current_position [ Z_AXIS ] ;    //The difference is added to current position and sent to planner.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      plan_set_position ( current_position [ X_AXIS ] ,  current_position [ Y_AXIS ] ,  current_position [ Z_AXIS ] ,  current_position [ E_AXIS ] ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifdef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            dock_sled ( true ,  - SLED_DOCKING_OFFSET ) ;  // correct for over travel.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  // Z_PROBE_SLED
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # ifdef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        dock_sled ( true ,  - SLED_DOCKING_OFFSET ) ;  // dock the probe, correcting for over-travel
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    break ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# ifndef Z_PROBE_SLED 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    case  30 :  // G30 Single Z Probe
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        {