From b33375d438aa300bd705eb0d2fb16dd8e287221a Mon Sep 17 00:00:00 2001 From: Alex Borro Date: Wed, 27 Nov 2013 22:37:35 -0200 Subject: [PATCH] Z Axis Safe Homing when using Z Probe Recommended for those who are using the Z Probe for Z Homing (as Z-Endstop) This feature has two changes: 1) Allow user to choose where the Z Probe will touch the bed when homing all axis together (G28) by setting below defines: Z_SAFE_HOMING_X_POINT Z_SAFE_HOMING_Y_POINT 2) Prevents the user to perform Z Axis Homing when the Z Probe is outsite bed. --- Marlin/Configuration.h | 40 +++++++++++++----- Marlin/Marlin.h | 13 +++--- Marlin/Marlin_main.cpp | 92 +++++++++++++++++++++++++++++++++--------- Marlin/language.h | 18 +++++++++ 4 files changed, 128 insertions(+), 35 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 14afa75ea3..c5b96b280b 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -305,6 +305,17 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of #define min_software_endstops true // If true, axis won't move to coordinates less than HOME_POS. #define max_software_endstops true // If true, axis won't move to coordinates greater than the defined lengths below. +// Travel limits after homing +#define X_MAX_POS 205 +#define X_MIN_POS 0 +#define Y_MAX_POS 205 +#define Y_MIN_POS 0 +#define Z_MAX_POS 200 +#define Z_MIN_POS 0 + +#define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS) +#define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS) +#define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS) //============================= Bed Auto Leveling =========================== //#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line) @@ -336,20 +347,27 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of // You MUST HAVE the SERVO_ENDSTOPS defined to use here a value higher than zero otherwise your code will not compile. // #define PROBE_SERVO_DEACTIVATION_DELAY 300 + + +//If you have enabled the Bed Auto Levelling and are using the same Z Probe for Z Homing, +//it is highly recommended you let this Z_SAFE_HOMING enabled!!! + + #define Z_SAFE_HOMING // This feature is meant to avoid Z homing with probe outside the bed area. + // When defined, it will: + // - Allow Z homing only after X and Y homing AND stepper drivers still enabled + // - If stepper drivers timeout, it will need X and Y homing again before Z homing + // - Position the probe in a defined XY point before Z Homing when homing all axis (G28) + // - Block Z homing only when the probe is outside bed area. + + #ifdef Z_SAFE_HOMING + + #define Z_SAFE_HOMING_X_POINT (X_MAX_LENGTH/2) // X point for Z homing when homing all axis (G28) + #define Z_SAFE_HOMING_Y_POINT (Y_MAX_LENGTH/2) // Y point for Z homing when homing all axis (G28) + + #endif #endif -// Travel limits after homing -#define X_MAX_POS 205 -#define X_MIN_POS 0 -#define Y_MAX_POS 205 -#define Y_MIN_POS 0 -#define Z_MAX_POS 200 -#define Z_MIN_POS 0 - -#define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS) -#define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS) -#define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS) // The position of the homing switches //#define MANUAL_HOME_POSITIONS // If defined, MANUAL_*_HOME_POS below will be used diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index f8fa556a00..be4115e068 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -107,10 +107,10 @@ void manage_inactivity(); #if defined(DUAL_X_CARRIAGE) && defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 \ && defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1 #define enable_x() do { WRITE(X_ENABLE_PIN, X_ENABLE_ON); WRITE(X2_ENABLE_PIN, X_ENABLE_ON); } while (0) - #define disable_x() do { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); WRITE(X2_ENABLE_PIN,!X_ENABLE_ON); } while (0) + #define disable_x() do { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); WRITE(X2_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } while (0) #elif defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 #define enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON) - #define disable_x() WRITE(X_ENABLE_PIN,!X_ENABLE_ON) + #define disable_x() { WRITE(X_ENABLE_PIN,!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } #else #define enable_x() ; #define disable_x() ; @@ -119,10 +119,10 @@ void manage_inactivity(); #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1 #ifdef Y_DUAL_STEPPER_DRIVERS #define enable_y() { WRITE(Y_ENABLE_PIN, Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, Y_ENABLE_ON); } - #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, !Y_ENABLE_ON); } + #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); WRITE(Y2_ENABLE_PIN, !Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; } #else #define enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON) - #define disable_y() WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON) + #define disable_y() { WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; } #endif #else #define enable_y() ; @@ -132,10 +132,10 @@ void manage_inactivity(); #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1 #ifdef Z_DUAL_STEPPER_DRIVERS #define enable_z() { WRITE(Z_ENABLE_PIN, Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN, Z_ENABLE_ON); } - #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); } + #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); WRITE(Z2_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } #else #define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) - #define disable_z() WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON) + #define disable_z() { WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; } #endif #else #define enable_z() ; @@ -209,6 +209,7 @@ extern float endstop_adj[3]; #endif extern float min_pos[3]; extern float max_pos[3]; +extern bool axis_known_position[3]; extern int fanSpeed; #ifdef BARICUDA extern int ValvePressure; diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 47c5b1ab44..1537d3199a 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -43,6 +43,7 @@ #include "ConfigurationStore.h" #include "language.h" #include "pins_arduino.h" +#include "math.h" #ifdef BLINKM #include "BlinkM.h" @@ -191,6 +192,7 @@ float endstop_adj[3]={0,0,0}; #endif float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }; float max_pos[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; +bool axis_known_position[3] = {false, false, false}; // Extruder offset #if EXTRUDERS > 1 @@ -949,16 +951,11 @@ static void homeaxis(int axis) { current_position[axis] = 0; plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + // Engage Servo endstop if enabled #ifdef SERVO_ENDSTOPS #if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0) if (axis==Z_AXIS) { - #if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0) - destination[axis] = Z_RAISE_BEFORE_HOMING * axis_home_dir * (-1); // Set destination away from bed - feedrate = max_feedrate[axis]; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder); - st_synchronize(); - #endif engage_z_probe(); } else @@ -1000,6 +997,7 @@ static void homeaxis(int axis) { destination[axis] = current_position[axis]; feedrate = 0.0; endstops_hit_on_purpose(); + axis_known_position[axis] = true; // Retract Servo endstop if enabled #ifdef SERVO_ENDSTOPS @@ -1208,12 +1206,6 @@ void process_commands() HOMEAXIS(Y); } - #if Z_HOME_DIR < 0 // If homing towards BED do Z last - if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { - HOMEAXIS(Z); - } - #endif - if(code_seen(axis_codes[X_AXIS])) { if(code_value_long() != 0) { @@ -1226,14 +1218,74 @@ void process_commands() current_position[Y_AXIS]=code_value()+add_homeing[1]; } } + + #if Z_HOME_DIR < 0 // If homing towards BED do Z last + #ifndef Z_SAFE_HOMING + if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { + #if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0) + destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1); // Set destination away from bed + feedrate = max_feedrate[Z_AXIS]; + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder); + st_synchronize(); + #endif + HOMEAXIS(Z); + } + #else // Z Safe mode activated. + if(home_all_axis) { + destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER); + destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER); + destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1); // Set destination away from bed + feedrate = XY_TRAVEL_SPEED; + current_position[Z_AXIS] = 0; + + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder); + st_synchronize(); + current_position[X_AXIS] = destination[X_AXIS]; + current_position[Y_AXIS] = destination[Y_AXIS]; + HOMEAXIS(Z); + } + // Let's see if X and Y are homed and probe is inside bed area. + if(code_seen(axis_codes[Z_AXIS])) { + if ( (axis_known_position[X_AXIS]) && (axis_known_position[Y_AXIS]) \ + && (current_position[X_AXIS]+X_PROBE_OFFSET_FROM_EXTRUDER >= X_MIN_POS) \ + && (current_position[X_AXIS]+X_PROBE_OFFSET_FROM_EXTRUDER <= X_MAX_POS) \ + && (current_position[Y_AXIS]+Y_PROBE_OFFSET_FROM_EXTRUDER >= Y_MIN_POS) \ + && (current_position[Y_AXIS]+Y_PROBE_OFFSET_FROM_EXTRUDER <= Y_MAX_POS)) { + + current_position[Z_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1); // Set destination away from bed + feedrate = max_feedrate[Z_AXIS]; + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder); + st_synchronize(); + + HOMEAXIS(Z); + } else if (!((axis_known_position[X_AXIS]) && (axis_known_position[Y_AXIS]))) { + LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN); + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN); + } else { + LCD_MESSAGEPGM(MSG_ZPROBE_OUT); + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM(MSG_ZPROBE_OUT); + } + } + #endif + #endif + + + if(code_seen(axis_codes[Z_AXIS])) { if(code_value_long() != 0) { current_position[Z_AXIS]=code_value()+add_homeing[2]; } } #ifdef ENABLE_AUTO_BED_LEVELING - current_position[Z_AXIS] -= Z_PROBE_OFFSET_FROM_EXTRUDER; //Add Z_Probe offset (the distance is negative) + if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { + current_position[Z_AXIS] -= Z_PROBE_OFFSET_FROM_EXTRUDER; //Add Z_Probe offset (the distance is negative) + } #endif plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); #endif // else DELTA @@ -1275,9 +1327,9 @@ void process_commands() do_blocking_move_to(LEFT_PROBE_BED_POSITION - X_PROBE_OFFSET_FROM_EXTRUDER, BACK_PROBE_BED_POSITION - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]); engage_z_probe(); // Engage Z Servo endstop if available - run_z_probe(); float z_at_xLeft_yBack = current_position[Z_AXIS]; + retract_z_probe(); SERIAL_PROTOCOLPGM("Bed x: "); SERIAL_PROTOCOL(LEFT_PROBE_BED_POSITION); @@ -1290,9 +1342,12 @@ void process_commands() // prob 2 do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS); do_blocking_move_to(LEFT_PROBE_BED_POSITION - X_PROBE_OFFSET_FROM_EXTRUDER, FRONT_PROBE_BED_POSITION - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]); + + engage_z_probe(); // Engage Z Servo endstop if available run_z_probe(); float z_at_xLeft_yFront = current_position[Z_AXIS]; - + retract_z_probe(); + SERIAL_PROTOCOLPGM("Bed x: "); SERIAL_PROTOCOL(LEFT_PROBE_BED_POSITION); SERIAL_PROTOCOLPGM(" y: "); @@ -1305,9 +1360,12 @@ void process_commands() do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS); // the current position will be updated by the blocking move so the head will not lower on this next call. do_blocking_move_to(RIGHT_PROBE_BED_POSITION - X_PROBE_OFFSET_FROM_EXTRUDER, FRONT_PROBE_BED_POSITION - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]); + + engage_z_probe(); // Engage Z Servo endstop if available run_z_probe(); float z_at_xRight_yFront = current_position[Z_AXIS]; - + retract_z_probe(); // Retract Z Servo endstop if available + SERIAL_PROTOCOLPGM("Bed x: "); SERIAL_PROTOCOL(RIGHT_PROBE_BED_POSITION); SERIAL_PROTOCOLPGM(" y: "); @@ -1320,8 +1378,6 @@ void process_commands() set_bed_level_equation(z_at_xLeft_yFront, z_at_xRight_yFront, z_at_xLeft_yBack); - retract_z_probe(); // Retract Z Servo endstop if available - st_synchronize(); // The following code correct the Z height difference from z-probe position and hotend tip position. diff --git a/Marlin/language.h b/Marlin/language.h index 5ebbd3fa14..48cd4118a0 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -136,6 +136,8 @@ #define MSG_FILAMENTCHANGE "Change filament" #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages @@ -301,6 +303,8 @@ #define MSG_FILAMENTCHANGE "Change filament" #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages @@ -465,6 +469,8 @@ #define MSG_FILAMENTCHANGE "Changer filament" #define MSG_INIT_SDCARD "Init. la carte SD" #define MSG_CNG_SDCARD "Changer de carte SD" + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages @@ -632,6 +638,8 @@ #define MSG_FILAMENTCHANGE "Filament wechseln" #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages @@ -803,6 +811,8 @@ #define MSG_RETRACT_ARROW "Retraer" #define MSG_PART_RELEASE "Desacople Parcial" #define MSG_STEPPER_RELEASED "Desacoplada." + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages @@ -964,6 +974,8 @@ #define MSG_FILAMENTCHANGE "Change filament" #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages @@ -1125,6 +1137,8 @@ #define MSG_FILAMENTCHANGE "Cambia filamento" #define MSG_INIT_SDCARD "Iniz. SD-Card" #define MSG_CNG_SDCARD "Cambia SD-Card" + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages @@ -1295,6 +1309,8 @@ #define MSG_FILAMENTCHANGE "Change filament" #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "Sonda fora da mesa" + #define MSG_POSITION_UNKNOWN "Home X/Y antes de Z" // Serial Console Messages @@ -1461,6 +1477,8 @@ #define MSG_FILAMENTCHANGE "Change filament" #define MSG_INIT_SDCARD "Init. SD-Card" #define MSG_CNG_SDCARD "Change SD-Card" + #define MSG_ZPROBE_OUT "ZProbe Outside Bed" + #define MSG_POSITION_UNKNOWN "Home X/Y before Z" // Serial Console Messages