@ -61,7 +61,7 @@
* G30 - Single Z probe , probes bed at X Y location ( defaults to current XY location )
* G31 - Dock sled ( Z_PROBE_SLED only )
* G32 - Undock sled ( Z_PROBE_SLED only )
* G33 - Delta ' 4- point ' auto calibration iteration
* G33 - Delta ' 1- 4- 7 - point ' auto calibration : " G33 V<verbose> P<points> <A> <O> <T> " ( Requires DELTA )
* G38 - Probe target - similar to G28 except it uses the Z_MIN_PROBE for all three axes
* G90 - Use Absolute Coordinates
* G91 - Use Relative Coordinates
@ -585,10 +585,10 @@ static uint8_t target_extruder;
// These values are loaded or reset at boot time when setup() calls
// settings.load(), which calls recalc_delta_settings().
float delta_radius ,
delta_tower_angle_trim [ ABC ] ,
delta_tower_angle_trim [ 2 ] ,
delta_tower [ ABC ] [ 2 ] ,
delta_diagonal_rod ,
delta_ diagonal_rod_trim[ ABC ] ,
delta_ calibration_radius ,
delta_diagonal_rod_2_tower [ ABC ] ,
delta_segments_per_second ,
delta_clip_start_height = Z_MAX_POS ;
@ -1830,6 +1830,9 @@ static void clean_up_after_endstop_or_probe_move() {
float z_dest = LOGICAL_Z_POSITION ( z_raise ) ;
if ( zprobe_zoffset < 0 ) z_dest - = zprobe_zoffset ;
# if ENABLED(DELTA)
z_dest - = home_offset [ Z_AXIS ] ;
# endif
if ( z_dest > current_position [ Z_AXIS ] )
do_blocking_move_to_z ( z_dest ) ;
@ -1837,7 +1840,8 @@ static void clean_up_after_endstop_or_probe_move() {
# endif //HAS_BED_PROBE
# if ENABLED(Z_PROBE_ALLEN_KEY) || ENABLED(Z_PROBE_SLED) || HAS_PROBING_PROCEDURE || HOTENDS > 1 || ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE)
# if HAS_PROBING_PROCEDURE || HOTENDS > 1 || ENABLED(Z_PROBE_ALLEN_KEY) || ENABLED(Z_PROBE_SLED) || ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE) || ENABLED(DELTA_AUTO_CALIBRATION)
bool axis_unhomed_error ( const bool x , const bool y , const bool z ) {
const bool xx = x & & ! axis_homed [ X_AXIS ] ,
yy = y & & ! axis_homed [ Y_AXIS ] ,
@ -1857,6 +1861,7 @@ static void clean_up_after_endstop_or_probe_move() {
}
return false ;
}
# endif
# if ENABLED(Z_PROBE_SLED)
@ -2308,6 +2313,9 @@ static void clean_up_after_endstop_or_probe_move() {
// move down quickly before doing the slow probe
float z = LOGICAL_Z_POSITION ( Z_CLEARANCE_BETWEEN_PROBES ) ;
if ( zprobe_zoffset < 0 ) z - = zprobe_zoffset ;
# if ENABLED(DELTA)
z - = home_offset [ Z_AXIS ] ;
# endif
if ( z < current_position [ Z_AXIS ] )
do_blocking_move_to_z ( z , MMM_TO_MMS ( Z_PROBE_SPEED_FAST ) ) ;
@ -5009,11 +5017,12 @@ inline void gcode_G28() {
/**
* G30 : Do a single Z probe at the current XY
* Usage :
* G30 < X # > < Y # > < S # >
* X = Probe X position ( default = current probe position )
* Y = Probe Y position ( default = current probe position )
* S = Stows the probe if 1 ( default = 1 )
*
* Parameters :
*
* X Probe X position ( default current X )
* Y Probe Y position ( default current Y )
* S0 Leave the probe deployed
*/
inline void gcode_G30 ( ) {
const float xpos = code_seen ( ' X ' ) ? code_value_linear_units ( ) : current_position [ X_AXIS ] + X_PROBE_OFFSET_FROM_EXTRUDER ,
@ -5056,32 +5065,25 @@ inline void gcode_G28() {
# if ENABLED(DELTA_AUTO_CALIBRATION)
/**
* G33 : Delta ' 4 - point ' auto calibration iteration
* G33 - Delta ' 1 - 4 - 7 - point ' auto calibration ( Requires DELTA )
*
* Usage : G33 < Cn > < Vn >
* Usage :
* G33 < Vn > < Pn > < A > < O > < T >
*
* C ( default ) = Calibrate endstops , height and delta radius
*
* - 2 , 1 - 4 : n x n probe points , default 3 x 3
*
* 1 : probe center
* set height only - useful when z_offset is changed
* 2 : probe center and towers
* solve one ' 4 point ' calibration
* - 2 : probe center and opposite the towers
* solve one ' 4 point ' calibration
* 3 : probe 3 center points , towers and opposite - towers
* averages between 2 ' 4 point ' calibrations
* 4 : probe 4 center points , towers , opposite - towers and itermediate points
* averages between 4 ' 4 point ' calibrations
*
* V Verbose level ( 0 - 3 , default 1 )
*
* 0 : Dry - run mode : no calibration
* 1 : Settings
* 2 : Setting + probe results
* 3 : Expert mode : setting + iteration factors ( see Configuration_adv . h )
* This prematurely stops the iteration process when factors are found
* Vn = verbose level ( n = 0 - 2 default 1 )
* n = 0 dry - run mode : setting + probe results / no calibration
* n = 1 settings
* n = 2 setting + probe results
* Pn = n = - 7 - > + 7 : n * n probe points
* calibrates height ( ' 1 point ' ) , endstops , and delta radius ( ' 4 points ' )
* and tower angles with n > 2 ( ' 7 + points ' )
* n = 1 probes center / sets height only
* n = 2 probes center and towers / sets height , endstops and delta radius
* n = 3 probes all points : center , towers and opposite towers / sets all
* n > 3 probes all points multiple times and averages
* A = abort 1 point delta height calibration after 1 probe
* O = use oposite tower points instead of tower points with 4 point calibration
* T = do not calibrate tower angles with 7 + point calibration
*/
inline void gcode_G33 ( ) {
@ -5091,49 +5093,55 @@ inline void gcode_G28() {
set_bed_leveling_enabled ( false ) ;
# endif
const int8_t pp = code_seen ( ' C ' ) ? code_value_int ( ) : DELTA_CALIBRATION_DEFAULT_POINTS ,
probe_points = ( WITHIN ( pp , 1 , 4 ) | | pp = = - 2 ) ? pp : DELTA_CALIBRATION_DEFAULT_POINTS ;
int8_t pp = ( code_seen ( ' P ' ) ? code_value_int ( ) : DELTA_CALIBRATION_DEFAULT_POINTS ) ,
probe_mode = ( WITHIN ( pp , 1 , 7 ) ? pp : DELTA_CALIBRATION_DEFAULT_POINTS ) ;
int8_t verbose_level = code_seen ( ' V ' ) ? code_value_byte ( ) : 1 ;
probe_mode = ( code_seen ( ' A ' ) & & probe_mode = = 1 ? - probe_mode : probe_mode ) ;
probe_mode = ( code_seen ( ' O ' ) & & probe_mode = = 2 ? - probe_mode : probe_mode ) ;
probe_mode = ( code_seen ( ' T ' ) & & probe_mode > 2 ? - probe_mode : probe_mode ) ;
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
# define _MAX_M33_V 3
if ( verbose_level = = 3 & & probe_points = = 1 ) verbose_level - - ; // needs at least 4 points
# else
# define _MAX_M33_V 2
if ( verbose_level > 2 )
SERIAL_PROTOCOLLNPGM ( " Enable DELTA_CALIBRATE_EXPERT_MODE in Configuration_adv.h " ) ;
# endif
int8_t verbose_level = ( code_seen ( ' V ' ) ? code_value_byte ( ) : 1 ) ;
if ( ! WITHIN ( verbose_level , 0 , _MAX_M33_V ) ) verbose_level = 1 ;
float zero_std_dev = verbose_level ? 999.0 : 0.0 ; // 0.0 in dry-run mode : forced end
if ( ! WITHIN ( verbose_level , 0 , 2 ) ) verbose_level = 1 ;
gcode_G28 ( ) ;
float e_old [ XYZ ] ,
const static char save_message [ ] PROGMEM = " Save with M500 and/or copy to Configuration.h " ;
float test_precision ,
zero_std_dev = ( verbose_level ? 999.0 : 0.0 ) , // 0.0 in dry-run mode : forced end
e_old [ XYZ ] = {
endstop_adj [ A_AXIS ] ,
endstop_adj [ B_AXIS ] ,
endstop_adj [ C_AXIS ]
} ,
dr_old = delta_radius ,
zh_old = home_offset [ Z_AXIS ] ;
COPY ( e_old , endstop_adj ) ;
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
// expert variables
float h_f_old = 1.00 , r_f_old = 0.00 ,
h_diff_min = 1.00 , r_diff_max = 0.10 ;
# endif
zh_old = home_offset [ Z_AXIS ] ,
alpha_old = delta_tower_angle_trim [ A_AXIS ] ,
beta_old = delta_tower_angle_trim [ B_AXIS ] ;
int8_t iterations = 0 ,
probe_points = abs ( probe_mode ) ;
const bool pp_equals_1 = ( probe_points = = 1 ) ,
pp_equals_2 = ( probe_points = = 2 ) ,
pp_equals_3 = ( probe_points = = 3 ) ,
pp_equals_4 = ( probe_points = = 4 ) ,
pp_equals_5 = ( probe_points = = 5 ) ,
pp_equals_6 = ( probe_points = = 6 ) ,
pp_equals_7 = ( probe_points = = 7 ) ,
pp_greather_2 = ( probe_points > 2 ) ,
pp_greather_3 = ( probe_points > 3 ) ,
pp_greather_4 = ( probe_points > 4 ) ,
pp_greather_5 = ( probe_points > 5 ) ;
// print settings
SERIAL_PROTOCOLLNPGM ( " G33 Auto Calibrate " ) ;
SERIAL_PROTOCOLPGM ( " Checking... AC " ) ;
if ( verbose_level = = 0 ) SERIAL_PROTOCOLPGM ( " (DRY-RUN) " ) ;
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
if ( verbose_level = = 3 ) SERIAL_PROTOCOLPGM ( " (EXPERT) " ) ;
# endif
SERIAL_EOL ;
LCD_MESSAGEPGM ( " Checking... AC " ) ;
SERIAL_PROTOCOLPAIR ( " Height:" , DELTA_HEIGHT + home_offset [ Z_AXIS ] ) ;
if ( abs ( probe_points ) > 1) {
SERIAL_PROTOCOLPAIR ( " . Height:" , DELTA_HEIGHT + home_offset [ Z_AXIS ] ) ;
if ( ! pp_equals_ 1) {
SERIAL_PROTOCOLPGM ( " Ex: " ) ;
if ( endstop_adj [ A_AXIS ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( endstop_adj [ A_AXIS ] , 2 ) ;
@ -5146,74 +5154,84 @@ inline void gcode_G28() {
SERIAL_PROTOCOLPAIR ( " Radius: " , delta_radius ) ;
}
SERIAL_EOL ;
if ( probe_mode > 2 ) { // negative disables tower angles
SERIAL_PROTOCOLPGM ( " .Tower angle : Tx: " ) ;
if ( delta_tower_angle_trim [ A_AXIS ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( delta_tower_angle_trim [ A_AXIS ] , 2 ) ;
SERIAL_PROTOCOLPGM ( " Ty: " ) ;
if ( delta_tower_angle_trim [ B_AXIS ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( delta_tower_angle_trim [ B_AXIS ] , 2 ) ;
SERIAL_PROTOCOLPGM ( " Tz:+0.00 " ) ;
SERIAL_EOL ;
}
# if ENABLED(Z_PROBE_SLED)
DEPLOY_PROBE ( ) ;
# endif
float test_precision ;
int8_t iterations = 0 ;
do { // start iterations
setup_for_endstop_or_probe_move ( ) ;
test_precision =
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
// Expert mode : forced end at std_dev < 0.1
( verbose_level = = 3 & & zero_std_dev < 0.1 ) ? 0.0 :
# endif
zero_std_dev
;
do {
float z_at_pt [ 13 ] = { 0 } ;
float z_at_pt [ 13 ] = { 0 } ,
S1 = 0.0 ,
S2 = 0.0 ;
int16_t N = 0 ;
test_precision = zero_std_dev ;
iterations + + ;
// probe the points
int16_t center_points = 0 ;
if ( probe_points ! = 3 ) {
if ( ! pp_equals_3 & & ! pp_equals_6 ) { // probe the centre
setup_for_endstop_or_probe_move ( ) ;
z_at_pt [ 0 ] + = probe_pt ( 0.0 , 0.0 , true , 1 ) ;
c enter_points = 1 ;
c lean_up_after_endstop_or_probe_move( ) ;
}
int16_t step_axis = 4 ;
if ( probe_points > = 3 ) {
for ( int8_t axis = 9 ; axis > 0 ; axis - = step_axis ) { // uint8_t starts endless loop
if ( pp_greather_2 ) { // probe extra centre points
for ( int8_t axis = ( pp_greather_4 ? 11 : 9 ) ; axis > 0 ; axis - = ( pp_greather_4 ? 2 : 4 ) ) {
setup_for_endstop_or_probe_move ( ) ;
z_at_pt [ 0 ] + = probe_pt (
0.1 * cos ( RADIANS ( 180 + 30 * axis ) ) * ( DELTA_CALIBRATION_RADIUS ) ,
0.1 * sin ( RADIANS ( 180 + 30 * axis ) ) * ( DELTA_CALIBRATION_RADIUS ) , true , 1 ) ;
cos ( RADIANS ( 180 + 30 * axis ) ) * ( 0.1 * delta_calibration_radius ) ,
sin ( RADIANS ( 180 + 30 * axis ) ) * ( 0.1 * delta_calibration_radius ) , true , 1 ) ;
clean_up_after_endstop_or_probe_move ( ) ;
}
center_points + = 3 ;
z_at_pt [ 0 ] / = center_points ;
z_at_pt [ 0 ] / = ( pp_equals_5 ? 7 : probe_points ) ;
}
float S1 = z_at_pt [ 0 ] , S2 = sq ( S1 ) ;
int16_t N = 1 , start = ( probe_points = = - 2 ) ? 3 : 1 ;
step_axis = ( abs ( probe_points ) = = 2 ) ? 4 : ( probe_points = = 3 ) ? 2 : 1 ;
if ( probe_points ! = 1 ) {
for ( uint8_t axis = start ; axis < 13 ; axis + = step_axis )
z_at_pt [ axis ] + = probe_pt (
cos ( RADIANS ( 180 + 30 * axis ) ) * ( DELTA_CALIBRATION_RADIUS ) ,
sin ( RADIANS ( 180 + 30 * axis ) ) * ( DELTA_CALIBRATION_RADIUS ) , true , 1
) ;
if ( probe_points = = 4 ) step_axis = 2 ;
if ( ! pp_equals_1 ) { // probe the radius
float start_circles = ( pp_equals_7 ? - 1.5 : pp_equals_6 | | pp_equals_5 ? - 1 : 0 ) ,
end_circles = - start_circles ;
bool zig_zag = true ;
for ( uint8_t axis = ( probe_mode = = - 2 ? 3 : 1 ) ; axis < 13 ;
axis + = ( pp_equals_2 ? 4 : pp_equals_3 | | pp_equals_5 ? 2 : 1 ) ) {
for ( float circles = start_circles ; circles < = end_circles ; circles + + ) {
setup_for_endstop_or_probe_move ( ) ;
z_at_pt [ axis ] + = probe_pt (
cos ( RADIANS ( 180 + 30 * axis ) ) *
( 1 + circles * 0.1 * ( zig_zag ? 1 : - 1 ) ) * delta_calibration_radius ,
sin ( RADIANS ( 180 + 30 * axis ) ) *
( 1 + circles * 0.1 * ( zig_zag ? 1 : - 1 ) ) * delta_calibration_radius , true , 1 ) ;
clean_up_after_endstop_or_probe_move ( ) ;
}
start_circles + = ( pp_greather_5 ? ( zig_zag ? 0.5 : - 0.5 ) : 0 ) ;
end_circles = - start_circles ;
zig_zag = ! zig_zag ;
z_at_pt [ axis ] / = ( pp_equals_7 ? ( zig_zag ? 4.0 : 3.0 ) :
pp_equals_6 ? ( zig_zag ? 3.0 : 2.0 ) : pp_equals_5 ? 3 : 1 ) ;
}
}
for ( uint8_t axis = start ; axis < 13 ; axis + = step_axis ) {
if ( probe_points = = 4 )
if ( pp_greather_3 & & ! pp_equals_5 ) // average intermediates to tower and opposites
for ( uint8_t axis = 1 ; axis < 13 ; axis + = 2 )
z_at_pt [ axis ] = ( z_at_pt [ axis ] + ( z_at_pt [ axis + 1 ] + z_at_pt [ ( axis + 10 ) % 12 + 1 ] ) / 2.0 ) / 2.0 ;
S1 + = z_at_pt [ axis ] ;
S2 + = sq ( z_at_pt [ axis ] ) ;
N + + ;
}
zero_std_dev = round ( sqrt ( S2 / N ) * 1000.0 ) / 1000.0 + 0.00001 ; // deviation from zero plane
S1 + = z_at_pt [ 0 ] ;
S2 + = sq ( z_at_pt [ 0 ] ) ;
N + + ;
if ( ! pp_equals_1 ) // std dev from zero plane
for ( uint8_t axis = ( probe_mode = = - 2 ? 3 : 1 ) ; axis < 13 ; axis + = ( pp_equals_2 ? 4 : 2 ) ) {
S1 + = z_at_pt [ axis ] ;
S2 + = sq ( z_at_pt [ axis ] ) ;
N + + ;
}
zero_std_dev = round ( sqrt ( S2 / N ) * 1000.0 ) / 1000.0 + 0.00001 ;
// Solve matrices
@ -5221,28 +5239,33 @@ inline void gcode_G28() {
COPY ( e_old , endstop_adj ) ;
dr_old = delta_radius ;
zh_old = home_offset [ Z_AXIS ] ;
alpha_old = delta_tower_angle_trim [ A_AXIS ] ;
beta_old = delta_tower_angle_trim [ B_AXIS ] ;
float e_delta [ XYZ ] = { 0.0 } , r_delta = 0.0 ;
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
float h_f_new = 0.0 , r_f_new = 0.0 , t_f_new = 0.0 ,
h_diff = 0.00 , r_diff = 0.00 ;
# endif
float e_delta [ XYZ ] = { 0.0 } , r_delta = 0.0 ,
t_alpha = 0.0 , t_beta = 0.0 ;
const float r_diff = delta_radius - delta_calibration_radius ,
h_factor = 1.00 + r_diff * 0.001 , //1.02 for r_diff = 20mm
r_factor = - ( 1.75 + 0.005 * r_diff + 0.001 * sq ( r_diff ) ) , //2.25 for r_diff = 20mm
a_factor = 100.0 / delta_calibration_radius ; //1.25 for cal_rd = 80mm
# define ZP(N,I) ((N) * z_at_pt[I])
# define Z1000(I) ZP(1.00, I)
# define Z1050(I) ZP(H_FACTOR, I)
# define Z0700(I) ZP((H_FACTOR) * 2.0 / 3.00, I)
# define Z0350(I) ZP((H_FACTOR) / 3.00, I)
# define Z0175(I) ZP((H_FACTOR) / 6.00, I)
# define Z2250(I) ZP(R_FACTOR, I)
# define Z0750(I) ZP((R_FACTOR) / 3.00, I)
# define Z0375(I) ZP((R_FACTOR) / 6.00, I)
switch ( probe_points ) {
# define Z1050(I) ZP(h_factor, I)
# define Z0700(I) ZP(h_factor * 2.0 / 3.00, I)
# define Z0350(I) ZP(h_factor / 3.00, I)
# define Z0175(I) ZP(h_factor / 6.00, I)
# define Z2250(I) ZP(r_factor, I)
# define Z0750(I) ZP(r_factor / 3.00, I)
# define Z0375(I) ZP(r_factor / 6.00, I)
# define Z0444(I) ZP(a_factor * 4.0 / 9.0, I)
# define Z0888(I) ZP(a_factor * 8.0 / 9.0, I)
switch ( probe_mode ) {
case - 1 :
test_precision = 0.00 ;
case 1 :
LOOP_XYZ ( i ) e_delta [ i ] = Z1000 ( 0 ) ;
r_delta = 0.00 ;
break ;
case 2 :
@ -5264,67 +5287,43 @@ inline void gcode_G28() {
e_delta [ Y_AXIS ] = Z1050 ( 0 ) - Z0175 ( 1 ) + Z0350 ( 5 ) - Z0175 ( 9 ) + Z0175 ( 7 ) - Z0350 ( 11 ) + Z0175 ( 3 ) ;
e_delta [ Z_AXIS ] = Z1050 ( 0 ) - Z0175 ( 1 ) - Z0175 ( 5 ) + Z0350 ( 9 ) + Z0175 ( 7 ) + Z0175 ( 11 ) - Z0350 ( 3 ) ;
r_delta = Z2250 ( 0 ) - Z0375 ( 1 ) - Z0375 ( 5 ) - Z0375 ( 9 ) - Z0375 ( 7 ) - Z0375 ( 11 ) - Z0375 ( 3 ) ;
if ( probe_mode > 0 ) { // negative disables tower angles
t_alpha = + Z0444 ( 1 ) - Z0888 ( 5 ) + Z0444 ( 9 ) + Z0444 ( 7 ) - Z0888 ( 11 ) + Z0444 ( 3 ) ;
t_beta = - Z0888 ( 1 ) + Z0444 ( 5 ) + Z0444 ( 9 ) - Z0888 ( 7 ) + Z0444 ( 11 ) + Z0444 ( 3 ) ;
}
break ;
}
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
// Calculate h & r factors
if ( verbose_level = = 3 ) {
LOOP_XYZ ( axis ) h_f_new + = e_delta [ axis ] / 3 ;
r_f_new = r_delta ;
h_diff = ( 1.0 / H_FACTOR ) * ( h_f_old - h_f_new ) / h_f_old ;
if ( h_diff < h_diff_min & & h_diff > 0.9 ) h_diff_min = h_diff ;
if ( r_f_old ! = 0 )
r_diff = ( 0.0301 * sq ( R_FACTOR ) * R_FACTOR
+ 0.311 * sq ( R_FACTOR )
+ 1.1493 * R_FACTOR
+ 1.7952
) * ( r_f_old - r_f_new ) / r_f_old ;
if ( r_diff > r_diff_max & & r_diff < 0.4444 ) r_diff_max = r_diff ;
SERIAL_EOL ;
h_f_old = h_f_new ;
r_f_old = r_f_new ;
}
# endif // DELTA_CALIBRATE_EXPERT_MODE
// Adjust delta_height and endstops by the max amount
LOOP_XYZ ( axis ) endstop_adj [ axis ] + = e_delta [ axis ] ;
delta_radius + = r_delta ;
delta_tower_angle_trim [ A_AXIS ] + = t_alpha ;
delta_tower_angle_trim [ B_AXIS ] - = t_beta ;
const float z_temp = MAX3 ( endstop_adj [ 0 ] , endstop_adj [ 1 ] , endstop_adj [ 2 ] ) ;
// adjust delta_height and endstops by the max amount
const float z_temp = MAX3 ( endstop_adj [ A_AXIS ] , endstop_adj [ B_AXIS ] , endstop_adj [ C_AXIS ] ) ;
home_offset [ Z_AXIS ] - = z_temp ;
LOOP_XYZ ( i ) endstop_adj [ i ] - = z_temp ;
recalc_delta_settings ( delta_radius , delta_diagonal_rod ) ;
}
else { // !iterate
// step one back
else { // step one back
COPY ( endstop_adj , e_old ) ;
delta_radius = dr_old ;
home_offset [ Z_AXIS ] = zh_old ;
delta_tower_angle_trim [ A_AXIS ] = alpha_old ;
delta_tower_angle_trim [ B_AXIS ] = beta_old ;
recalc_delta_settings ( delta_radius , delta_diagonal_rod ) ;
}
// print report
// print report
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
if ( verbose_level = = 3 ) {
const float r_factor = 22.902 * sq ( r_diff_max ) * r_diff_max
- 44.988 * sq ( r_diff_max )
+ 31.697 * r_diff_max
- 9.4439 ;
SERIAL_PROTOCOLPAIR ( " h_factor: " , 1.0 / h_diff_min ) ;
SERIAL_PROTOCOLPAIR ( " r_factor: " , r_factor ) ;
SERIAL_EOL ;
}
# endif
if ( verbose_level = = 2 ) {
SERIAL_PROTOCOLPGM ( " . c: " ) ;
if ( verbose_level ! = 1 ) {
SERIAL_PROTOCOLPGM ( " . c: " ) ;
if ( z_at_pt [ 0 ] > 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( z_at_pt [ 0 ] , 2 ) ;
if ( probe_ points > 1 ) {
if ( probe_mode = = 2 | | pp_greather_2 ) {
SERIAL_PROTOCOLPGM ( " x: " ) ;
if ( z_at_pt [ 1 ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( z_at_pt [ 1 ] , 2 ) ;
@ -5335,9 +5334,12 @@ inline void gcode_G28() {
if ( z_at_pt [ 9 ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( z_at_pt [ 9 ] , 2 ) ;
}
if ( probe_points > 0 ) SERIAL_EOL ;
if ( probe_points > 2 | | probe_points = = - 2 ) {
if ( probe_points > 2 ) SERIAL_PROTOCOLPGM ( " . " ) ;
if ( probe_mode ! = - 2 ) SERIAL_EOL ;
if ( probe_mode = = - 2 | | pp_greather_2 ) {
if ( pp_greather_2 ) {
SERIAL_CHAR ( ' . ' ) ;
SERIAL_PROTOCOL_SP ( 13 ) ;
}
SERIAL_PROTOCOLPGM ( " yz: " ) ;
if ( z_at_pt [ 7 ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( z_at_pt [ 7 ] , 2 ) ;
@ -5350,25 +5352,27 @@ inline void gcode_G28() {
SERIAL_EOL ;
}
}
if ( test_precision ! = 0.0 ) { // !forced end
if ( zero_std_dev > = test_precision ) {
if ( test_precision ! = 0.0 ) { // !forced end
if ( zero_std_dev > = test_precision ) { // end iterations
SERIAL_PROTOCOLPGM ( " Calibration OK " ) ;
SERIAL_PROTOCOL LNPGM( " rolling back 1 " ) ;
LCD_MESSAGEPGM( " Calibration OK " ) ;
SERIAL_PROTOCOL _SP( 36 ) ;
SERIAL_PROTOCOLPGM( " rolling back. " ) ;
SERIAL_EOL ;
LCD_MESSAGEPGM ( " Calibration OK " ) ;
}
else { // !end iterations
else { // !end iterations
char mess [ 15 ] = " No convergence " ;
if ( iterations < 31 )
sprintf_P ( mess , PSTR ( " Iteration : %02i " ) , ( int ) iterations ) ;
SERIAL_PROTOCOL ( mess ) ;
SERIAL_PROTOCOLPGM ( " std dev: " ) ;
SERIAL_PROTOCOL_SP ( 36 ) ;
SERIAL_PROTOCOLPGM ( " std dev: " ) ;
SERIAL_PROTOCOL_F ( zero_std_dev , 3 ) ;
SERIAL_EOL ;
lcd_setstatus ( mess ) ;
}
SERIAL_PROTOCOLPAIR ( " Height:" , DELTA_HEIGHT + home_offset [ Z_AXIS ] ) ;
if ( abs ( probe_points ) > 1) {
SERIAL_PROTOCOLPAIR ( " . Height:" , DELTA_HEIGHT + home_offset [ Z_AXIS ] ) ;
if ( ! pp_equals_ 1) {
SERIAL_PROTOCOLPGM ( " Ex: " ) ;
if ( endstop_adj [ A_AXIS ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( endstop_adj [ A_AXIS ] , 2 ) ;
@ -5381,23 +5385,38 @@ inline void gcode_G28() {
SERIAL_PROTOCOLPAIR ( " Radius: " , delta_radius ) ;
}
SERIAL_EOL ;
if ( probe_mode > 2 ) { // negative disables tower angles
SERIAL_PROTOCOLPGM ( " .Tower angle : Tx: " ) ;
if ( delta_tower_angle_trim [ A_AXIS ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( delta_tower_angle_trim [ A_AXIS ] , 2 ) ;
SERIAL_PROTOCOLPGM ( " Ty: " ) ;
if ( delta_tower_angle_trim [ B_AXIS ] > = 0 ) SERIAL_CHAR ( ' + ' ) ;
SERIAL_PROTOCOL_F ( delta_tower_angle_trim [ B_AXIS ] , 2 ) ;
SERIAL_PROTOCOLPGM ( " Tz:+0.00 " ) ;
SERIAL_EOL ;
}
if ( zero_std_dev > = test_precision )
SERIAL_PROTOCOLLNPGM ( " Save with M500 " ) ;
serialprintPGM ( save_message ) ;
SERIAL_EOL ;
}
else { // forced end
# if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
if ( verbose_level = = 3 )
SERIAL_PROTOCOLLNPGM ( " Copy to Configuration_adv.h " ) ;
else
# endif
{
SERIAL_PROTOCOLPGM ( " End DRY-RUN std dev: " ) ;
SERIAL_PROTOCOL_F ( zero_std_dev , 3 ) ;
SERIAL_EOL ;
}
else { // forced end
if ( verbose_level = = 0 ) {
SERIAL_PROTOCOLPGM ( " End DRY-RUN " ) ;
SERIAL_PROTOCOL_SP ( 39 ) ;
SERIAL_PROTOCOLPGM ( " std dev: " ) ;
SERIAL_PROTOCOL_F ( zero_std_dev , 3 ) ;
SERIAL_EOL ;
}
else {
SERIAL_PROTOCOLLNPGM ( " Calibration OK " ) ;
LCD_MESSAGEPGM ( " Calibration OK " ) ;
SERIAL_PROTOCOLPAIR ( " .Height: " , DELTA_HEIGHT + home_offset [ Z_AXIS ] ) ;
SERIAL_EOL ;
serialprintPGM ( save_message ) ;
SERIAL_EOL ;
}
}
clean_up_after_endstop_or_probe_move ( ) ;
stepper . synchronize ( ) ;
gcode_G28 ( ) ;
@ -7620,12 +7639,13 @@ inline void gcode_M205() {
if ( code_seen ( ' L ' ) ) delta_diagonal_rod = code_value_linear_units ( ) ;
if ( code_seen ( ' R ' ) ) delta_radius = code_value_linear_units ( ) ;
if ( code_seen ( ' S ' ) ) delta_segments_per_second = code_value_float ( ) ;
if ( code_seen ( ' A ' ) ) delta_diagonal_rod_trim [ A_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' B ' ) ) delta_diagonal_rod_trim [ B_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' C ' ) ) delta_diagonal_rod_trim [ C_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' I ' ) ) delta_tower_angle_trim [ A_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' J ' ) ) delta_tower_angle_trim [ B_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' K ' ) ) delta_tower_angle_trim [ C_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' B ' ) ) delta_calibration_radius = code_value_float ( ) ;
if ( code_seen ( ' X ' ) ) delta_tower_angle_trim [ A_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' Y ' ) ) delta_tower_angle_trim [ B_AXIS ] = code_value_linear_units ( ) ;
if ( code_seen ( ' Z ' ) ) { // rotate all 3 axis for Z = 0
delta_tower_angle_trim [ A_AXIS ] - = code_value_linear_units ( ) ;
delta_tower_angle_trim [ B_AXIS ] - = code_value_linear_units ( ) ;
}
recalc_delta_settings ( delta_radius , delta_diagonal_rod ) ;
}
/**
@ -7653,6 +7673,10 @@ inline void gcode_M205() {
SERIAL_ECHOLNPGM ( " <<< gcode_M666 " ) ;
}
# endif
// normalize endstops so all are <=0; set the residue to delta height
const float z_temp = MAX3 ( endstop_adj [ A_AXIS ] , endstop_adj [ B_AXIS ] , endstop_adj [ C_AXIS ] ) ;
home_offset [ Z_AXIS ] - = z_temp ;
LOOP_XYZ ( i ) endstop_adj [ i ] - = z_temp ;
}
# elif ENABLED(Z_DUAL_ENDSTOPS) // !DELTA && ENABLED(Z_DUAL_ENDSTOPS)
@ -8564,7 +8588,7 @@ inline void gcode_M503() {
if ( ! isnan ( last_zoffset ) ) {
# if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(BABYSTEP_ZPROBE_OFFSET)
# if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(BABYSTEP_ZPROBE_OFFSET) || ENABLED(DELTA)
const float diff = zprobe_zoffset - last_zoffset ;
# endif
@ -8586,6 +8610,10 @@ inline void gcode_M503() {
# else
UNUSED ( no_babystep ) ;
# endif
# if ENABLED(DELTA) // correct the delta_height
home_offset [ Z_AXIS ] - = diff ;
# endif
}
last_zoffset = zprobe_zoffset ;
@ -10651,15 +10679,17 @@ void ok_to_send() {
* settings have been changed ( e . g . , by M665 ) .
*/
void recalc_delta_settings ( float radius , float diagonal_rod ) {
delta_tower [ A_AXIS ] [ X_AXIS ] = - sin ( RADIANS ( 60 - delta_tower_angle_trim [ A_AXIS ] ) ) * ( radius + DELTA_RADIUS_TRIM_TOWER_1 ) ; // front left tower
delta_tower [ A_AXIS ] [ Y_AXIS ] = - cos ( RADIANS ( 60 - delta_tower_angle_trim [ A_AXIS ] ) ) * ( radius + DELTA_RADIUS_TRIM_TOWER_1 ) ;
delta_tower [ B_AXIS ] [ X_AXIS ] = sin ( RADIANS ( 60 + delta_tower_angle_trim [ B_AXIS ] ) ) * ( radius + DELTA_RADIUS_TRIM_TOWER_2 ) ; // front right tower
delta_tower [ B_AXIS ] [ Y_AXIS ] = - cos ( RADIANS ( 60 + delta_tower_angle_trim [ B_AXIS ] ) ) * ( radius + DELTA_RADIUS_TRIM_TOWER_2 ) ;
delta_tower [ C_AXIS ] [ X_AXIS ] = - sin ( RADIANS ( delta_tower_angle_trim [ C_AXIS ] ) ) * ( radius + DELTA_RADIUS_TRIM_TOWER_3 ) ; // back middle tower
delta_tower [ C_AXIS ] [ Y_AXIS ] = cos ( RADIANS ( delta_tower_angle_trim [ C_AXIS ] ) ) * ( radius + DELTA_RADIUS_TRIM_TOWER_3 ) ;
delta_diagonal_rod_2_tower [ A_AXIS ] = sq ( diagonal_rod + delta_diagonal_rod_trim [ A_AXIS ] ) ;
delta_diagonal_rod_2_tower [ B_AXIS ] = sq ( diagonal_rod + delta_diagonal_rod_trim [ B_AXIS ] ) ;
delta_diagonal_rod_2_tower [ C_AXIS ] = sq ( diagonal_rod + delta_diagonal_rod_trim [ C_AXIS ] ) ;
const float trt [ ABC ] = DELTA_RADIUS_TRIM_TOWER ,
drt [ ABC ] = DELTA_DIAGONAL_ROD_TRIM_TOWER ;
delta_tower [ A_AXIS ] [ X_AXIS ] = cos ( RADIANS ( 210 + delta_tower_angle_trim [ A_AXIS ] ) ) * ( radius + trt [ A_AXIS ] ) ; // front left tower
delta_tower [ A_AXIS ] [ Y_AXIS ] = sin ( RADIANS ( 210 + delta_tower_angle_trim [ A_AXIS ] ) ) * ( radius + trt [ A_AXIS ] ) ;
delta_tower [ B_AXIS ] [ X_AXIS ] = cos ( RADIANS ( 330 + delta_tower_angle_trim [ B_AXIS ] ) ) * ( radius + trt [ B_AXIS ] ) ; // front right tower
delta_tower [ B_AXIS ] [ Y_AXIS ] = sin ( RADIANS ( 330 + delta_tower_angle_trim [ B_AXIS ] ) ) * ( radius + trt [ B_AXIS ] ) ;
delta_tower [ C_AXIS ] [ X_AXIS ] = 0.0 ; // back middle tower
delta_tower [ C_AXIS ] [ Y_AXIS ] = ( radius + trt [ C_AXIS ] ) ;
delta_diagonal_rod_2_tower [ A_AXIS ] = sq ( diagonal_rod + drt [ A_AXIS ] ) ;
delta_diagonal_rod_2_tower [ B_AXIS ] = sq ( diagonal_rod + drt [ B_AXIS ] ) ;
delta_diagonal_rod_2_tower [ C_AXIS ] = sq ( diagonal_rod + drt [ C_AXIS ] ) ;
}
# if ENABLED(DELTA_FAST_SQRT)