[FR?] Multiple endstops per stepper, select secondary endstop within "G28" Command

So I am not able to fully grasp how to do any hardcore coding for Klipper (slowly trying to learn) but from my understanding so far this seems like it could be possible? Anyone that has a knack for Klipper may be able to chime in for me on this.

Background:
Building a JennyCoreXY printer has proven to me at least that klipper is fairly configured only for the Voron2 when it comes to gantry leveling, and endstop positions. Due to a sagging gantry at the rear when powering down, I needed to get my gantry leveled before doing a QBL, and installed endstops at MAX, then proceed to PROBE Z0, and use a G92 with the Z_PROBE offset to have the printer find Z0.

Issue with this now is when I do QBL, it sees my endstops are not perfectly distanced from the print bed and fails the QBL due to out of tolerance. So unless I greatly widen my tolerance, it will never have that great of a result for QBL.

Proposal:
My proposal I believe can be implemented? And that’s where I am looking for insight from more experienced Klipper users / developers.

Is it possible to assign “default” enstops in the config, but then also secondary or even tertiary endstops that can be called upon within the “G28” command? In my situation a third would even be great to have an automatic Z_OFFSET.

Example Printer.cfg:

[stepper_z1]
step_pin: PB9
dir_pin: PE0
enable_pin: !PE1
microsteps: 32
rotation_distance: 8
endstop_pin1: PB1
endstop_pin2: probe:z_virtual_endstop
position1_max 400
position1_min -2
position2_max 0
position2_min -5

Example G28:

G28 X0 Y0 Z(P1)400 ; Home axis, Z max via endstop
G1 X200 Y200 Z50 ; Position tool head to center of the bed for probing
G28 Z(P2)0 ; Override Z homing position to max=0, via probe as Z-endstop

Does this seem logical? Or too much?

3 Likes

I am also in the need for a similar function.

An alternative would be to have a SET_ENDSTOP command for a stepper or to alter the MANUAL_STEPPER or STOP_ON_ENDSTOP parameter with an endstop pin at runtime.

The difference with your need is you need it on a XYZE stepper, I would need it on manual steppers or basically every stepper.

What I do not really understand is why there is such a big difference in the commands. It should be possible to do G28 Z for gcode reasons, but a G28 manual_stepper_name or G28 stepper_y should also work - or, the other way around, a STEPPER (instead of MANUAL_STEPPER) … MOVE … STOP_ON_ENDSTOP.

If you could merge those to syntaxes I guess providing an endstop pin at runtime via the STOP_ON_ENDSTOP parameter would be more generic and would not require new Gcode commands to utilize a secondary (or third, fourth and so on) endstop.

Happy New Year. If you google the topic you will find many requests for multitble endstops and just as many answers why they do not exist yet.

I also drive a MMU with klipper macros. OK the solution works but the line by line evaluation of the macros, especially with nesting, does not make it easy. Actually the macro solution is not designed for this and you would have to put the whole thing in a Python extension, which is quite possible and has been on my todo list for a while.
In Python you can change the enstops of an axis in the fly, but you have to handle each enstop type a little bit different.

In my mod for the MPCNC I have already done something like that for the Z axis.

I excessively googled the topic constraining it to klipper and tbh most requests could have been “solved” with workarounds (SYNC or synching extruder steppers) and other answers where just like “no one took the effort yet to implement it”.

However I guess multiple endstops per axis could generally lead to confusion on installation/gcoding and also to machine security and reliability flaws if not properly implemented.

But other than that I see no reason why a SET_ENDSTOP command or another way of incorporating multiple endstops per stepper do not exist yet.

A MMU2S.py extension would be nice of course but for me at least quite some effort to implement. And it would be a very “nichy” solution - the multiple endstop approach can be utilized for alot of the other use cases too on the other hand. Though should you tackle an MMU extension I would happily help.

Atm I am thinking about switching the endstops hardware-wise with a GPIO pin, probably the quickest solution for me but also the most unflexible and non-sharable.

Hello I also want to use multiple endstop. Exist a feature to create a virtual endstop that trigger as a result of a logical operation between two real endstops for example:
viltual_endstop = endstop1 OR endstop2
?