Friday 22 June 2012

The only way is up

I have always had my machines home away from the bed, with the Z limit switch at the top. Reprap software has always done the opposite, homing towards the bed. As I wanted Mendel90 to work with standard Reprap hardware and software I designed a bottom limit switch with a fine screw adjustment. Playing with it like that for a few days reinforced my opinion that homing upwards is much better.

I have clips in the corners of my bed, and being limited to using the Prusa PCB heater and the smallest bulldog clips I can find means the corners are no go areas. That means there is no homing sequence that guarantees not to crash the head. G28 homes X and Y to a corner and then homes Z, so that is a guaranteed crash. I had to home X first and then move to the middle before homing Y, then move to the middle and home Z. But if Z was already lower than the clips and Y was at one extreme then homing X would crash. So then I raised Z a few mm before homing but that means if Z was at the top it could ram the bar clamp.

After a few days I had crashed the head several times, ripped the tape on my bed and the final straw was homing Z with some crap on the nozzle. That stopped the nozzle reaching the bed so it failed to trigger the endstop. That caused it to pull the nuts out of the X ends and then spin endlessly so the levelling was lost.

I really hate levelling the bed when there are four points (it is easy with three, but without redesigning the PCB, I am stuck with four). So I went back to having a fixed limit switch at the top. It has the following advantages: -

  • Z homes to the top first, so it is always a safe operation no matter what the starting position is and what is on the bed or if there is any plastic stuck to the nozzle.
  • It prevents the Z axis ramming into the top, which is potentially damaging because it can exert quite a lot of force. Driving Z past the bottom is fairly safe because the nut traps are open at the bottom. That means the maximum force it can apply to the nozzle is the weight of the X axis.
  • Z = 0 is defined to be when the nozzle touches the bed (when hot) but it never has to actually go to that position. It is defined by putting the distance from the end stop in the firmware configuration so adjusting it is a matter of tweaking a number rather than a screw adjustment. I set it roughly by nudging to 8mm while rolling an 8mm bar under the nozzle. Then I extrude an outline, cool it and measure its height. I can then correct the number to get the first layer exactly the right height. There is no trial and error, just a simple adjustment procedure.
  • The end stop is much simpler as it no longer needs to be adjustable.
I had to hack Marlin to make it work. If the homing position is towards the top it does Z first instead of last.

I also like my X Y origin to be in the middle of the bed, not one corner. That means the G code doesn't need  to contain the origin offset, everything is sliced to be at 0,0. The comments in configuration.h implied that you could define the origin in the middle but then the soft limits didn't work. I changed the way the axes are defined to be more flexible. Instead of defining just the HOME_POS and the MAX_LENGTH I define the MIN_POS, MAX_POS and HOME_POS. For X and Y they are -100, 100 and - 102 as Mendel90 has exactly 200 mm of travel plus 2mm clearance each end and 2mm to the end stop. So the axis only ever hits the endstop during homing. After that the soft limits prevent it hitting any of the ends. Z cannot be driven lower than 0, so it can just touch the bed worst case.

The code is available on Github. I will remove the bottom endstop from the Mendel90 configuration as I don't see any need for it. Changing a number in the firmware is so much easier than tweaking a screw.

Since reverting to this method I have not had any head crashes or homing mishaps, it just works. I also have ooze free unattended starts with the following G code.

M83 ; use relative distances for extrusion
G1X5Y99F9000 ; Go to the middle of the front
G1Z0.05 ; close to the bed
M104 S200 ; set extruder temp
M190 S55 ; set bed temp & wait
M109 S200 ; wait for extruder temp
G1E5F50 ; extrude a blob
G1X40F4000 ;wipe 40mm along the edge of the bed
G1Z0.3 ;lift Z 


  1. This is some common sense thinking. Like it a lot & try to replicate this on my Ultimaker!

    Thanks :)

  2. Great work again very useful I will be trying your "On the up" method Thanks!

  3. Great Work!
    For me trying to change something in firmware is always some kind of maze )

    Meanwhile orginal Marlin turnes back, a lot of useful info in pronterface systray. could it be switched back in that firmware too?

    1. Sorry I don't know what you mean by the "pronterface systray"? What sort of information?

      I didn't change anything other than the homing and the configuration.

  4. I have to disagree with one of your points, specifically that "Z homes to the top first, so it is always a safe operation no matter what the starting position is and what is on the bed or if there is any plastic stuck to the nozzle.". On my Sells Mendel with a Wade extruder this is not true. With X=0 the stepper motor hits the frame on the left side at about Y=60mm. That is why I have to ensure that Z < 60mm BEFORE I start a new print since it homes X, Y and Z in that order! In fact, now that I wrote it down it would be simple to change the sequence to Home Z first...

    Keep up the good work!

  5. I set the Z limit on my Mendel so it is below where it hits the bars. That does mean the max Z is quite low. Potentially it could print taller things in the middle if the Z limit was at the bottom instead.

    1. Yes, I routinely print objects > 100mm high.
      Maximum is 120mm on my current RepRap (Sells) Mendel.

  6. yep i'll definitely give this a try. cheers.

  7. Hi I'm trying to commission my mendal90 with a sanguinololu board using marlin firmware (latest which includes your mod for homing z at the top). I have endstops at the front Ymin , right Xmax and top Zmax all NC. The problem is I can only move the axis if I open the switches!! I've modified the config file to mirror your setup on github. Any advice? Thanks

  8. Perhaps you have wired to the normally open pins of the switch instead of normally closed?

    The two outer pins are the ones to use.

  9. No I was using the outer pins. I have now got it to work by playing about with the settings in Marlin. I don't quite understand why I should need different settings to the ones you posted on github but there we are. Incidentally it is still possible to get into problems eg if the x carriage is at the lhs it will hit the top end support before the z end stop is reached.

    BTW please could you tell me where you bought the polypropylene tape or could you sell me some.

    Many thanks

  10. I can't imagine how your endstops get inverted. You have used the outer pins at both the board end and at the switch? When inactive the switch should be closed and pulls the input low. When it hits the switch opens and the internal pull-ups take it high.

    Yes the left hand clash is a bug I didn't notice despite running the machine for nearly a year.

    I get the PP from here: but here does smaller quantities:

    1. Just a note to the people implementing this way if working:

      Nopheads changes to the marlin firmware have been included in the main build.

      To get the endstop to work correctly you may need to change the pins.h file.
      For my Ramps 1.2 board, the max endstop for the z-axis was set at -1 (inactive)
      and had to be changed to 19 (value was included in the comments).

  11. That Start G-code works great!
    I haven't installed homing sensors yet so I've added the following at the very start of the code for my machine.
    ;Note! No home switches installed! Actions before print:
    ;Manually calibrate X0 Y0 Z0. Then move to Z+30!
    G92 X0 Y0 Z30 E0 ; set position