From a2864ab7fe766372783d64b35f13ef984ab660c1 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 26 Sep 2016 01:30:34 -0500 Subject: [PATCH] Patched up, cleaned up --- Marlin/Configuration.h | 159 ++++++++++++++------- Marlin/Configuration_adv.h | 12 +- Marlin/Marlin.h | 7 +- Marlin/Marlin_main.cpp | 286 +++++++++++++++---------------------- Marlin/SanityCheck.h | 11 ++ Marlin/endstops.cpp | 36 ++--- 6 files changed, 257 insertions(+), 254 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index b4e19d90d1..79e091dc51 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -86,7 +86,7 @@ // User-specified version info of this build to display in [Pronterface, etc] terminal window during // startup. Implementation of an idea by Prof Braino to inform user that any changes made to this // build by the user have been successfully uploaded into firmware. -#define STRING_CONFIG_H_AUTHOR "Bob Kuhn, G2/G3 radius testing" // Who made the changes. +#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. #define SHOW_BOOTSCREEN #define STRING_SPLASH_LINE1 SHORT_BUILD_VERSION // will be shown during bootup in line 1 #define STRING_SPLASH_LINE2 WEBSITE_URL // will be shown during bootup in line 2 @@ -105,15 +105,24 @@ //#define SHOW_CUSTOM_BOOTSCREEN // @section machine -// SERIAL_PORT selects which serial port should be used for communication with the host. -// This allows the connection of wireless adapters (for instance) to non-default port pins. -// Serial port 0 is still used by the Arduino bootloader regardless of this setting. -// :[0,1,2,3,4,5,6,7] +/** + * Select which serial port on the board will be used for communication with the host. + * This allows the connection of wireless adapters (for instance) to non-default port pins. + * Serial port 0 is always used by the Arduino bootloader regardless of this setting. + * + * :[0,1,2,3,4,5,6,7] + */ #define SERIAL_PORT 0 -// This determines the communication speed of the printer -// :[2400,9600,19200,38400,57600,115200,250000] -#define BAUDRATE 115200 +#define BAUDRATE 250000 +/** + * This setting determines the communication speed of the printer. + * + * 250000 works in most cases, but you might try a lower speed if + * you commonly experience drop-outs during host printing. + * + * :[2400,9600,19200,38400,57600,115200,250000] + */ // Enable the Bluetooth serial interface on AT90USB devices //#define BLUETOOTH @@ -121,7 +130,7 @@ // The following define selects which electronics board you have. // Please choose the name from boards.h that matches your setup #ifndef MOTHERBOARD - #define MOTHERBOARD BOARD_AZTEEG_X3_PRO + #define MOTHERBOARD BOARD_RAMPS_14_EFB #endif // Optional custom name for your RepStrap or other custom machine @@ -169,14 +178,22 @@ //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis //#define HOTEND_OFFSET_Y {0.0, 5.00} // (in mm) for each extruder, offset of the hotend on the Y axis -//// The following define selects which power supply you have. Please choose the one that matches your setup -// 1 = ATX -// 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) -// :{1:'ATX',2:'X-Box 360'} -#define POWER_SUPPLY 1 +/** + * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN + * + * 0 = No Power Switch + * 1 = ATX + * 2 = X-Box 360 203Watts (the blue wire connected to PS_ON and the red wire to VCC) + * + * :{0:'No power switch',1:'ATX',2:'X-Box 360'} + */ +#define POWER_SUPPLY 0 -// Define this to have the electronics keep the power supply off on startup. If you don't know what this is leave it. -//#define PS_DEFAULT_OFF +#if POWER_SUPPLY > 0 + // Enable this option to leave the PSU off at startup. + // Power to steppers and heaters will need to be turned on with M80. + //#define PS_DEFAULT_OFF +#endif // @section temperature @@ -222,10 +239,10 @@ // 110 is Pt100 with 1k pullup (non standard) // 998 and 999 are Dummy Tables. They will ALWAYS read 25°C or the temperature defined below. // Use it for Testing or Development purposes. NEVER for production machine. -#define DUMMY_THERMISTOR_998_VALUE 25 +//#define DUMMY_THERMISTOR_998_VALUE 25 //#define DUMMY_THERMISTOR_999_VALUE 100 // :{ '0': "Not used",'1':"100k / 4.7k - EPCOS",'2':"200k / 4.7k - ATC Semitec 204GT-2",'3':"Mendel-parts / 4.7k",'4':"10k !! do not use for a hotend. Bad resolution at high temp. !!",'5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)",'6':"100k / 4.7k EPCOS - Not as accurate as Table 1",'7':"100k / 4.7k Honeywell 135-104LAG-J01",'8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT",'9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1",'10':"100k / 4.7k RS 198-961",'11':"100k / 4.7k beta 3950 1%",'12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)",'13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'",'20':"PT100 (Ultimainboard V2.x)",'51':"100k / 1k - EPCOS",'52':"200k / 1k - ATC Semitec 204GT-2",'55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)",'60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950",'66':"Dyze Design 4.7M High Temperature thermistor",'70':"the 100K thermistor found in the bq Hephestos 2",'71':"100k / 4.7k Honeywell 135-104LAF-J01",'147':"Pt100 / 4.7k",'1047':"Pt1000 / 4.7k",'110':"Pt100 / 1k (non-standard)",'1010':"Pt1000 / 1k (non standard)",'-3':"Thermocouple + MAX31855 (only for sensor 0)",'-2':"Thermocouple + MAX6675 (only for sensor 0)",'-1':"Thermocouple + AD595",'998':"Dummy 1",'999':"Dummy 2" } -#define TEMP_SENSOR_0 998 +#define TEMP_SENSOR_0 1 #define TEMP_SENSOR_1 0 #define TEMP_SENSOR_2 0 #define TEMP_SENSOR_3 0 @@ -355,8 +372,9 @@ #define EXTRUDE_MINTEMP 170 // This option prevents a single extrusion longer than EXTRUDE_MAXLENGTH. +// Note that for Bowden Extruders a too-small value here may prevent loading. #define PREVENT_LENGTHY_EXTRUDE -#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) +#define EXTRUDE_MAXLENGTH 200 //=========================================================================== //======================== Thermal Runaway Protection ======================= @@ -403,9 +421,9 @@ #define USE_XMIN_PLUG #define USE_YMIN_PLUG #define USE_ZMIN_PLUG -#define USE_XMAX_PLUG -#define USE_YMAX_PLUG -#define USE_ZMAX_PLUG +//#define USE_XMAX_PLUG +//#define USE_YMAX_PLUG +//#define USE_ZMAX_PLUG // coarse Endstop Settings #define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors @@ -422,13 +440,13 @@ #endif // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). -#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. -#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. -#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. -#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. -#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. -#define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. -#define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +#define X_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define X_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Y_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. //============================================================================= @@ -436,20 +454,56 @@ //============================================================================= // @section motion -#define DEFAULT_AXIS_STEPS_PER_UNIT {8*24.8139,8*24.8139,8*24.8139,100} -#define DEFAULT_MAX_FEEDRATE {35, 35, 25, 25} // (mm/sec) -#define DEFAULT_MAX_ACCELERATION {3000,3000,100,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for Skeinforge 40+, for older versions raise them a lot. +/** + * Default Settings + * + * These settings can be reset by M502 + * + * Note that if EEPROM is enabled, saved values will override these. + */ -#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration in mm/s^2 for printing moves -#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration in mm/s^2 for retracts -#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration in mm/s^2 for travel (non printing) moves +/** + * Default Axis Steps Per Unit (steps/mm) + * Override with M92 + */ +#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 4000, 500 } -// "Jerk" specifies the minimum speed change that requires acceleration. -// When changing speed and direction, if the difference is less than the -// value set here, it may happen instantaneously. -#define DEFAULT_XYJERK 20.0 // (mm/sec) -#define DEFAULT_ZJERK 0.4 // (mm/sec) -#define DEFAULT_EJERK 5.0 // (mm/sec) +/** + * Default Max Feed Rate (mm/s) + * Override with M203 + */ +#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 } + +/** + * Default Max Acceleration (change/s) change = mm/s + * Override with M201 + * + * Maximum start speed for accelerated moves: { X, Y, Z, E } + */ +#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } + +/** + * Default Acceleration (change/s) change = mm/s + * Override with M204 + * + * M204 P Acceleration + * M204 R Retract Acceleration + * M204 T Travel Acceleration + */ +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts +#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves + +/** + * Defult Jerk (mm/s) + * + * "Jerk" specifies the minimum speed change that requires acceleration. + * When changing speed and direction, if the difference is less than the + * value set here, it may happen instantaneously. + */ +#define DEFAULT_XYJERK 20.0 +#define DEFAULT_ZJERK 0.4 +#define DEFAULT_EJERK 5.0 //=========================================================================== @@ -474,6 +528,7 @@ //#define FIX_MOUNTED_PROBE // The BLTouch probe emulates a servo probe. +// The default connector is SERVO 0. Set Z_ENDSTOP_SERVO_NR below to override. //#define BLTOUCH // Z Servo Probe, such as an endstop switch on a rotating arm. @@ -610,9 +665,9 @@ // @section machine // Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. -#define INVERT_X_DIR true // positive is away from the motor -#define INVERT_Y_DIR false // positive is towards the motor -#define INVERT_Z_DIR true // positive is away from the motor +#define INVERT_X_DIR false +#define INVERT_Y_DIR true +#define INVERT_Z_DIR false // @section extruder @@ -640,12 +695,12 @@ // @section machine // Travel limits after homing (units are in mm) -#define X_MIN_POS -100 -#define Y_MIN_POS -100 -#define Z_MIN_POS -100 -#define X_MAX_POS 375 -#define Y_MAX_POS 450 -#define Z_MAX_POS 450 +#define X_MIN_POS 0 +#define Y_MIN_POS 0 +#define Z_MIN_POS 0 +#define X_MAX_POS 200 +#define Y_MAX_POS 200 +#define Z_MAX_POS 200 //=========================================================================== //========================= Filament Runout Sensor ========================== @@ -1005,7 +1060,7 @@ // SD Card support is disabled by default. If your controller has an SD slot, // you must uncomment the following option or it won't work. // -#define SDSUPPORT +//#define SDSUPPORT // // SD CARD: SPI SPEED @@ -1022,7 +1077,7 @@ // // Use CRC checks and retries on the SD communication. // -#define SD_CHECK_AND_RETRY +//#define SD_CHECK_AND_RETRY // // ENCODER SETTINGS diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 751da7fb82..545f5ce8bd 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -244,16 +244,16 @@ // Dual Y Steppers // Uncomment this option to drive two Y axis motors. // The next unused E driver will be assigned to the second Y stepper. -#define Y_DUAL_STEPPER_DRIVERS +//#define Y_DUAL_STEPPER_DRIVERS #if ENABLED(Y_DUAL_STEPPER_DRIVERS) // Set true if the two Y motors need to rotate in opposite directions - #define INVERT_Y2_VS_Y_DIR false + #define INVERT_Y2_VS_Y_DIR true #endif // A single Z stepper driver is usually used to drive 2 stepper motors. // Uncomment this option to use a separate stepper driver for each Z axis motor. // The next unused E driver will be assigned to the second Z stepper. -#define Z_DUAL_STEPPER_DRIVERS +//#define Z_DUAL_STEPPER_DRIVERS #if ENABLED(Z_DUAL_STEPPER_DRIVERS) @@ -532,6 +532,12 @@ // Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes. //#define BEZIER_CURVE_SUPPORT +// G38 Probe Target +//#define G38_2_3 +#if ENABLED(G38_2_3) + #define G38_MINIMUM_MOVE 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) +#endif + // Moves (or segments) with fewer steps than this will be joined with the next move #define MIN_STEPS_PER_SEGMENT 6 diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index bebc91cf89..8fd720cd4d 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -209,10 +209,9 @@ void manage_inactivity(bool ignore_stepper_queue = false); #endif // !MIXING_EXTRUDER -#define G38_2_3 -#ifdef G38_2_3 -extern bool G38_flag ; //flag to tell the interrupt handler that a G38 command is being run -extern bool G38_flag_pass ; //flag from the interrupt handler to indicate if the endstop went active +#if ENABLED(G38_2_3) + extern bool G38_move, // flag to tell the interrupt handler that a G38 command is being run + G38_endstop_hit; // flag from the interrupt handler to indicate if the endstop went active #endif /** diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 98993c8ccf..cadb169402 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -117,7 +117,7 @@ * G30 - Single Z probe, probes bed at current XY location. * G31 - Dock sled (Z_PROBE_SLED only) * G32 - Undock sled (Z_PROBE_SLED only) - * G38 - Probe target - similar to G28 except it uses the Z_Probe for all three axis + * G38 - Probe target - similar to G28 except it uses the Z_MIN endstop for all three axes * G90 - Use Absolute Coordinates * G91 - Use Relative Coordinates * G92 - Set current position to coordinates given @@ -277,9 +277,9 @@ TWIBus i2c; #endif -#ifdef G38_2_3 -bool G38_flag = false; // init G38 flags -bool G38_flag_pass = false; +#if ENABLED(G38_2_3) + bool G38_move = false, + G38_endstop_hit = false; #endif bool Running = true; @@ -1343,7 +1343,7 @@ static void set_home_offset(AxisEnum axis, float v) { * SCARA should wait until all XY homing is done before setting the XY * current_position to home, because neither X nor Y is at home until * both are at home. Z can however be homed individually. - * + * */ static void set_axis_is_at_home(AxisEnum axis) { #if ENABLED(DEBUG_LEVELING_FEATURE) @@ -2331,146 +2331,6 @@ static void clean_up_after_endstop_or_probe_move() { #endif // AUTO_BED_LEVELING_BILINEAR - -#ifdef G38_2_3 - -#define G38_minimum_move 0.0275 // minimum distance in mm that will produce a move (determined using the print statement in check_move) - -bool check_move() //checks that at least one of the axis in the command line has an actual move - // motion planner only does moves of 0.001mm and larger -{ - - bool move_flag = false; - for(int8_t i=0; i < 3; i++) { -/* debug used to determine prints - SERIAL_PROTOCOLPGM("axis: "); - SERIAL_PROTOCOL(axis_codes[i]); - SERIAL_PROTOCOLPGM(" code_seen : "); - SERIAL_PROTOCOL(code_seen(axis_codes[i])); - SERIAL_PROTOCOLPGM(" destination : "); - SERIAL_PROTOCOL(destination[i]); - SERIAL_PROTOCOLPGM(" current : "); - SERIAL_PROTOCOL(current_position[i]); - SERIAL_PROTOCOLPGM(" dif x 1000 : "); - SERIAL_PROTOCOLLN((destination[i] - current_position[i]) * 1000); - */ - if (code_seen(axis_codes[i]) && (fabs(destination[i] - current_position[i]) >= G38_minimum_move)) move_flag = true ; -/* - ?? 0.0275mm produced a move on my machine along with an updated current position. - 0.0265mm did NOT produce a move and did NOT change the current position - this is very different than the 0.001 in the planner. - 0.001" is .0254mm so maybe the 0.0275 observed comes from digital storage limitations/conversion/rounding - */ - } - return move_flag; -} - - -static void G38_run_probe(bool *G38_pass_fail) { - - G38_flag = true; //tell the interrupt handler that we're doing a G38 probe - *G38_pass_fail = false; - -#ifdef X_HOME_BUMP_MM -#ifdef Y_HOME_BUMP_MM -#ifdef Z_HOME_BUMP_MM - float G38_X_retract_mm = home_bump_mm(X_AXIS); - float G38_Y_retract_mm = home_bump_mm(Y_AXIS); - float G38_Z_retract_mm = home_bump_mm(Z_AXIS); - -#else - - float G38_X_retract_mm = 5; - float G38_Y_retract_mm = 5; - float G38_Z_retract_mm = 2; - -#endif -#endif -#endif - - // only retract the axis if the axis is in the command - if( (!code_seen('X') || (code_value_axis_units(X_AXIS) == 0))) G38_X_retract_mm = 0; - if( (!code_seen('Y') || (code_value_axis_units(Y_AXIS) == 0))) G38_Y_retract_mm = 0; - if( (!code_seen('Z') || (code_value_axis_units(Z_AXIS) == 0))) G38_Z_retract_mm = 0; - - // change the direction of the retract if needed - if ((destination[X_AXIS] - current_position[X_AXIS])>0) G38_X_retract_mm = -G38_X_retract_mm; - if ((destination[Y_AXIS] - current_position[Y_AXIS])>0) G38_Y_retract_mm = -G38_Y_retract_mm; - if ((destination[Z_AXIS] - current_position[Z_AXIS])>0) G38_Z_retract_mm = -G38_Z_retract_mm; - - - stepper.synchronize(); // wait until the machine is idle - - bool save_endstops = endstops.enabled; //remember state of endstops so we can retore them at the end - endstops.enable(true); - - // move until you reach the destination or hit an endstop or hit the target - // it's an error unless have hit the target - G38_flag_pass = false; - *G38_pass_fail = false; - - planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate_mm_s, active_extruder); - stepper.synchronize(); - - // we have to let the planner know where we are right now as it is not where we said to go. - // and we need to update current_position[axis] - current_position[X_AXIS] = stepper.get_axis_position_mm(X_AXIS); - current_position[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS); - current_position[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS); - planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS] , current_position[Z_AXIS] , current_position[E_AXIS]); - - *G38_pass_fail = G38_flag_pass ; // only care if hit target on the first move - - if (*G38_pass_fail) { // no sense in doing the remaining moves if we didn't hit the endstop - // move away the retract distance - float xPosition = current_position[X_AXIS] + G38_X_retract_mm; - float yPosition = current_position[Y_AXIS] + G38_Y_retract_mm; - float zPosition = current_position[Z_AXIS] + G38_Z_retract_mm; - - - - // disable endstops on retract otherwise sometimes can't get away - endstops.enable(false); - G38_flag = false; - - planner.buffer_line(xPosition, yPosition , zPosition , current_position[E_AXIS], feedrate_mm_s/4, active_extruder); - stepper.synchronize(); - - - // move back slowly - xPosition -= G38_X_retract_mm * 2; - yPosition -= G38_Y_retract_mm * 2; - zPosition -= G38_Z_retract_mm * 2; - - - // enable endstops on move back - endstops.enable(true); - G38_flag = true; - - planner.buffer_line(xPosition, yPosition , zPosition , current_position[E_AXIS], feedrate_mm_s/4, active_extruder); - stepper.synchronize(); - - // we have to let the planner know where we are right now as it is not where we said to go. - // and we need to update current_position[axis] - current_position[X_AXIS] = stepper.get_axis_position_mm(X_AXIS); - current_position[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS); - current_position[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS); - planner.set_position_mm(current_position[X_AXIS], current_position[Y_AXIS] , current_position[Z_AXIS] , current_position[E_AXIS]); - - } - -// clean_up_after_endstop_move(); - - endstops.enable(save_endstops); //restore endstops to same state as when we started - - endstops.hit_on_purpose(); - G38_flag = false; //tell the interrupt handler that we're done - -} - -#endif //G38_2_3 - - /** * Home an individual linear axis */ @@ -4306,25 +4166,93 @@ inline void gcode_G28() { #endif // HAS_BED_PROBE -#ifdef G38_2_3 - inline void gcode_G38(float code_num) { - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) || ENABLED(Z_MIN_PROBE_ENDSTOP) //must have valid Z_MIN_PROBE definition for this command to work - if ((code_num == 38.2 || code_num == 38.3 ) && (code_seen('X') || code_seen('Y') || code_seen('Z'))) { - gcode_get_destination(); // For X Y Z E F - if (check_move()) { // see if the commanded movement will result in a physical movement - bool G38_pass_fail = false; - G38_run_probe(&G38_pass_fail); - if (!G38_pass_fail && (code_num == 38.2) ) SERIAL_PROTOCOLLNPGM(" ERROR - failed to reach target "); - } - } - } -#else - - SERIAL_PROTOCOLLNPGM(" ERROR - Z_MIN_PROBE must be enabled "); - } -#endif -#endif //G38_2_3 +#if ENABLED(G38_2_3) + static bool G38_run_probe() { + + bool G38_pass_fail = false; + + // Get direction of move and retract + float retract_mm[XYZ]; + LOOP_XYZ(i) { + float dist = destination[i] - current_position[i]; + retract_mm[i] = fabs(dist) < G38_MINIMUM_MOVE ? 0 : home_bump_mm(i) * (dist > 0 ? -1 : 1); + } + + stepper.synchronize(); // wait until the machine is idle + + // Move until destination reached or target hit + endstops.enable(true); + G38_move = true; + G38_endstop_hit = false; + prepare_move_to_destination(); + stepper.synchronize(); + G38_move = false; + + endstops.hit_on_purpose(); + set_current_from_steppers_for_axis(ALL_AXES); + SYNC_PLAN_POSITION_KINEMATIC(); + + // Only do remaining moves if target was hit + if (G38_endstop_hit) { + + G38_pass_fail = true; + + // Move away by the retract distance + set_destination_to_current(); + LOOP_XYZ(i) destination[i] += retract_mm[i]; + endstops.enable(false); + prepare_move_to_destination(); + stepper.synchronize(); + + feedrate_mm_s /= 4; + + // Bump the target more slowly + LOOP_XYZ(i) destination[i] -= retract_mm[i] * 2; + + endstops.enable(true); + G38_move = true; + prepare_move_to_destination(); + stepper.synchronize(); + G38_move = false; + + set_current_from_steppers_for_axis(ALL_AXES); + SYNC_PLAN_POSITION_KINEMATIC(); + } + + endstops.hit_on_purpose(); + endstops.not_homing(); + return G38_pass_fail; + } + + /** + * G38.2 - probe toward workpiece, stop on contact, signal error if failure + * G38.3 - probe toward workpiece, stop on contact + * + * Like G28 except uses Z min endstop for all axes + */ + inline void gcode_G38(bool is_38_2) { + // Get X Y Z E F + gcode_get_destination(); + + setup_for_endstop_or_probe_move(); + + // If any axis has enough movement, do the move + LOOP_XYZ(i) + if (fabs(destination[i] - current_position[i]) >= G38_MINIMUM_MOVE) { + if (!code_seen('F')) feedrate_mm_s = homing_feedrate_mm_s[i]; + // If G38.2 fails throw an error + if (!G38_run_probe() && is_38_2) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Failed to reach target"); + } + break; + } + + clean_up_after_endstop_or_probe_move(); + } + +#endif // G38_2_3 /** * G92: Set current position to given X Y Z E @@ -7447,23 +7375,32 @@ void process_next_command() { // Skip spaces to get the numeric part while (*cmd_ptr == ' ') cmd_ptr++; + // Allow for decimal point in command + #if ENABLED(G38_2_3) + uint8_t subcode = 0; + #endif + uint16_t codenum = 0; // define ahead of goto // Bail early if there's no code bool code_is_good = NUMERIC(*cmd_ptr); if (!code_is_good) goto ExitUnknownCommand; -#ifdef G38_2_3 - double codenum_float; - codenum_float = atof(cmd_ptr); //allow for decimal point in command -#endif - // Get and skip the code number do { codenum = (codenum * 10) + (*cmd_ptr - '0'); cmd_ptr++; } while (NUMERIC(*cmd_ptr)); + // Allow for decimal point in command + #if ENABLED(G38_2_3) + if (*cmd_ptr == '.') { + cmd_ptr++; + while (NUMERIC(*cmd_ptr)) + subcode = (subcode * 10) + (*cmd_ptr++ - '0'); + } + #endif + // Skip all spaces to get to the first argument, or nul while (*cmd_ptr == ' ') cmd_ptr++; @@ -7564,12 +7501,13 @@ void process_next_command() { #endif // Z_PROBE_SLED #endif // HAS_BED_PROBE - #ifdef G38_2_3 - case 38: //G38.2 & G38.3 - gcode_G38(codenum_float); + #if ENABLED(G38_2_3) + case 38: // G38.2 & G38.3 + if (subcode == 2 || subcode == 3) + gcode_G38(subcode == 2); break; - #endif - + #endif + case 90: // G90 relative_mode = false; break; @@ -9078,7 +9016,7 @@ void prepare_move_to_destination() { * Morgan SCARA Inverse Kinematics. Results in delta[]. * * See http://forums.reprap.org/read.php?185,283327 - * + * * Maths and first version by QHARLEY. * Integrated into Marlin and slightly restructured by Joachim Cerny. */ diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h index d14eda6356..2d6414fb27 100644 --- a/Marlin/SanityCheck.h +++ b/Marlin/SanityCheck.h @@ -851,6 +851,17 @@ #endif #endif +/** + * G38 Probe Target + */ +#if ENABLED(G38_2_3) + #if !HAS_BED_PROBE + #error "G38_2_3 requires a bed probe." + #elif !IS_CARTESIAN + #error "G38_2_3 requires a Cartesian machine." + #endif +#endif + /** * Make sure only one display is enabled * diff --git a/Marlin/endstops.cpp b/Marlin/endstops.cpp index 348d8edb65..7bb2fda71d 100644 --- a/Marlin/endstops.cpp +++ b/Marlin/endstops.cpp @@ -243,33 +243,27 @@ void Endstops::update() { // COPY_BIT: copy the value of COPY_BIT to BIT in bits #define COPY_BIT(bits, COPY_BIT, BIT) SET_BIT(bits, BIT, TEST(bits, COPY_BIT)) - -#if defined(G38_2_3) && defined(Z_MIN_PIN) && Z_MIN_PIN > -1 // If G38 command then check Z_MIN for every axis and every direction - #define UPDATE_ENDSTOP(AXIS,MINMAX) do { \ + #define _UPDATE_ENDSTOP(AXIS,MINMAX,CODE) do { \ UPDATE_ENDSTOP_BIT(AXIS, MINMAX); \ if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX)) && stepper.current_block->steps[_AXIS(AXIS)] > 0) { \ _ENDSTOP_HIT(AXIS); \ stepper.endstop_triggered(_AXIS(AXIS)); \ - } \ - if (G38_flag) {\ - UPDATE_ENDSTOP_BIT(Z, MIN); \ - if (TEST_ENDSTOP(_ENDSTOP(Z, MIN)) && stepper.current_block->steps[_AXIS(AXIS)] > 0) { \ - _ENDSTOP_HIT(AXIS); \ - stepper.endstop_triggered(_AXIS(AXIS)); \ - G38_flag_pass = true;\ - } \ + CODE; \ } \ } while(0) -#else - #define UPDATE_ENDSTOP(AXIS,MINMAX) do { \ - UPDATE_ENDSTOP_BIT(AXIS, MINMAX); \ - if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX)) && stepper.current_block->steps[_AXIS(AXIS)] > 0) { \ - _ENDSTOP_HIT(AXIS); \ - stepper.endstop_triggered(_AXIS(AXIS)); \ - } \ - } while(0) - -#endif + + #if ENABLED(G38_2_3) && PIN_EXISTS(Z_MIN) // If G38 command then check Z_MIN for every axis and every direction + + #define UPDATE_ENDSTOP(AXIS,MINMAX) do { \ + _UPDATE_ENDSTOP(AXIS,MINMAX,NOOP); \ + if (G38_move) _UPDATE_ENDSTOP(Z, MIN, G38_endstop_hit = true); \ + } while(0) + + #else + + #define UPDATE_ENDSTOP(AXIS,MINMAX) _UPDATE_ENDSTOP(AXIS,MINMAX,NOOP) + + #endif #if ENABLED(COREXY) || ENABLED(COREXZ) // Head direction in -X axis for CoreXY and CoreXZ bots.