Z homing Gcode bloody for beginners

  • Hello 🙂

    I managed to set up my Cetus MK1 with the Duet3D Maestro and am very happy with the clean setup and the quiet motor drivers – I now only hear my Noctua fan which really is a silent one!
    Anyway I'm now trying to set up the homing macro scripts and stumbling over my weak GCode knowledge. So here are some questions I hope you will answer.

    I currently have an endstop switch at the Z axis (which is pointing up in print direction) maximum position . Later on I will add a BLTouch, too. Both probes are positioned on different ends of the Z axis then: BLTouch down at the bed, Endstop up at the highest print point.

    1. With the BLTouch connected, can I still take any advantage of the existing endstop? E.g. for max z movement limiting or so?

    2. Can you recommend me any homez.g script or just the relevant commands that allow me to do multiple runs against the endstop with different speeds to find the right position? I just need a startup example.

  • Moderator

    Yes you can use both the end stop and the probe. It's totally up to you how you use them, since homing is defined in the macros you set up.

    This should get you started with the basics: https://duet3d.dozuki.com/Wiki/ConfiguringRepRapFirmwareCartesianPrinter#Section_Homing_files

    The web configurator will also provide you a complete starting config set if you go through the wizard. https://configurator.reprapfirmware.org/Start

    When you do setup the probe, this will help: https://duet3d.dozuki.com/Wiki/Connecting_a_Z_probe

  • Thank you, that helps a lot! 🙂

    Is the following process possible?

    1. Drive down z-leveling with BLTouch and setting the found position to 0 with G92
    2. Go back up to find the max position of the Z axis using the end switch setting the current position as max for z using M208

    The difficult part I'm curious about is how to use the current position as input for the M208 command. Also I still don't understand how bed mesh compensation could be integrated here. Any hint?

  • Hi.

    Short answers to both questions - yes.
    A bit longer: 1. After you connected you probe you should continue with this : https://duet3d.dozuki.com/Wiki/Test_and_calibrate_the_Z_probe. After that if all works as supposed continue with this: https://duet3d.dozuki.com/Wiki/Using_mesh_bed_compensation
    2. If you have found your Z0, then its easy to find out Zmax, just send carriage up (or bed down) to its actual max position and read value of Z in duet web control. Then edit config M208 command.

  • @aidar Thanks for the fast answer! That really helps!

    I wonder if there is an automatic way to do the value assignment?
    I want to do the process automatically without any need for editing files.

  • Moderator

    @ted Yes I think you should be able to do that.


    1RepRapFirmware can be set to enable or disable the "sensing" of endstops during a move. Using the S1 or S2 parameter on a delta printer causes the XYZ parameters to refer to the individual tower motor positions instead of the head position, and to enable endstop detection as well if the parameter is S1.

    If S3 is passed instead, RepRapFirmware will measure the axis length.

    For example:

    ; Homeall.g
    G91 ; relative mode
    G1 S2 Z4 F200 ; raise head 4mm for clearance
    G1 S1 X-340 Y-340 F3000 ; move up to 340mm in the -X and -Y directions until the homing switches are triggered
    G1 S2 X4 Y4 F600; move slowly 6mm in +X and +Y directions
    G1 S1 X-10 Y-10 ; move up to 10mm in the -X and -Y directions until the homing switches are triggered again
    G90 ; back to absolute mode
    G1 X100 Y100 F2000 ; put head over the centre of the bed, or wherever you want to probe
    G30 ; lower head, stop when probe triggered and set Z to trigger height
    G1 S3 Z+400 ; Seek Z max endstop and when endstop triggers set axis length.

    The G1 S3 Z+400 move at the end would travel to the top of the Z axis and set the M208 to be the resulting distance. This is possible because your zprobe has identified Z0 for you already. In fact, you could use the above gcode to home even without an actual z probe like a BLTouch. You set the probe type to be manual, and it will pop up a jog dialogue asking you to move the nozzle to touch the bed.

    In config.g it would need M558 P0 to set manual probe type and G31 X0 Y0 Z0 to set the nozzle to probe offset as 0 since the nozzle is the probe.

    Another way to set the Z Max axis is to have a macro that will home to z0 and then move up 300mm and then you use an adjustable set screw or optical flag to trigger the endstop at exactly 300mm. That way, as long as your bed is pretty stable in where Z0 is, it will stay accurate for quite some time. So need to measure it on every homeall, saving quite a bit of homing time.

    Something like this: 0_1556310613251_2_HomeZMax.g 0_1556310657894_0_Measure Zmax trigger.g

  • Moderator

    I should add that you can save the resulting axis length measurement with M500, which will save the M208 axis maxima value to config-override.g. In this way, if your Z axis positioning via z probe and the mechanical repeatability is high enough, you'd only need to home Zmax and measure the axis occasionally.


    So in that macro example in my last post, you would add M500 after the last line with G1 S3 Z+400. You could rename that macro MeasureZMax and only use it when needed. Your normal Homeall.g would only do a G30 at the end to find Z0.

    The example gcode file I included above does the measurement to a fixed length and then uses an optical endstop flag to physically set the trigger distance. The G1 S3 way would probably be more precise than adjusting the flag until an LED turns off.

  • I found the wiki to be a bit unclear on that part as in the table is says S3/H3 is for delta only. But I'm certainly pleased to see it works fine on a cartesian system as well.

  • @Phaedrux Thanks for the detailed explaination! I will try it out soon! It really cleared things up for me.

    I also found a missing hint in the documentation that got me hard: In one page it says for the Z trigger high to insert the measured value negated to the G31 command and on the other page there is no hint on any negation via G31.

  • Moderator

    @bearer I think it's most commonly and originally used on deltas, but there doesn't seem to be any limitation on its use to only deltas.

    @dc42 The table in the gcode wiki does say on delta (only), is that accurate?

  • Moderator

    @ted That's a good catch on the negated value thing. I don't think it should say that. The value will be negative in cases where the nozzle makes contact with the bed (like with a piezo, or maybe microswitch) in which case the nozzle tip is below the bed plane slightly. Otherwise it should be positive, indicating the height above the bed that the nozzle is when the probe triggers.

    I'll change that wording in the mesh compensation article. I think it may say negative there because it's borrowed from the Smart Effector documentation, which uses a strain gauge as a nozzle contact probe, which would have a negative value.

  • I got sidetracked by the mesh bed compensation while trying to find out where on my bed I should probe for finding z=0. I could get mesh bed compensation working but now I wonder how I could combine it with probing for z=0. Could not find any information about this.

    MBC finds out the least square error of all probe points on z axis and uses it to correct the actual z=0 position transparently (if I'm not mistaken). I could not find any more information.

    • Should MBC run after z=0 probing?
    • Should it run before z=0 probing?
    • Does bed mesh compensation include setting absolute z position so z=0 probing is not necessary?

    Imaging a bed mesh compensation made using 9 measurement points while the center measurement point is used for probing z=0 (actually: current-z-height=z-probe-trigger-height):

    If you first probe for z=0 and then apply MBC the transparent correction would lead to very different height values per measure point depending on whether your z=0 probing upfront happens on a measure point with negative error or positive error: The error of the measurement point used for finding z=0 gets applied to all points. In that situation I would have to introduce another static correction offset that compensates for the error of the measurement point used for probing z=0. This static offset breaks when having a fluctuating bed surface, e.g. when printing with cold, warm and hot bed due to different bed deformation depending on temperature. That would be very bad as I want to use the probe to eliminate ANY manual z-correction step per print.

    First doing the MBC instead could eliminate the problem when the correction is taken into account when probing for z=0. Is it?
    If it is not taken into account we have the same situation as when first probing, than doing the MBC: The found relative error of the probing point is introduced to all points uniformly.

    If the z=0 probing includes the MBC z-correction for the measurement point or when both is done in the same step, the algorithm could remove the error of the point.

    Did I understood something wrong? Hope you can shed any light on this!

  • Moderator

    You should probe for Z0 at bed center, or rather the center point between your mounting screws.

    Are you use mesh compensation in a few ways. 1 it can show you what your bed surface looks like which can be useful to get a visual representation of how flat it is. Second, it can be used to compensate for a flat bed that is out of level slightly. It can also compensate for a bed that is convex or concave, or a gantry that is arched or sagging.

    So at the very least it's a good diagnostic to see what your bed is like, then you can decide if and how you should apply correction.

    If it's simply flat but a little tilted, you can use a sparse grid pattern with 9 points to define a plane.

    If it's curved in anyway, you can do a more detailed grid. If the bed is curved, you can tapper it off after a few mm. If the gantry is sagging, you should not tapper it off since it will persist the entire print.

    If your bed is very stable and doesn't change much you can save the heightmap and load it before the print to apply the correction. Or if your bed is less stable and changes shape you can run G29 before each print. Not ideal if you're using many points.

    In your case, I think the Cetus bed is pretty stable and it's not very big and it's probably pretty flat. So you could either run a detailed G29 and save it, or run a smaller grid before each print.

    Before you run the G29 you should try and make the bed as mechanically level as possible and you should have established Z0 in some way (ie, homed the printer). This is so that the heightmap has a reference for where Z0 is and the topography is either above or below that point. That way when the mesh compensation is active, it should move the print head up or down in relation to the bed in real time so that Z0 keeps the nozzle touching the bed at all X and Y points along the surface of the bed.

    Does that alleviate your confusion at all, or make it worse?

  • @phaedrux Thanks a lot for the detailed explanation. It really cleared things up I was confused about.

    What I want is:

    • Automatic z=0 probing: So I don't have to worry about meanwhile changed bed height due to mechanical problems (lokbuild thickness changed due to mechanic impacts) or slight changes to the hotend mount (I often replace it with a laser cutter toolhead)
    • Automatic bed mesh compensation: To also compensate for a meanwhile changed bed level (e.g. my bed corners come up when heated and I don't always print with heatbed on).

    What I read from your text is that I first need to find z=0 and then run the MBC if I want an up to date z=0 and flatness compensation. Since needed time for MBC is nothing compared to the actual print time I want to do this at start of every print.

    What I still don't understand is how the MBC is working in detail: Where will it position the previously measured z=0 when applying error compensation on z axis?
    Somwhere I read about a least square error based bed mesh compensation but can't find it anymore. I got confused by that as it brings up the question if it adjusts the z=0 somehow for when the point we used for finding z=0 has an square error > 0. If not it would then just add an error to all points depending on the scale of the error of that measurement point. This would make the compensation obsolete as every point on the mesh map will inflict in this error.

    So did I understand it correctly that MBC just finds a relative built plate z-offset map that is applied to all points respectively without any square error thing? It does NOT contain any additional z=0 setting, just an offset is applied?

    Then I don't understand how the MBC knows that it does NOT need to add the offset to the centered point. Imaging that we have the following process:

    • Use the center point A to find z=0 with G30
    • Use G29 to build and store a correction mesh map
    • All correction offset values are applied respectively to the corresponding point x/y point on the build plate when printing
    • For the next print you find z=0 again with G30 using a different measurement point B (which is lower on z than center A)
    • You load the existing correction mesh map again with G29 S1 (bed did not change, so mesh is still correct)
    • All correction offset values are applied respectively to the corresponding point x/y point on the build plate when printing

    The result: If the two measurement points have different correction offset values due to different real world heights of the built plate (we assumed that B is lower than A) the actually corrected z position for measurement points is different for when printing leveled at point A compared to when leveled at point B (using the same map).
    This is because when probing z=0, using either point A or B, we do not store the information where on the build plate it was measured. In fact the first print (leveled with point A) is higher than the second (leveled with the lower point B) uniformly over the whole bed.

    Of course using two different points is just the extreme situation constructed to maximise error for illustration. The problem obviously occurs for a single point, too, as the algorithm that applies the correction offsets to z axis while printing does not know on which point (and what error that point had) we used to find z=0.

    My conclusion is that the MBC algorithm can only work if it actually sets where Z=0 is using its own measured z-values.

    What am I thinking wrong?

  • Another linked question:

    G30 does probe for z=0 (actually correctly applying the z-trigger-height of the probe). It does that by driving down about 10mm (lets call it the probing window). If the sensor (I'm using BLTouch) does not trigger it brings up an error and does not change z=0.

    My problem is that I can't ensure mechanically that my hardcoded starting z height is not further away than the 10mm probing window. That already lead to the situation that the probing stopped with the error 1mm above the build plate as it didn't reach the probing distance. In other words: The probing window was not big enough.

    I could also thing of the opposite where the build plate is higher than expected so that it does not start probing with the necessary minimum distance to the plate.

    Is it somehow possible to tell G30 command that it has a probing window of 180 mm (which is my z build volume height)?
    An alternative would be to somehow use the BLTouch as endstop and move down with a relative G1 Z-200 S1. Is that possible?

  • @ted said in Z homing Gcode bloody for beginners:

    Is it somehow possible to tell G30 command that it has a probing window of 180 mm (which is my z build volume height)?

    M558 parameter H does this. Another question is, do you really need this.

  • Moderator

    @ted said in Z homing Gcode bloody for beginners:

    lets call it the probing window

    Let's call it the dive height instead.

    Usually, the way this is handled is that the dive height is set at some minimum amount so that it doesn't take forever to run a G29 mesh compensation routine because it has to raise the probe to the dive height for each point, possibly multiple times. For the BLTouch 5mm is a good value. But really it only needs to be slightly more than the measured trigger height.

    But the dive height doesn't set a minimum travel distance for G30. If your bed is far from the nozzle and the Z axis isn't homed, and you home the printer, it will move the z axis until the probe triggers, not just the dive height and then stop. Just like for a homing move using an endstop. After that first trigger, if it needs to probe again it will then travel to the dive height and probe again.

    To ensure that the probe is a safe distance away from bed after you home the printer it can be a good idea to raise the print head after homing is finished. This could be the same as the dive height, but really it just needs to be enough distance to allow the BLTouch pin to drop freely without hitting the bed.

    Can you better describe the situation where you're getting the error of the probe not triggering? How far away is it from the bed? During what operation is this happening? What are your actual settings?

  • @aidar Thanks, that solves the problem for me!

    @phaedrux I set the dive height to 50 mm. It gives me a lot of failure tolerance. It is working fine for me. So far no problems and much safer than just the 5 mm default. The mentioned error while probing (which I now avoid with a higher dive height) was due to mechanical tolerances in my extruder / laser mount.

    It is working fine for single probes using G30. Wasn't aware that this would affect the dive height of G29, too. Haven't tried G29 in a while now as I still don't know if it resets z=0 when called AFTER G30.
    I got the problem that whenever G29 after G30 the printer prints with different z=0 heights. It is always a way too high and it is different every sequence! Trigger height of BLTouch probe is wonderful stable with < 0.01 mm tolerance, which is amazing! Also checked if I have missing steps and lowered max z speed to 1 mm/s. It's fine. Still looking for the error and still thinking about my question above: When G29 is not setting z=0 than this could cause the changing z=0 height. Need to investigate here.

    BTW: When having dive height at 50 mm and then G30 down and get the probe triggered already after 1 mm it is not driving back 1 mm but driving back whole 50 mm. So it ends at 50 mm over the trigger point while started at 1 mm over the trigger point. Not sure if this is not a bug. When first setting the dive height to 180 mm (my build volume) I got the problem that it rises even over the endpoint switch. Since G29 seems to use that dive height also it is not a good idea to do so anyway (unless I have too much time).

Log in to reply