@ -424,9 +424,9 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLLNPGM ( " Mesh invalidated. Probing mesh. \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( g29_verbose_level  >  1 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ ECHOPGM ( " Probing Mesh Points Closest to ( " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ ECHO( x_pos  ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ ECHO PAI R( " , " ,  y_pos ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ PROTOCOLPAIR ( " Probing Mesh Points Closest to ( " ,  x_pos ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ PROTOCOLCHAR( ' , '  ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ PROTOCOL ( y_pos ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLLNPGM ( " ) \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          probe_entire_mesh ( x_pos  +  X_PROBE_OFFSET_FROM_EXTRUDER ,  y_pos  +  Y_PROBE_OFFSET_FROM_EXTRUDER , 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -440,16 +440,16 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          SERIAL_PROTOCOLLNPGM ( " Manually probing unreachable mesh locations. \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          do_blocking_move_to_z ( Z_CLEARANCE_BETWEEN_PROBES ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( ! x_flag  & &  ! y_flag )  {       // use a good default location for the path
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            x_pos  =  X_MIN_POS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            y_pos  =  Y_MIN_POS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( X_PROBE_OFFSET_FROM_EXTRUDER  >  0 )    // The flipped > and < operators on these two comparisons is
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              x_pos  =  X_MAX_POS ;                     // intentional. It should cause the probed points to follow a
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( Y_PROBE_OFFSET_FROM_EXTRUDER  <  0 )    // nice path on Cartesian printers. It may make sense to
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              y_pos  =  Y_MAX_POS ;                     // have Delta printers default to the center of the bed.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          }                                          // For now, until that is decided, it can be forced with the X
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // The flipped > and < operators on these two comparisons is
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // intentional. It should cause the probed points to follow a
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // nice path on Cartesian printers. It may make sense to
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // have Delta printers default to the center of the bed.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // For now, until that is decided, it can be forced with the X
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            // and Y parameters.
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            x_pos  =  X_PROBE_OFFSET_FROM_EXTRUDER  >  0  ?  X_MAX_POS  :  X_MIN_POS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            y_pos  =  Y_PROBE_OFFSET_FROM_EXTRUDER  <  0  ?  Y_MAX_POS  :  Y_MIN_POS ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( code_seen ( ' C ' ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            x_pos  =  current_position [ X_AXIS ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            y_pos  =  current_position [ Y_AXIS ] ; 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -674,7 +674,7 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( ELAPSED ( millis ( ) ,  nxt ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_PROTOCOLLNPGM ( " \n Z-Offset Adjustment Stopped. " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            do_blocking_move_to_z ( Z_CLEARANCE_DEPLOY_PROBE ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            lcd_setstatuspgm ( " Z-Offset Stopped " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            lcd_setstatuspgm ( PSTR ( " Z-Offset Stopped " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            restore_ubl_active_state_and_leave ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            goto  LEAVE ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -693,7 +693,7 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # if ENABLED(ULTRA_LCD) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_reset_alert_level ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( " " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( PSTR ( " " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_quick_feedback ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -997,7 +997,7 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  bool  g29_parameter_parsing ( )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # if ENABLED(ULTRA_LCD) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( " Doing G29 UBL! " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( PSTR ( " Doing G29 UBL! " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_quick_feedback ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -1118,7 +1118,7 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    ubl_state_recursion_chk + + ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  ( ubl_state_recursion_chk  ! =  1 )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOLNPGM ( " save_ubl_active_state_and_disabled() called multiple times in a row. " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( " save_UBL_active() error " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( PSTR ( " save_UBL_active() error " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_quick_feedback ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      return ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    } 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -1129,7 +1129,7 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  void  restore_ubl_active_state_and_leave ( )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    if  ( - - ubl_state_recursion_chk )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOLNPGM ( " restore_ubl_active_state_and_leave() called too many times. " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( " restore_UBL_active() error " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( PSTR ( " restore_UBL_active() error " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_quick_feedback ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      return ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    } 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -1369,7 +1369,7 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    memset ( not_done ,  0xFF ,  sizeof ( not_done ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # if ENABLED(ULTRA_LCD) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( " Fine Tuning Mesh " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( PSTR ( " Fine Tuning Mesh " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    do_blocking_move_to_z ( Z_CLEARANCE_DEPLOY_PROBE ) ; 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -1428,7 +1428,7 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          lcd_return_to_status ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          //SERIAL_PROTOCOLLNPGM("\nFine Tuning of Mesh Stopped.");
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          do_blocking_move_to_z ( Z_CLEARANCE_DEPLOY_PROBE ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          lcd_setstatuspgm ( " Mesh Editing Stopped " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          lcd_setstatuspgm ( PSTR ( " Mesh Editing Stopped " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          while  ( ubl_lcd_clicked ( ) )  idle ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -1456,42 +1456,41 @@
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    do_blocking_move_to_xy ( lx ,  ly ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # if ENABLED(ULTRA_LCD) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( " Done Editing Mesh " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      lcd_setstatuspgm ( PSTR ( " Done Editing Mesh " ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    # endif 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    SERIAL_ECHOLNPGM ( " Done Editing Mesh " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					  void  tilt_mesh_based_on_probed_grid ( const  bool  do_ubl_mesh_map )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      int8_t  grid_G_index_to_xpos [ grid_size_G ] ;   //  UBL MESH X index to be probed
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      int8_t  grid_G_index_to_ypos [ grid_size_G ] ;    //  UBL MESH Y index to be probed
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      int8_t   i ,  j  , k ,  xCount ,  yCount ,  G_X_index ,  G_Y_index ;   // counter variables
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      int8_t  grid_G_index_to_xpos [ grid_size_G ] ,   //  UBL MESH X index to be probed
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             grid_G_index_to_ypos [ grid_size_G ] ,    //  UBL MESH Y index to be probed
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              i ,  j  , k ,  xCount ,  yCount ,  G_X_index ,  G_Y_index ;   // counter variables
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      float  z_values_G [ grid_size_G ] [ grid_size_G ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      struct   linear_fit * results ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       linear_fit * results ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      for  ( G_Y_index  =  0 ;  G_Y_index  <  grid_size_G ;  G_Y_index + + ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					       for  ( G_X_index  =  0 ;  G_X_index  <  grid_size_G ;  G_X_index + + ) 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        z_values_G [ G_X_index ] [ G_Y_index ]  =  NAN ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      uint8_t  x_min  =  GRID_MAX_POINTS_X  -  1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      uint8_t  x_max  =  0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      uint8_t  y_min  =  GRID_MAX_POINTS_Y  -  1 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      uint8_t   y_max  =  0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      uint8_t  x_min  =  GRID_MAX_POINTS_X  -  1 , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              x_max  =  0 ,  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					              y_min  =  GRID_MAX_POINTS_Y  -  1 ,  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					               y_max  =  0 ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      //find min & max probeable points in the mesh
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      for  ( xCount  =  0 ;  xCount  <  GRID_MAX_POINTS_X ;  xCount + + )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        for  ( yCount  =  0 ;  yCount  <  GRID_MAX_POINTS_Y ;  yCount + + )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( WITHIN ( ubl . mesh_index_to_xpos [ xCount ] ,  MIN_PROBE_X ,  MAX_PROBE_X )  & &  WITHIN ( ubl . mesh_index_to_ypos [ yCount ] ,  MIN_PROBE_Y ,  MAX_PROBE_Y ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( x_min  >  xCount )  x_min  =  xCount ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( x_max  <  xCount )  x_max  =  xCount ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( y_min  >  yCount )  y_min  =  yCount ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            if  ( y_max  <  yCount )  y_max  =  yCount ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            NOMORE ( x_min ,  xCount ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            NOLESS ( x_max ,  xCount ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            NOMORE ( y_min ,  yCount ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            NOLESS ( y_max ,  yCount ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      if  ( ( x_max  -  x_min  +  1 )   <  ( grid_size_G )   | |  ( y_max  -  y_min  +  1 )   <  ( grid_size_G ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      if  ( x_max  -  x_min  +  1  <  grid_size_G  | |  y_max  -  y_min  +  1  <  grid_size_G )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        SERIAL_ECHOPAIR ( " ERROR - probeable UBL MESH smaller than grid - X points:  " ,  x_max  -  x_min  +  1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        SERIAL_ECHOPAIR ( "   Y points:  " ,  y_max  -  y_min  +  1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        SERIAL_ECHOLNPAIR ( "   grid:  " ,  grid_size_G ) ; 
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				 
				
					@ -1557,40 +1556,39 @@ SERIAL_ECHOPAIR("\nPR_OUTER_VAR: ", PR_OUTER_VAR);
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        // Inner loop is Y with PROBE_Y_FIRST enabled
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        for  ( PR_INNER_VAR  =  inStart ;  PR_INNER_VAR  ! =  inStop ;  PR_INNER_VAR  + =  inInc )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n PR_INNER_VAR:  " ,  PR_INNER_VAR ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          //SERIAL_ECHOPAIR("\nPR_INNER_VAR: ", PR_INNER_VAR);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n Checkpoint:  " ,  1 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          //SERIAL_ECHOPAIR("\nCheckpoint: ", 1);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          // end of G29 AUTO_BED_LEVELING_BILINEAR method/code
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          if  ( ubl_lcd_clicked ( ) )  { 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n Checkpoint:  " ,  2 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            //SERIAL_ECHOPAIR("\nCheckpoint: ", 2);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            SERIAL_ECHOLNPGM ( " \n Grid only partially populated. \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            lcd_quick_feedback ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            STOW_PROBE ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n Checkpoint:  " ,  3 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            //SERIAL_ECHOPAIR("\nCheckpoint: ", 3);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            while  ( ubl_lcd_clicked ( ) )  idle ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n Checkpoint:  " ,  4 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            //SERIAL_ECHOPAIR("\nCheckpoint: ", 4);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            ubl . has_control_of_lcd_panel  =  false ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            restore_ubl_active_state_and_leave ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            safe_delay ( 50 ) ;   // Debounce the Encoder wheel
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					            return ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n Checkpoint:  " ,  5 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          //SERIAL_ECHOPAIR("\nCheckpoint: ", 5);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  probeX  =  ubl . mesh_index_to_xpos [ grid_G_index_to_xpos [ xCount ] ] ,   //where we want the probe to be
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          probeY  =  ubl . mesh_index_to_ypos [ grid_G_index_to_ypos [ yCount ] ] ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n Checkpoint:  " ,  6 ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          //SERIAL_ECHOPAIR("\nCheckpoint: ", 6);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          const  float  measured_z  =  probe_pt ( LOGICAL_X_POSITION ( probeX ) ,  LOGICAL_Y_POSITION ( probeY ) ,  code_seen ( ' E ' ) ,  ( code_seen ( ' V ' )  & &  code_has_value ( ) )  ?  code_value_int ( )  :  0 ) ;   // takes into account the offsets
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHOPAIR ( " \n measured_z:  " ,  measured_z  ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          //SERIAL_ECHOPAIR("\nmeasured_z: ", measured_z);
  
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					          z_values_G [ xCount ] [ yCount ]  =  measured_z ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					//SERIAL_ LNPGM("\nFine Tuning of Mesh Stopped.");
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					           //SERIAL_ ECHO LNPGM("\nFine Tuning of Mesh Stopped.");
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					        } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      } 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHO ( " \n Done probing... \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      //SERIAL_ECHOLNPGM("\nDone probing...\n");
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      STOW_PROBE ( ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      restore_ubl_active_state_and_leave ( ) ; 
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				 
				
					@ -1599,40 +1597,34 @@ SERIAL_ECHO("\nDone probing...\n");
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      //do_blocking_move_to_xy(ubl.mesh_index_to_xpos[grid_G_index_to_xpos[0]], ubl.mesh_index_to_ypos[grid_G_index_to_ypos[0]]);
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      // least squares code
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  xxx9 [ ]  =  {  0 , 50 , 100 , 150 , 200 ,            20 , 70 , 120 , 165 , 195 ,          0 , 50 , 100 , 150 , 200 ,            0 , 55 , 100 , 150 , 200 ,            0 , 65 , 100 , 150 , 205  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  yyy9 [ ]  =  {  0 ,  1 ,   2 ,   3 ,  4 ,             50 ,  51 ,   52 ,   53 ,  54 ,      100 ,  101 , 102 , 103 , 104 ,         150 , 151 , 152 , 153 , 154 ,         200 , 201 , 202 , 203 , 204  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  zzz9 [ ]  =  {  0.01 , .002 , - .01 , - .02 , 0 ,       0.01 , .002 , - .01 , - .02 , 0 ,      0.01 , .002 , - .01 , - .02 , 0 ,       0.01 , .002 , - .01 , - .02 , 0 ,       0.01 , .002 , - .01 , - .012 , 0.01 } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					int  nine_size  =  sizeof ( xxx9 )  /  sizeof ( double ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  xxx0 [ ]  =  {  0.0 ,  0.0 ,  1.0  } ; 	// Expect [0,0,0.1,0]
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  yyy0 [ ]  =  {  0.0 ,  1.0 ,  0.0  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  zzz0 [ ]  =  {  0.1 ,  0.1 ,  0.1  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					int  zero_size  =  sizeof ( xxx0 )  /  sizeof ( double ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  xxx [ ]  =  {  0.0 ,  0.0 ,  1.0 ,  1.0  } ; 	// Expect [0.1,0,0.05,0]
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  yyy [ ]  =  {  0.0 ,  1.0 ,  0.0 ,  1.0  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					double  zzz [ ]  =  {  0.05 ,  0.05 ,  0.15 ,  0.15  } ;       
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					int  three_size  =  sizeof ( xxx )  /  sizeof ( double ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      results  =  lsf_linear_fit ( xxx9 ,  yyy9 ,  zzz9 ,  nine_size ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      double  xxx9 [ ]  =  {  0 , 50 , 100 , 150 , 200 ,            20 , 70 , 120 , 165 , 195 ,          0 , 50 , 100 , 150 , 200 ,            0 , 55 , 100 , 150 , 200 ,            0 , 65 , 100 , 150 , 205  } , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             yyy9 [ ]  =  {  0 ,  1 ,   2 ,   3 ,  4 ,             50 ,  51 ,   52 ,   53 ,  54 ,      100 ,  101 , 102 , 103 , 104 ,         150 , 151 , 152 , 153 , 154 ,         200 , 201 , 202 , 203 , 204  } , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             zzz9 [ ]  =  {  0.01 , .002 , - .01 , - .02 , 0 ,       0.01 , .002 , - .01 , - .02 , 0 ,      0.01 , .002 , - .01 , - .02 , 0 ,       0.01 , .002 , - .01 , - .02 , 0 ,       0.01 , .002 , - .01 , - .012 , 0.01 } , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             xxx0 [ ]  =  {  0.0 ,  0.0 ,  1.0  } ,   // Expect [0,0,0.1,0]
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             yyy0 [ ]  =  {  0.0 ,  1.0 ,  0.0  } , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             zzz0 [ ]  =  {  0.1 ,  0.1 ,  0.1  } , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             xxx [ ]  =  {  0.0 ,  0.0 ,  1.0 ,  1.0  } ,   // Expect [0.1,0,0.05,0]
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             yyy [ ]  =  {  0.0 ,  1.0 ,  0.0 ,  1.0  } , 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					             zzz [ ]  =  {  0.05 ,  0.05 ,  0.15 ,  0.15  } ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      results  =  lsf_linear_fit ( xxx9 ,  yyy9 ,  zzz9 ,  COUNT ( xxx9 ) ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx9->A = " ,  results - > A ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx9->B = " ,  results - > B ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx9->D = " ,  results - > D ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHO ( " \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_EOL ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      results  =  lsf_linear_fit ( xxx0 ,  yyy0 ,  zzz0 ,  zero_size ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      results  =  lsf_linear_fit ( xxx0 ,  yyy0 ,  zzz0 ,  COUNT( xxx0 )  ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx0->A = " ,  results - > A ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx0->B = " ,  results - > B ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx0->D = " ,  results - > D ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHO ( " \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_EOL  ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      results  =  lsf_linear_fit ( xxx ,  yyy ,  zzz ,  three_size ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      results  =  lsf_linear_fit ( xxx ,  yyy ,  zzz ,  COUNT( xxx )  ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx->A = " ,  results - > A ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx->B = " ,  results - > B ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_ECHOPAIR ( " \n xxx->D = " ,  results - > D ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					SERIAL_ECHO ( " \n " ) ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      SERIAL_EOL  ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					      return ; 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					    }   // end of tilt_mesh_based_on_probed_grid()
 
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				 
				
					# endif  // AUTO_BED_LEVELING_UBL