diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 79e091dc51de0dc99cbc076a5d3055586d0fdfd9..b4e19d90d1efe40f570807eda58d6a0a16568d19 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 "(none, default config)" // Who made the changes.
+#define STRING_CONFIG_H_AUTHOR "Bob Kuhn, G2/G3 radius testing" // 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,24 +105,15 @@
 //#define SHOW_CUSTOM_BOOTSCREEN
 // @section machine
 
-/**
- * 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]
- */
+// 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]
 #define SERIAL_PORT 0
 
-#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]
- */
+// This determines the communication speed of the printer
+// :[2400,9600,19200,38400,57600,115200,250000]
+#define BAUDRATE 115200
 
 // Enable the Bluetooth serial interface on AT90USB devices
 //#define BLUETOOTH
@@ -130,7 +121,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_RAMPS_14_EFB
+  #define MOTHERBOARD BOARD_AZTEEG_X3_PRO     
 #endif
 
 // Optional custom name for your RepStrap or other custom machine
@@ -178,22 +169,14 @@
 //#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
 
-/**
- * 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
+//// 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
 
-#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
+// 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
 
 // @section temperature
 
@@ -239,10 +222,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 1
+#define TEMP_SENSOR_0 998
 #define TEMP_SENSOR_1 0
 #define TEMP_SENSOR_2 0
 #define TEMP_SENSOR_3 0
@@ -372,9 +355,8 @@
 #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 200
+#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH)
 
 //===========================================================================
 //======================== Thermal Runaway Protection =======================
@@ -421,9 +403,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
@@ -440,13 +422,13 @@
 #endif
 
 // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
-#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.
+#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.
 
 
 //=============================================================================
@@ -454,56 +436,20 @@
 //=============================================================================
 // @section motion
 
-/**
- * Default Settings
- *
- * These settings can be reset by M502
- *
- * Note that if EEPROM is enabled, saved values will override these.
- */
-
-/**
- * Default Axis Steps Per Unit (steps/mm)
- * Override with M92
- */
-#define DEFAULT_AXIS_STEPS_PER_UNIT   { 80, 80, 4000, 500 }
-
-/**
- * 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 }
+#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 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
+#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
 
-/**
- * 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
+// "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)
 
 
 //===========================================================================
@@ -528,7 +474,6 @@
 //#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.
@@ -665,9 +610,9 @@
 // @section machine
 
 // Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
-#define INVERT_X_DIR false
-#define INVERT_Y_DIR true
-#define INVERT_Z_DIR false
+#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
 
 // @section extruder
 
@@ -695,12 +640,12 @@
 // @section machine
 
 // Travel limits after homing (units are in mm)
-#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
+#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
 
 //===========================================================================
 //========================= Filament Runout Sensor ==========================
@@ -1060,7 +1005,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
@@ -1077,7 +1022,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 ceec7e69ba773fe032a066e0220b25014045f182..751da7fb828e2e2fb1bb360110c813049f434a2b 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 true
+  #define INVERT_Y2_VS_Y_DIR false
 #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)
 
diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 1daefe76231eb69a2c030f8d91cb57d5cf696bc2..bebc91cf89634e5880993dea8c15b5483d7e9f33 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -209,6 +209,12 @@ 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
+#endif
+
 /**
  * The axis order in all axis related arrays is X, Y, Z, E
  */
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index f334341061a3fa93cf5c0dc775da53337615163e..98993c8ccf7750a156566c4badb4abc95b81822f 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -117,6 +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
  * G90 - Use Absolute Coordinates
  * G91 - Use Relative Coordinates
  * G92 - Set current position to coordinates given
@@ -276,6 +277,11 @@
   TWIBus i2c;
 #endif
 
+#ifdef G38_2_3
+bool G38_flag = false;   // init G38 flags
+bool G38_flag_pass = false;
+#endif
+
 bool Running = true;
 
 uint8_t marlin_debug_flags = DEBUG_NONE;
@@ -2325,6 +2331,146 @@ 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
  */
@@ -4160,6 +4306,26 @@ 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
+
+
 /**
  * G92: Set current position to given X Y Z E
  */
@@ -7287,6 +7453,11 @@ void process_next_command() {
   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');
@@ -7393,6 +7564,12 @@ 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);
+          break;
+	 #endif
+ 
       case 90: // G90
         relative_mode = false;
         break;
diff --git a/Marlin/endstops.cpp b/Marlin/endstops.cpp
index 1c50eb649233e6f7a6a3c63888ced6791afb421f..348d8edb65b2946f981a823cccdf972750a31102 100644
--- a/Marlin/endstops.cpp
+++ b/Marlin/endstops.cpp
@@ -243,6 +243,24 @@ 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 { \
+      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;\
+        } \
+      } \
+    } 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) { \
@@ -250,6 +268,8 @@ void Endstops::update() {
         stepper.endstop_triggered(_AXIS(AXIS)); \
       } \
     } while(0)
+	
+#endif	  		
 
   #if ENABLED(COREXY) || ENABLED(COREXZ)
     // Head direction in -X axis for CoreXY and CoreXZ bots.