@ -102,8 +102,6 @@
* specified height , no correction is applied and natural printer kenimatics take over . If no
* number is specified for the command , 10 mm is assumed to be reasonable .
*
* G # Grid * Perform a Grid Based Leveling of the current Mesh using a grid with n points on a side .
*
* H # Height Specify the Height to raise the nozzle after each manual probe of the bed . The
* default is 5 mm .
*
@ -117,6 +115,10 @@
* the bed and use this feature to select the center of the area ( or cell ) you want to
* invalidate .
*
* J # Grid * Perform a Grid Based Leveling of the current Mesh using a grid with n points on a side .
*
* j EEPROM Dump This function probably goes away after debug is complete .
*
* K # Kompare Kompare current Mesh with stored Mesh # replacing current Mesh with the result . This
* command literally performs a diff between two Meshes .
*
@ -303,7 +305,7 @@
// The simple parameter flags and values are 'static' so parameter parsing can be in a support routine.
static int g29_verbose_level , phase_value = - 1 , repetition_cnt ,
storage_slot = 0 , map_type , grid_size _G ; //unlevel_value = -1;
storage_slot = 0 , map_type , grid_size ;
static bool repeat_flag , c_flag , x_flag , y_flag ;
static float x_pos , y_pos , measured_z , card_thickness = 0.0 , ubl_constant = 0.0 ;
@ -378,24 +380,9 @@
}
}
/*
if ( code_seen ( ' U ' ) ) {
unlevel_value = code_value_int ( ) ;
//if (!WITHIN(unlevel_value, 0, 7)) {
// SERIAL_PROTOCOLLNPGM("Invalid Unlevel value. (0-4)\n");
// return;
//}
}
*/
if ( code_seen ( ' G ' ) ) {
uint8_t grid_size_G = code_has_value ( ) ? code_value_int ( ) : 3 ;
if ( grid_size_G < 2 ) {
SERIAL_PROTOCOLLNPGM ( " ERROR - grid size must be 2 or more " ) ;
return ;
}
if ( grid_size_G > GRID_MAX_POINTS_X | | grid_size_G > GRID_MAX_POINTS_Y ) {
SERIAL_PROTOCOLLNPGM ( " ERROR - grid size can NOT exceed GRID_MAX_POINTS_X nor GRID_MAX_POINTS_Y " ) ;
if ( code_seen ( ' J ' ) ) {
if ( grid_size < 2 | | grid_size > 5 ) {
SERIAL_PROTOCOLLNPGM ( " ERROR - grid size must be between 2 and 5 " ) ;
return ;
}
tilt_mesh_based_on_probed_grid ( code_seen ( ' O ' ) | | code_seen ( ' M ' ) ) ;
@ -567,7 +554,7 @@
// When we are fully debugged, the EEPROM dump command will get deleted also. But
// right now, it is good to have the extra information. Soon... we prune this.
//
if ( code_seen ( ' J ' ) ) g29_eeprom_dump ( ) ; // EEPROM Dump
if ( code_seen ( ' j ' ) ) g29_eeprom_dump ( ) ; // EEPROM Dump
//
// When we are fully debugged, this may go away. But there are some valid
@ -692,11 +679,9 @@
LEAVE :
# if ENABLED(ULTRA_LCD)
lcd_reset_alert_level ( ) ;
LCD_MESSAGEPGM ( " " ) ;
lcd_quick_feedback ( ) ;
# endif
ubl . has_control_of_lcd_panel = false ;
}
@ -997,18 +982,26 @@
}
bool g29_parameter_parsing ( ) {
# if ENABLED(ULTRA_LCD)
bool err_flag = false ;
LCD_MESSAGEPGM ( " Doing G29 UBL! " ) ;
lcd_quick_feedback ( ) ;
# endif
x_flag = code_seen ( ' X ' ) & & code_has_value ( ) ;
y_flag = code_seen ( ' Y ' ) & & code_has_value ( ) ;
x_pos = x_flag ? code_value_float ( ) : current_position [ X_AXIS ] ;
y_flag = code_seen ( ' Y ' ) & & code_has_value ( ) ;
y_pos = y_flag ? code_value_float ( ) : current_position [ Y_AXIS ] ;
repeat_flag = code_seen ( ' R ' ) ? code_value_bool ( ) : false ;
bool err_flag = false ;
repetition_cnt = 0 ;
repeat_flag = code_seen ( ' R ' ) ;
if ( repeat_flag ) {
repetition_cnt = code_has_value ( ) ? code_value_int ( ) : GRID_MAX_POINTS_X * GRID_MAX_POINTS_Y ;
if ( repetition_cnt < 1 ) {
SERIAL_PROTOCOLLNPGM ( " Invalid Repetition count. \n " ) ;
return UBL_ERR ;
}
}
g29_verbose_level = code_seen ( ' V ' ) ? code_value_int ( ) : 0 ;
if ( ! WITHIN ( g29_verbose_level , 0 , 4 ) ) {
@ -1017,8 +1010,8 @@
}
if ( code_seen ( ' G ' ) ) {
grid_size _G = code_has_value ( ) ? code_value_int ( ) : 3 ;
if ( ! WITHIN ( grid_size _G, 2 , 10 ) ) {
grid_size = code_has_value ( ) ? code_value_int ( ) : 3 ;
if ( ! WITHIN ( grid_size , 2 , 5 ) ) {
SERIAL_PROTOCOLLNPGM ( " Invalid grid probe points specified. \n " ) ;
err_flag = true ;
}
@ -1032,11 +1025,27 @@
if ( ! WITHIN ( RAW_X_POSITION ( x_pos ) , X_MIN_POS , X_MAX_POS ) ) {
SERIAL_PROTOCOLLNPGM ( " Invalid X location specified. \n " ) ;
err_flag = true ;
SERIAL_PROTOCOLPAIR ( " \n x_flag = " , x_flag ) ; // These print blocks are only useful because sometimes the
SERIAL_PROTOCOLPAIR ( " \n x_pos = " , x_pos ) ; // data corruption causes x_pos and y_pos to be crazy. This gets deleted soon.
SERIAL_PROTOCOLPAIR ( " \n current[] = " , current_position [ X_AXIS ] ) ;
SERIAL_PROTOCOLPAIR ( " \n X_MIN_POS = " , X_MIN_POS ) ;
SERIAL_PROTOCOLPAIR ( " \n X_MAX_POS = " , X_MAX_POS ) ;
SERIAL_PROTOCOLPAIR ( " \n RAW_X_POSITION() = " , RAW_X_POSITION ( x_pos ) ) ;
SERIAL_PROTOCOLPAIR ( " \n within() = " , WITHIN ( RAW_X_POSITION ( x_pos ) , X_MIN_POS , X_MAX_POS ) ) ;
SERIAL_PROTOCOL ( " \n " ) ;
}
if ( ! WITHIN ( RAW_Y_POSITION ( y_pos ) , Y_MIN_POS , Y_MAX_POS ) ) {
SERIAL_PROTOCOLLNPGM ( " Invalid Y location specified. \n " ) ;
err_flag = true ;
SERIAL_PROTOCOLPAIR ( " \n y_flag = " , y_flag ) ; // These print blocks are only useful because sometimes the
SERIAL_PROTOCOLPAIR ( " \n y_pos = " , y_pos ) ; // data corruption causes x_pos and y_pos to be crazy. This gets deleted soon.
SERIAL_PROTOCOLPAIR ( " \n current[] = " , current_position [ Y_AXIS ] ) ;
SERIAL_PROTOCOLPAIR ( " \n Y_MIN_POS = " , Y_MIN_POS ) ;
SERIAL_PROTOCOLPAIR ( " \n Y_MAX_POS = " , Y_MAX_POS ) ;
SERIAL_PROTOCOLPAIR ( " \n RAW_Y_POSITION() = " , RAW_Y_POSITION ( y_pos ) ) ;
SERIAL_PROTOCOLPAIR ( " \n within() = " , WITHIN ( RAW_Y_POSITION ( y_pos ) , Y_MIN_POS , Y_MAX_POS ) ) ;
SERIAL_PROTOCOL ( " \n " ) ;
}
if ( err_flag ) return UBL_ERR ;
@ -1068,11 +1077,6 @@
}
# endif
repetition_cnt = repeat_flag ? ( code_has_value ( ) ? code_value_int ( ) : 9999 ) : 1 ;
if ( repetition_cnt < 1 ) {
SERIAL_PROTOCOLLNPGM ( " Invalid Repetition count. \n " ) ;
return UBL_ERR ;
}
map_type = code_seen ( ' O ' ) & & code_has_value ( ) ? code_value_int ( ) : 0 ;
if ( ! WITHIN ( map_type , 0 , 1 ) ) {
@ -1365,9 +1369,8 @@
}
void fine_tune_mesh ( const float & lx , const float & ly , const bool do_ubl_mesh_map ) {
// do all mesh points unless R option has a value of 1 or more
repetition_cnt = code_seen ( ' R ' ) & & code_has_value ( ) ? code_value_byte ( ) : GRID_MAX_POINTS_X * GRID_MAX_POINTS_Y ;
if ( repetition_cnt = = 0 ) repetition_cnt = GRID_MAX_POINTS_X * GRID_MAX_POINTS_Y ;
if ( ! code_seen ( ' R ' ) ) // fine_tune_mesh() is special. If no repetion count flag is specified
repetition_cnt = 1 ; // we know to do exactly one mesh location. Otherwise we use what the parser decided.
mesh_index_pair location ;
uint16_t not_done [ 16 ] ;
@ -1448,7 +1451,7 @@
lcd_implementation_clear ( ) ;
} while ( location . x_index > = 0 & & location . y_index > = 0 & & - - repetition_cnt ) ;
} while ( location . x_index > = 0 & & location . y_index > = 0 & & ( - - repetition_cnt > 0 ) ) ;
FINE_TUNE_EXIT :
@ -1466,16 +1469,16 @@
}
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
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 ] ;
int8_t grid_G_index_to_xpos [ grid_size ] , // UBL MESH X index to be probed
grid_G_index_to_ypos [ grid_size ] , // UBL MESH Y index to be probed
i , j , k , xCount , yCount , xi, yi ; // counter variables
float z_values_G [ grid_size ] [ grid_size ] ;
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 ;
for ( yi = 0 ; yi < grid_size ; yi + + )
for ( xi = 0 ; xi < grid_size ; xi + + )
z_values_G [ xi ] [ yi ] = NAN ;
uint8_t x_min = GRID_MAX_POINTS_X - 1 ,
x_max = 0 ,
@ -1494,26 +1497,26 @@
}
}
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 | | y_max - y_min + 1 < grid_size ) {
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 ) ;
SERIAL_ECHOLNPAIR ( " grid: " , grid_size ) ;
return ;
}
// populate X matrix
for ( G_X_index = 0 ; G_X_index < grid_size_G ; G_X_index + + ) {
grid_G_index_to_xpos [ G_X_index] = x_min + G_X_index * ( x_max - x_min ) / ( grid_size _G - 1 ) ;
if ( G_X_index > 0 & & grid_G_index_to_xpos [ G_X_index - 1 ] = = grid_G_index_to_xpos [ G_X_index ] ) {
grid_G_index_to_xpos [ G_X_index] = grid_G_index_to_xpos [ G_X_index - 1 ] + 1 ;
for ( xi = 0 ; xi < grid_size ; xi + + ) {
grid_G_index_to_xpos [ xi] = x_min + xi * ( x_max - x_min ) / ( grid_size - 1 ) ;
if ( xi > 0 & & grid_G_index_to_xpos [ xi - 1 ] = = grid_G_index_to_xpos [ xi ] ) {
grid_G_index_to_xpos [ xi] = grid_G_index_to_xpos [ xi - 1 ] + 1 ;
}
}
// populate Y matrix
for ( G_Y_index = 0 ; G_Y_index < grid_size_G ; G_Y_index + + ) {
grid_G_index_to_ypos [ G_Y_index] = y_min + G_Y_index * ( y_max - y_min ) / ( grid_size _G - 1 ) ;
if ( G_Y_index > 0 & & grid_G_index_to_ypos [ G_Y_index - 1 ] = = grid_G_index_to_ypos [ G_Y_index ] ) {
grid_G_index_to_ypos [ G_Y_index] = grid_G_index_to_ypos [ G_Y_index - 1 ] + 1 ;
for ( yi = 0 ; yi < grid_size ; yi + + ) {
grid_G_index_to_ypos [ yi] = y_min + yi * ( y_max - y_min ) / ( grid_size - 1 ) ;
if ( yi > 0 & & grid_G_index_to_ypos [ yi - 1 ] = = grid_G_index_to_ypos [ yi ] ) {
grid_G_index_to_ypos [ yi] = grid_G_index_to_ypos [ yi - 1 ] + 1 ;
}
}
@ -1526,14 +1529,14 @@
# undef PROBE_Y_FIRST
# if ENABLED(PROBE_Y_FIRST)
# define PR_OUTER_VAR xCount
# define PR_OUTER_NUM grid_size _G
# define PR_OUTER_NUM grid_size
# define PR_INNER_VAR yCount
# define PR_INNER_NUM grid_size _G
# define PR_INNER_NUM grid_size
# else
# define PR_OUTER_VAR yCount
# define PR_OUTER_NUM grid_size _G
# define PR_OUTER_NUM grid_size
# define PR_INNER_VAR xCount
# define PR_INNER_NUM grid_size _G
# define PR_INNER_NUM grid_size
# endif
bool zig = PR_OUTER_NUM & 1 ; // Always end at RIGHT and BACK_PROBE_BED_POSITION
@ -1601,9 +1604,9 @@
//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 xxx 9 [ ] = { 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 } ,
yyy 9 [ ] = { 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 } ,
zzz 9 [ ] = { 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 } ,
double xxx 5 [ ] = { 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 } ,
yyy 5 [ ] = { 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 } ,
zzz 5 [ ] = { 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 } ,
@ -1611,10 +1614,10 @@
yyy [ ] = { 0.0 , 1.0 , 0.0 , 1.0 } ,
zzz [ ] = { 0.05 , 0.05 , 0.15 , 0.15 } ;
results = lsf_linear_fit ( xxx 9, yyy9 , zzz9 , COUNT ( xxx9 ) ) ;
SERIAL_ECHOPAIR ( " \n xxx 9 ->A =" , results - > A ) ;
SERIAL_ECHOPAIR ( " \n xxx 9 ->B =" , results - > B ) ;
SERIAL_ECHOPAIR ( " \n xxx 9 ->D =" , results - > D ) ;
results = lsf_linear_fit ( xxx 5, yyy5 , zzz5 , COUNT ( xxx5 ) ) ;
SERIAL_ECHOPAIR ( " \n xxx 5 ->A =" , results - > A ) ;
SERIAL_ECHOPAIR ( " \n xxx 5 ->B =" , results - > B ) ;
SERIAL_ECHOPAIR ( " \n xxx 5 ->D =" , results - > D ) ;
SERIAL_EOL ;
results = lsf_linear_fit ( xxx0 , yyy0 , zzz0 , COUNT ( xxx0 ) ) ;