I've noticed the stock micro switch Z limit sensor on my printer is a bit hit-and-miss. Mostly it works fine but occasionally the nozzle ends up a bit high, which of course ruins the print.
This project is not to swap the microswitch for an optical sensor, but instead to _add_ a secondary sensor for improved accuracy.
I'm hoping by adding the sensor to the Z screw, I can take advantage of the distance-magnifying effect of the screw pitch.
Edit: At least that was the plan, but I've fixed the problem without an additional sensor! Just the stock microswitch.
For the die-hard fans of auto-bed-levelling I have two comments:
1. my bed is flat enough not to need to account for its shape by measuring it, so I don't; and
2. I shouldn't have to re-level before every print if this idea works, so saving time.
Oh well that's embarassing, I've only gone and bloomin' fixed it. And without resorting to using the optical sensor!
Short version: I rewired the microswitch board to work off the NO contact (instead of NC), pulling a 3.3V line from the unused BLTouch port on the motherboard. That's completely cured it, with homing repeatability in the sub-5um range and no more occasional big errors.
The schematic below shows roughly how the circuit looks now:
Revised circuit
I had to cut a track and solder a resistor onto the microswitch board, and swap wires in the connector to provide +3.3V from the BLTouch port to make it work. So it was a little complicated, but cost nothing and took about 10 minutes.
I borrowed a cheap dial gauge, marked in 0.01mm (10um) increments, and fitted it to the printer so I could watch the height of the gantry while experimenting.
Repeated Z-homings got a surprisingly consistent result: good to within about +/-2-3um...right at the limit of what the gauge could indicate...but only when the microswitch worked. Three out of the 30 homings that I tried were way off, like 100um or more off - this exactly matches my suspicions.
Turning the screw slowly highlighted two things:
the Z stepper is indeed capable of incredibly fine control/small steps - no noticeable 'stepping' on the gauge, suggesting steps are down at the '5um or less' scale.
the point at which the microswitch clicks is very consistent, and 100% reliable. So this explanation for why it's not working seems spot-on. The NC contact is breaking slightly early, before the 'tipping point' where the spring slams the armature over to hit the NO contact. Leaving the NC contact happens slowly, so is a bit uncontrolled, compared to hitting the NO contact which happens at great speed ensuring a repeatable make. Designing the end-stop input to use the NC contact is Ender's mistake here IMO.
Also, interestingly, there's about 50um of backlash in Z. So I've modified my bed-levelling script to always move to the target height in an upwards direction - like in normal printing - rather than downwards. That should take care of the backlash effect.
Helpfully, the device dimensions and other specs are listed, stopping short of an actual schematic. 2.7 to 5V operation, active high, sounds fine.
Since the mechanical switch is normally short circuit, rising to 10k when triggered, we can just connect it in parallel with the optical sensor's output so that the signal only goes high when both are triggered.
As it stands, the machine's limit sensor input looks like a logic input pulled up to 3.3V via about 8.5kΩ. The 0V connection is the wire nearest the machine.
The microswitch is wired normally closed, and has a 10kΩ resistor across it so that when contacted its resistance rises to 10kΩ.
Schematic showing approximately what's going on
Thus the input looks like a high-impedance logic input, active high, that rises from 0V to about 1.8V 3.3V when the limit is reached. This is what we need to emulate with our combined sensor.
Rather inconveniently there is no third wire with 3.3V or 5V on which we could use as a supply.
(Edit: ignore the stuff about a 10k resistor - I think I added that at some point, and messed up, it was a bad idea. It's gone now.)
For quite a while now I've noticed during homing that the microswitch doesn't always trigger at the same point, leaving the head a bit high. (Perhaps this is the reason?) Is it really surprising, given the kind of switch used is really just to detect presence rather than necessarily achieve high precision and repeatability.
So I added this 'optical marker' so I can visually check it before each run starts. By including g-code to raise the head by 8mm after homing, i.e. exactly one rotation, I have a few seconds to check it while the nozzle heats up.
The pen line is about 0.5mm wide, and I can easily detect an error of one line width by eye, possibly less, which equates to +/-60um or so nozzle height (shaft coupler is 20mm diameter, and screw pitch is 8mm/rotation).
Is 60um accurate enough? For 0.4mm nozzle prints, where the first layer is maybe 200um, then perhaps. But if I want to print small items using a 0.2mm nozzle, say, then the first layer might only be 100um and getting it right might mean maintaining the height to within 25um. This can either be done by directly sensing the gantry height, requiring a sensor precision of 25um, or indirectly off the Z screw. There is just about room for a pin or blade 18mm long, i.e. from the screw central axis, and given the 8mm/turn pitch, a sensor here would only need 177um precision to achieve 25um at the head.
THE PLAN then is to fit an optical switch next to the screw, with a blade that breaks the light beam as the screw rotates. Increasing the length of the blade (it's radius) should gain further precision. To overcome the complication of the sensor triggering on every rotation, not just when the head is at zero height, it needs to be wired in series with the existing mechanical switch.
(Insane alternative plan: keep the mechanical switch, but attach it to the gantry and arrange it to hit a screw-mounted blade only when the gantry is at its lowest position. Something for another day perhaps...)