Question on Homing with Marlin

Ok, Hopefully someone knows a quick-fix for this (as I’m about to pull my hair out!)…

I’m using Marlin (Ryan’s pre-configured version based on 414 2.0-bugfix) on a Mega2560 with Ramps v1.4, also RepetierHost on a PC (although I don’t think repetier comes into play with this issue). I have endstop switches on min-X, min-Y and max-Z. Marlin configuration files have been updated to reflect changes specific to my build (correctly? maybe not?).
Anyway, when I do a Home for all axis (G28) the gantry moves up to bump against the max-Z switch, then homes X, then Y - all just like I would expect (double bumps, gantry left with all 3 switches activated). However, Marlin reports the final coordinates as X=0, Y=0, Z=5.
If I home only the Z-axis (G28 Z0) the Z axis homes as expected and coordinates are reported with Z=0.
I cannot figure out where the Z=5 is coming from on the parameterless G28?

I’m doing a compare of the original conf files to what I have now and will post the diffs in a few minutes…

I thought the Z position when homing upward came from Z_MAX_POS but I can’t understand why it would be different between G28 and G28 Z. Then there is also the homing offset M206, maybe is applied only for global home but not for single axis?

Diffs in Marlin Configuration.h:

  1. Uncommented #define USE_ZMAX_PLUG
  2. I set Z_MAX_ENDSTOP_INVERTING true
  3. *_DRIVER_TYPE were all commented out (to revert to A4988 drivers, which are what I have)
  4. DEFAULT_AXIS_STPES_PER_UNIT (100, 100, 400, 100) (to account for 16 microsteps for A4988 drivers)
  5. Commented out #define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN
  6. Uncommented #define FIX_MOUNTED_PROBE (I’m using probing to detect work surface)
  7. Changed NOZZLE_TO_PROBE_OFFSET to {0, 0, 0}
  8. Changed MIN_PROBR_EDGE to 0
  9. Uncommented #define MULTIPLE_PROBING 2
  10. #define Z_HOME_DIR 1 (home upwards)
  11. #define X_BED_SIZE 455
  12. #define Y_BED_SIZE 300
  13. #define Z_MIN_POS -75
  14. #define Z_MAX_POS 0
  15. Uncommented #define MANUAL_(X,Y & Z)_HOME_POS 0

In Configuration_adv.h I changed:

  1. uncommented #define G38_PROBE_TARGET

Thoughts?

M206 reports offsets are 0, 0, 0

I managed to track down where the Z=5 after homing was coming from… Since I’m homing to Z-max when G28 is executed by marlin it will home Z first (moving to the endstop, and setting Z to Z_MAX_POS (0 in my case). Then it moves to home X, and it tries to move the Z-axis up to Z_HOMING_HEIGHT, which is set from Z_CLEARANCE_BETWEEN_PROBES if that is defined (which it was for me, and it was 5). So marlin is trying to move Z to 5, which is above the endstop. Since the endstops are enabled (because we’re in the middle of a homing operation) the move does not happen - but the current position for Z is updated anyway (to 5). Once the X and Y homing operations are complete, the current coordinates are set to (0, 0, 5) - even though the head is physically at (0, 0, 0).

I tried undefining Z_CLEARANCE_BETWEEN_PROBES and that does resolve this issue, but introduces a new one. Now when X or Y are homed the Z position is not moved at all (because Z_HOME_HEIGHT is now zero). The code in G28 looks incorrect to me, in that if the Z_HOMING_HEIGHT is non-zero it looks like it will attempt to go there first, but if zero it doesn’t.

One of the goals with my current setup was to make accidentally requesting a home of the Z-axis “safe” (not plunge the bit into the table/workpiece, and not run it up off the rails either). I think I’m going to give up on my current approach of trying to Home to Z-max and just live with requesting a home of the Z-axis being a no-go. I’ll leave the Z-max endstop configured so that if I ever need to I can still go “all the way up” without running off the rails…

1 Like

Can you just set Z_MAX_POS to 5?

1 Like

I don’t think it’s the Z_MAX_POS being zero that’s ‘confusing’ marlin - I’m pretty sure it’s the value that it infers for Z_HOME_HEIGHT (from Z_CLEARANCE_BETWEEN_PROBES) being zero. The code in G28.cpp which I believe is in error is:

if (z_homing_height && (doX || doY)) {
  // Raise Z before homing any other axes and z is not already high enough (never lower z)
  destination.z = z_homing_height;
  if (destination.z > current_position.z) {
    if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) to ", destination.z);
    do_blocking_move_to_z(destination.z);
  }
}

I think it should be this instead:

if  (doX || doY) {
  // Raise Z before homing any other axes and z is not already high enough (never lower z)
  if (z_homing_height > current_position.z) {
    destination.z = z_homing_height;
    if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) to ", destination.z);
    do_blocking_move_to_z(destination.z);
  }
}

I may try that before giving up entirely on my approach, but I hate having to hack (supposedly working) code to get it to behave correctly…

It definitely feels like this thread of code is highly suspect, as the config value Z_CLEARANCE_BETWEEN_PROBES sounds like it should be a delta value (as opposed to an absolute position). But in Conditionals_post.h Z_HOMING_HEIGHT (which sounds like it should be an absolute position) is set from it. Then, in the code posted above, the if statement is conditional on Z_HOMING_HEIGHT not being zero – which just seems wrong…

It looks like I could probably get away with defining Z_HOMING_HEIGHT directly. But since I would want it to be zero, I would still have to modify the G28 code as described above).

Again, I may give it a shot…

I think you are right, that section of code seems fishy, especially if it sets destination.z and doesn’t act on it right away.

I think Jeffe was not speaking of a fix per se but a workaround. If z max were some positive number at least as large as the clearance then it can go to Z homing height without any other issues.

Also the soft stop behavior at the limits is not quite what I would have hoped. I would probabpy prefer if it retained the position where the endstop was hit instead of thinking it went beyond. If movement stops and it thinks it goes beyond, then the job is essentially guaranteed to be ruined.

I think it means G38.2 is really the only way to hit a stop and not mess everyhing up.

I was really saying, if you home to zmax, who cares where Marlin thinks you are? Your goals were:

As a bonus, I would home Z just to get it out of the way.

You can do all that, and then still probe Z? Sounds like a good solution to me.

1 Like

Agreed. Seems like with the current behavior it would almost be better if the firmware just panicked and terminated the job when an unexpected endstop trigger occurred. I get the impression though that false-positive endstop triggers either were or are fairly common in the 3D printer designs out there, and suspect a trade-off may have been made to presume that unexpected triggers were more likely to be false-positives than true triggers.

But if that were the case I could just live with the current behavior (Zmax set at 0, on G28 marlin believes it’s left Z at 5). I think setting Zmax to 5 would just leave me in the situation where marlin thinks it’s at 10, but it’s really at 5 (new Zmax)…

No, I think it is looking for clearance above Z=0, not clearance above the home position. Lets say you set an odd number like Z_MAX_POS = 9. Then when you home upward it associates the endstop position with Z = 9. Then when it looks for at least 5 mm clearance above Z=0 it already has clearance so no problem.

Or let’s say you home Z and then move down to Z=0, which is now 9mm below the endstop. Then if you home XY it should move up to Z=5 (no issue) and home X and Y.

Ah - yes, gotcha. It’s trying to move directly to Z=5, not Home+5.

I set Z_MAX_POS, Z_CLEARANCE_BETWEEN_PROBES and Z_CLEARANCE_MULTI_PROBES to 5. Left Z_AFTER_PROBING undefined, and commented out my defines of MANUAL_XYZ_HOME_POS. Did not make any changes to the (buggy!) G28 code.

Results were as you (@Jeffeb3) predicted - I can home all axis (Z is still homing upwards) and Both marlin and repetier agree the final position is (0, 0, 5). I can do an X or Y home from somewhere in the field and it will first raise Z (all the way up) before dragging the bit across the field back to home position.
I can also still use G38.2 Z-80 to probe down to a touch-plate (using Zmin endstop pins) for finding top of work piece.

So I’m pretty happy with this setup. It lets me achieve all my goals for the endstops and touchplate:

  1. Ability to sync marlin and repetier coordinates if repetier gets out-of-sync with marlin (can always rehome, then reposition to project origina and G92/@isathome from there)
  2. Use touch plate for finding top of work surface (using G38.2 Z-80 and G92)
  3. Ability to accurately re-find project origin after tool change or power loss (as long as offset coordinates from Home position where recorded on original setup)
  4. Have a tool change process that allows either repetier controlled motion or manual motion of gantry with steppers powered off. (can rehome after tool change and reset project origin)
  5. Ability to @pause repetier on tool change to allow manual position changes (to allow access for tool change)
  6. Accidental homing should be “safe”.
    6.1 Homing Z should not plunge into work
    6.2 Homing XY should attempt to lift cutter out of work piece
  7. Ability to pause carve, move tool up/down (at least) to provide clearance for adjusting dust boot, then resume program where it left off (head should automatically return to where it was and continue)
  8. Ability to script a “fool proof” tool change (either mid program or as separate jobs)
1 Like

I think you’re way ahead of the pack here. Very compelling setup, for sure. If you wanted, posting a git diff (if you know what that means) or just sharing the configuration/adv so when someone finds this post in three months, they will have the exact settings to change.

1 Like

Great setup. One more thing I would offer is the possibility of work offsets (G54, G55, etc.). After jogging and probing your workpiece you can change into a work coordinate system before doing G92. Then if you want to go to an absolute machine location to do a tool change say, you can switch back to machine coordinates to move to your tool change place, then go back to workpiece coordinates to resume work. You might not be able to probe again, or you might not want to.

This was instrumental for my auto tool changer because the tools were at fixed machine locations but the workpiece wasn’t.

Is there a specific git repo/branch that corresponds to the MPCNC_Ramps_T8_16T_LCD_32step build?

(I just pulled and unzipped that build, then started updating locally from there) I would definitely prefer something I could fork, branch and manage my local changes in…

It is the same named branch, on Ryan’s github.

His may have moved forward, because he sometimes doesn’t release the .zip.

Ok - Duh… I missed the “view more active branches” link. :man_facepalming:
Thanks!

Diffs of my config files attached…
Kizmit99Config.zip (2.2 KB)

Hardware wise I used MakerBot v1.2 mechanical endstops on Xmin, Ymin and Zmax, wired to the corresponding connectors on the Ramps board.
I used a simple touchplate that looks like this:

wired to the Ramps Zmin endstop connector.

Overall a pretty simple setup - once you get past exactly which bits of the marlin configs are needed, and which aren’t…

1 Like