Printer Model: Custom Desktop Pick and Place machine
MCU / Printerboard: Custom running RPI CM5
Host / SBC: Mainsaill
klippy.log
Fill out above information andin all cases attach yourklippy.logfile (use zip to compress it, if too big). Pasting yourprinter.cfgis not needed Be sure to check our “Knowledge Base” Category first. Most relevant items, e.g. error messages, are covered there
Describe your issue:
I’m designing a pick and place machine and using OpenPNP to operate it. I have CoreXY AWD setup with a head that contains 2 nozzles. The head has 4x manual_steppers to operate 2x Z motors (to bring the nozzles up/down) and 2x rotation motors to rotate the nozzles.
Kevin kindly made a custom Klipper branch to support manual stepper to have extra limit switches so that I can use the nozzles to probe the PCBs to detect component heights, etc. (this makes setting up OpenPNP much easier)
In any case, I discovered that I was missing one detail. OpenPNP checks with M114 what the probed position is after the probe (nozzle) detects something. However, Klipper currently does not include manual steppers in its reporting with M114. How can I have it be included with a custom macro or otherwise? Attached the trace log that OpenPNP produces to show the issue.
2026-01-02 15:25:10.789 GcodeAsyncDriver$WriterThread TRACE: [Rapid Board:127.0.0.1:5000] >> M114
2026-01-02 15:25:13.997 GcodeDriver$ReaderThread TRACE: [Rapid Board:127.0.0.1:5000] << ok
2026-01-02 15:25:13.998 GcodeDriver TRACE: Position report: ok
2026-01-02 15:25:13.998 GcodeDriver WARNING: Rapid Board: Axis x letter X missing in POSITION_REPORT_REGEX groups.
2026-01-02 15:25:13.998 GcodeDriver WARNING: Rapid Board: Axis y letter Y missing in POSITION_REPORT_REGEX groups.
2026-01-02 15:25:13.998 GcodeDriver WARNING: Rapid Board: Axis LeftZ letter A missing in POSITION_REPORT_REGEX groups.
2026-01-02 15:25:13.998 GcodeDriver WARNING: Rapid Board: Axis RightZ letter C missing in POSITION_REPORT_REGEX groups.
2026-01-02 15:25:13.998 GcodeDriver WARNING: Rapid Board: Axis LeftRot letter B missing in POSITION_REPORT_REGEX groups.
2026-01-02 15:25:13.998 GcodeDriver WARNING: Rapid Board: Axis RightRot letter D missing in POSITION_REPORT_REGEX groups.
2026-01-02 15:25:13.998 GcodeDriver$ReaderThread TRACE: [Rapid Board:127.0.0.1:5000] << X:488.500 Y:355.000 Z:0.000 E:0.000
2026-01-02 15:25:13.998 GcodeDriver TRACE: Rapid Board got lastReportedLocation ()
2026-01-02 15:25:13.998 GcodeDriver TRACE: Position report: X:488.500 Y:355.000 Z:0.000 E:0.000
2026-01-02 15:25:13.999 GcodeAsyncDriver TRACE: Rapid Board confirmation complete.
Hey @EddyMI3D no one ever said anything. Lets not put words in people’s mouths I am simply trying to exhaust my options before I post on the forum here and ask for help. Thanks for the feedback on the text formatting, I did try to fix it several times but for some reason it didn’t work.
I did copy his text exactly using the copy function in the forum and it simply printed out the line in the console. Are we use that Klipper is even tracking manual_stepper positions in the kinematics?
Note that you’ll need to add [respond] to your config for the above to work.
Note that the above only works if you also map the desired manual_stepper objects as an “extra axis”. To do this, you’ll want to run a MANUAL_STEPPER GCODE_AXIS=A ... type command - G-Codes - Klipper documentation .
Finally, note that the above should allow M114 to report where you’ve commanded the manual stepper to move to. However, when using the MANUAL_STEPPER ... MOVE=987 STOP_ON_ENDSTOP=1 type features the code sets the final position to the requested position (eg, 987) upon contact with the endstop - so I’m not sure you can use that support to “probe” a height. Achieving the above is possible, but would likely require additional code changes to the manual_stepper module.
I think in that case this wouldn’t help either way then without this feature. I basically need the nozzle to act as a probe and report back the position it detected something. Is it possible to implement this?
Thanks @koconnor we seem to be getting somewhere now but it’s not showing any numbers and my X axis is homed to some weird decimal point for some reason.
I will also add that I’m still having the issue with the nozzles not stopping in time when the switch is detected. I can confirm that when I set up a button and press the nozzle, it prints it in console immediately. But when doing moves with stop on endstop, it gets over-compressed.
As I mentioned in the original thread for this feature, I was pretty sure it was working at one point without issues. My only guess is that perhaps I changed something in the config and it broke it, but I don’t see what could’ve caused that. My only theory is that maybe because I increased my tiny z motors current, it has some effect on the power draw, but even then I only increased it by like 0.10 amps.
Anyway, we can figure out this issue afterwards. One problem at a time
Take a look through the documents I linked above. It should be possible to figure out where the error is. (It’s not easy to debug these things remotely, without the actual hardware.)
Also, make sure you’ve enabled the given manual_stepper objects via the GCODE_AXIS mechanism - the M114 code above definitely wont work if the motor isn’t mapped to its corresponding axis.
I answered this as best as I could at How to create multiple probes for multiple manual_steppers? - #24 by koconnor . You seem to be asking the question, “why does the Klipper software delay its response to the driver’s stall signal?” and the answer is, “it doesn’t”. The question I think you should be asking is, “why is the tmc driver only producing a stall signal after a delay?”. I’d say best would be to investigate different tmc driver configuration settings; it may also be possible that the tmc driver isn’t suitable for detecting stalls in that situation.
Ok I’ll try my best to continue troubleshooting, but I do want to clarify again that I am NOT using the TMC2209 to detect the stall. I have an optical limit switch that detects when the nozzle’s spring gets compressed. It’s a pretty clean switch with a good pull up/down resistor setup and I tested it by creating a button setup in Klipper’s config where I pressed it manually and it triggers instantly by printing out the result in the console.
I only use the TMC2209 sensorless homing when homing upwards (endstop_pin). Downwards I use the optical switch (endstop1_pin) to probe.
Ah, okay. I misunderstood. I guess it is one of the challenges of not having the hardware on hand.
I don’t know why there would be a delay like that. You could try different homing speeds to see if it changes the behavior. You may also want to check if there is a large capacitor on the signal line for the optical sensor - we’ve seen in the past some delays can occur if it takes some time to alter the signal. I’m just guessing though.
I did notice I had an error in my original post (gcode_position is not exported for extra axes). You could try something like this instead:
Small note, I had to fix the macro and change to quotes (Gemini helped figure out why it was malformed command )
[gcode_macro M114]
rename_existing: M114.99
gcode:
{% set amap = printer.gcode_move.axis_map %}
{% set pos = printer.gcode_move.position %}
{% set gpos = printer.gcode_move.gcode_position %}
Use standard straight quotes below:
RESPOND TYPE=command MSG=“X:{gpos.x} Y:{gpos.y} Z:{gpos.z} A:{pos[amap.A]|default(0.0)} B:{pos[amap.B]|default(0.0)} C:{pos[amap.C]|default(0.0)} D:{pos[amap.D]|default(0.0)}”
Also, as you mentioned, the STOP_ON_ENDSTOP doesn’t work with G1 command and it just goes to 0.0. Even if I touch the probe, it ignores it and moves all the way (no delay even, just straight up ignoring it, attached Klippy log)
10:46 AM X:0.0 Y:0.0 Z:0.0 A:0.0 B:0.0 C:21.9 D:0.0
10:46 AM m114
10:46 AM g1 A0 STOP_ON_ENDSTOP=1
10:46 AM g28a
In regards to the probe issue - since you had noticed yesterday that the wrong code version was on GitHub, is it possible that the original version I tested had something different that made it work? As I mentioned before, I am pretty sure it worked the first time as expected, but maybe my memory is just bad. I came back from a two week vacation and re-installed the firmware and that’s when I think it stopped working and started over-traveling. So just wondering if it’s possible to do some sort of code comparison with the version you had on there before November 16, 2025?
Also thanks for your continued help, just chipped in a bit on Ko-fi
Also, probing down to endstop1_pin at slower speeds does help - but doesn’t solve it completely. It compresses the nozzle less, but it’s painfully slow.
In regards to your capacitor theory, yes I would agree. I need to check the schematic if I have one on the signal line but if it works registering in console with [gcode_button] very fast, I would imagine it shouldn’t be an issue when probing?
Ah, STOP_ON_ENDSTOP is not a valid parameter of G1 - that’s only valid on the MANUAL_STEPPER command. So, any time you need to home one of these steppers you would need to use a macro that does something like:
# Unmap stepper from regular G1 commands
MANUAL_STEPPER STEPPER=xxx GCODE_AXIS=
# Home stepper
MANUAL_STEPPER STEPPER=xxx MOVE=0 STOP_ON_ENDSTOP=1
# Remap stepper to regular G1 commands
MANUAL_STEPPER STEPPER=xxx GCODE_AXIS=A
I’m not aware of anything in the software that could delay a trigger signal like that. At a low-level, during a homing/probing event, the host software instructs the mcu to periodically check the trigger pin and to stop stepper movement upon a change to that pin (ie, the voltage level changes on one of the wires going to the mcu). The same code is used for homing/probing on basically all axes on all printers.
As a suggestion, you might want to try gathering more data on the issue. For example, if you have access to an oscilloscope you could try monitoring the pin connected to the optical sensor along with the pin connected to the stepper “step” signal. That may help give some more concrete information like how long is the delay, and is the delay in the mcu or the sensor.
Thanks Kevin for the oscilloscope idea, I agree that would be a good way to determine if the signal is lagging or not. I’ll work to set that up and post the results.
Regarding STOP_ON_ENDSTOP=1 not working with G1, yeah I figured that to be the case but tried it anyway.
Would you have bandwidth to update the code so that M114 doesn’t print 0 when it probes on the endstop? Otherwise the M114 would always be wrong Appreciate all the help you’re providing to make this work!