I’m not really sure you understand how endstops are supposed to work in 3D printers for endstops. Adding code (or hardware) to debounce the endstop switch input will result in decreased homing accuracy.
First off, it’s not a common problem in 3D printers. I just did a Google check and I could not find any reference to button bounce being an issue. Maybe you can explain why you think it is.
Secondly, “add a pull up resistor” has nothing to do with button bounce; the pull up resistor provides a high voltage level that can be pulled to ground by the switch, with the resistor minimizing the current drawn from the source to ground.
When switches are used for endstops as part of the homing process, the goal is to recognize when the first level transition take place, as that indicates when the carriage/gantry/toolhead/whatever has reached the endstop. Any later transitions (ie “bounces”) are simply ignored.
By adding any kind of debounce mechanism, there is a delay (indeterminate in length because the number of bounces and the interval between them is unknown) in which the signal from the switch is given time for the transitions to end and become stable.
During this debounce process, the carriage/gantry/toolhead/whatever continues to move and, as the length of time the debounce process takes is indeterminate, the position that is indicated by the stable signal is incorrect and, more importantly, non-repeatable.
Now, maybe you’re talking about user interface buttons and, in these cases, debouncing the buttons is desireable but for endstops adding any kind of debouncing will result in a decrease in accuracy in the printer’s homing operation.
I’m trying to figure out the rationale for need to have code that debounces endstops. In this discussion, I’m ignoring sensorless homing, eddy current sensors and load cells because they have their own unique processing requirements.
First off, I’m concerned about the presence of endstop debouncing code in Klipper. Of the common methods used for endstop sensors (microswitches, Hall effect switches, optical interrupters, inductive (and capacitive) proximity sensors and BL Touch), only microswitches have the opportunity for bounces and, as I noted above, they should not return a change in signal unless their contacts close (this is discussed below).
The term “microswitch” is pretty loose - in 3D printers, it ranges from nice Omron devices which have no bounce whatsoever (I’ve looked at enough of them with a 'scope over the years to make that assertion) to an old momentary switches with no “snap action” to a couple of bared wires that touch when an extreme is reached. In the case of the no snap action momentary switch or the bared wires, there will be bouncing but the first time the contacts close, you’ll get an initial signal which indicate that the endstop has been reached - the subsequent contacts (post bounces) are irrelevant to the endstop operation. Only the time of the first contact is required.
Now, I haven’t examined the entirety of the code so I have to ask the question, if the debouncing sequence is started, does the stepper movement stop? If stepper movement isn’t stopped, then there is the chance that the movement will continue beyond where the endstop was encountered. To be fair, this isn’t a significant concern for X/Y homing, but it is for Z axis homing.
Secondly, I’m concerned about the inclusion of debouncing on endstops because it can mask intermittent wiring problems - if something opens or closes instantaneously during movement, before reaching the endstop, the debouncing code will filter it out.
This is masking a hardware/wiring problem which can result in much more significant problems later as the issue moves from intermittent to permanent.
Again, I’m curious about the rationale for the inclusion of endstop debouncing code. Any insights you have would be appreciated.
One comment about user interface button debounces.
You wrote:
It sounds like the debouncing interval is less than 10ms; if this is the case then should be examined as it’s much too short.
Even with good quality, snap action buttons you should have an interval of at least in the 10s of milliseconds as humans make very inconsistent presses of buttons.
When I worked at IBM, the buckling spring keyboards had a debounce time of 50ms - this allows for a theoretical 240 words per minute typing speed. When I worked at Logitech and RIM, they used similar debouncing times on their products.
I have nothing to say about filament sensors other than I use them on a couple of printers and never had an issue with how they operate.
I think for an IDEX printer it can matter concerning the X-axes.
Wit my IDEX printer. I aligned both endstops (microswitches) for the two tools on the x-axis so that they print on the same spot when they go to the same coordinate.
But it can happen, that this alignment is of from time to time after homing. Could that be a matter of the debouncing routine during homing?
Could we fork this into its own thread? (Maybe @Sineos can do that?)
This always happens. The final position of the toolhead is never the endstop trigger location. The time of the endstop triggering is exactly recorded and the position of the toolhead at that time is the reported endstop position. but the toolhead has physically moved on from there.
This gets worse with multi-mcu homing as up to 25ms of time can elapse from the trigger to the time the axis stops.
Most machines don’t care about the overshoot. In industry we have probes with tips that move. 3D printers are all squishy enough to overshoot by 25 microns and not care, even with a nozzle probe.
I think its a damned if you do and damned if you don’t kind of situation. If you don’t offer debouncing, every user has to have perfect wiring. Users with slightly imperfect machines will be very upset and blame the software. If you do offer it, you hide slight imperfections from users and the problem has to get bad before they notice.
That’s interesting - I hadn’t thought about it. I want to make an IDEX printer, but I have too many things going on to be distracted by that.
What kind of switches are you using for the X axis?
Unfortunately, I think it’s unlikely that bouncing switches are your problem (unless they’re extremely bouncy - like using a couple of bared wires as I mentioned previously).
To come to this conclusion, I just went through the math. In Klipper, the default homing speed is 5mm/s - let’s use that for our calculations. Converting the time units to μs (as that is what the sampling time is), it works out to 5nm/μs.
Looking at the code (~/klipper/klippy/extras/homing.py), it seems that the default ENDSTOP_SAMPLE_TIME is 15μs and ENDSTOP_SAMPLE_COUNT is 4. This means that the best case endstop debounce time is 60μs.
In that amount of time, the gantry/toolhead will move 900nm or 0.9μm - much too small a distance to be practically noticeable.
In your case, I would have to understand more about your system to make an informed opinion but, based on this analysis, I would look at the X-Axis endstop sensors and examine them for mechanical issues.
Based on the analysis above, the extra movement is insignificant for all intents and purposes.
But…
This is interesting as this is in the timing range that I was expecting for debouncing - if we’re working in ms, then the 5mm/s becomes 5μm/ms and if we have a 25ms delay or error period then unwanted movement is in the range of 100μm which is significant.
This is also discussed in the Klipper documentation:
I’m not sure how to reply to your statement of “perfect” wiring and your acceptance of not all users being expect to have it.
Rather than use the term “perfect”, I would say that I expect all users to have “appropriate” wiring. This means that all the wires are properly terminated, routed with no sharp bends, are never pinched, have strain relief and are stranded. If somebody doesn’t follow these basic guidelines for routing wires in their printer, then they’re going to have problems and no debouncing is going to shield them from that - maybe it will provide some short term masking, but they’re going to have significant problems.
This will likely be worse than a microswitch. IMO, sensorless homing is a “misuse” (without meaning it derogatorily) of a totally different feature, namely detecting stalls. I would assume that many factors are influencing the overshoot, like stiffness, acceleration, velocity, and the “springiness” of the material against which you bounce. “Springiness” overall might even depend on the direction from which you hit, e.g., hitting with the left side of the head compared to hitting the right side.
Good quality microswitches, e.g., Omron, are known for high precision and repeatability. There are factors that may influence this, such as:
RC circuits on the board that are used for filtering spurious signals and may introduce time constants in the signal. This should be constant and not affect repeatability or precision.
Spring steel levers can introduce unwanted effects.
Mechanical alignment issues and effects of thermal expansion.
Sensorless homing is not the correct approach for this situation (homing the X axis on an IDEX printer so that both toolheads have the same home/reference position to move from). I use Sensorless homing on all my printers for X/Y homing and it seems to be repeatable within 0.5mm or so - good enough for a single toolhead for prints that I keep builds at least 5mm away from the bed edges but I don’t think it’s accurate enough for this.
What kind of main/toolhead controller board are you using to mount the microswitches on? As @Sineos indicated the circuitry on the board can affect things (ie a resistor/capacitor on the pin acts as a hardware debounce and will delay when the contact is recognized by the appropriate MCU).
When things are off, how much are they off by? That could be a clue as to what’s happening here. I’m thinking of the Multi-MMU timing issues that @garethky highlighted.
My first recommendation is to replace your generic microswitch with an Omron SS-5GL one - I used to use the SS-5GL111-F-3T, which has a 12g sense (the lowest possible) and, for Z-Axis endstops (which is similar to your application), I pulled off the lever and just used the button, which you are appearing to do.
The Omron SS-5GL is historically the one recommended for use in 3D printers - I don’t know if there was any kind of analysis done in the day, I can just say it worked great for me for the Z axis on my Prusa i3 clone and Sapphire Pro.
If they’re connected directly to the main controller board, then you don’t have the Multi-MMU issues then try the Omron microswitches -they’re only a few bucks and hopefully not all that much work to replace.
Was testing sensorless homing at first on my own IDEX mod to save cables but then went to micro switches too due to better precision and reliability.
Wire as NC switches and maybe use a slower second homing attempt to get more precision.
I’m not sure I fully understand the background of this thread, but I can try to add a few details.
The “endstop debouncing” in Klipper isn’t really “debouncing” - it’s EMI mitigation. It’s fairly common for some printers to route the endstop wires along the same path as the stepper motor wires. This, along with other situations, can lead to sporadic voltage spikes on the endstop pin that cause the gpio to read as a logical “high”. These false readings are rare, but if they occur they totally mess up the homing process. The mitigation is fairly straight forward - make sure the gpio reads “high” for 4 consecutive readings spaced over 60us. Since this was implemented, the reports for false endstop triggers went away and I haven’t seen any reports of problems introduced from it.
Note that the homing code uses the time of the first trigger in the position calculations. So, the additional checks should not adversely impact the accuracy.
The buttons code also implements a “debouncing” logic, but this is largely separate from the endstop code. The buttons code requires a changed value to be at the new value for two consecutive readings before it is reported to the host. The default time between reads is 2ms. This seems to help quite a bit with typical “button bouncing” - at least on modern mouse type microswitches that don’t require a long time to “debounce”.
Sorry about that. This topic was split from another one which proposed generalizing the Python debounce code used for ADC based virtual buttons to all buttons.
I used “debounce” loosely there, as I’m used to hardware implementations that also act as false trigger mitigation. Which was the main focus of this topic.
That seems a bit too tight, especially when switches like this one have a max 10ms bounce time, per it’s datasheet. Admittedly, that’s a tactile switch, but Würth isn’t exactly a no name company.
Something interesting I noticed while browsing datasheets. Even some Omron microswitches are only rated to 500 m/s^2, with malfunctions at 200 m/s^2. They almost certainly exceed those by a large margin, and that’s real acceleration in one direction. However, it is worth keeping in mind.