Adding 9g servo-based auto level sensor to your RAMPS-based 3D printer

There are all kinds of auto level sensors for 3D printers – some cheap, some more expensive…
The cheap, and most often used ones are the capacitive and inductive proximity sensors, which although widely used, have a lot of disadvantages when used for 3D printers.
For starters, they don’t measure the TOP curvature of the print surface.
Capacitive ones measure some approximation of the heated bed curvature/tilt + the print surface (they can hardly detect glass – if they detect it at all), and inductive detect only the metal of the heated bed, not what’s on top of it. So forget about inductive sensors if you are using glass – it WILL work, but your measurements will not be correct, because you won’t be measuring the print surface itself.
Another disadvantage of the capacitive sensors, is that they usually have to be very close to the print surface in order to detect something (like 1mm if you use 3mm glass), which can sometimes lead to a print being knocked out of the bed just because there’s a slight curling in some poorly cooled corner…
Yet another disadvantage, is that they can be and are influenced by air humidity.
Got the picture? From day to day they are not that accurate at all, regardless of their standard deviation at one specific moment. They WILL work just fine, but strictly speaking, your results won’t be as accurate, as you believe.

Another kind of sensor is the BLTouch sensor (and it’s clones) – which although very good, accurate and reliable, has one key disadvantage: it’s not cheap. Depending on where you buy it, it can cost you from $20 to $50. Money, which I am NOT willing to pay for a glorified switch. That’s why I’m into the whole DIY-thing – because I prefer making the things I need with my own hands & brain.

Back to the capacitive sensor bashing…
For me, the biggest issue was that the sensor had to be pretty close to the print surface (1mm).
So I decided to try a different kind of sensor – a DIY one, using widely available, and most importantly – CHEAP 9g servo, and a regular endstop switch. The whole thing costs less than $4, and is  amazingly accurate!
Far more accurate than what BLTouch claims about these kind of servo-based sensors on their sales page… What a surprise 🙂
The principle is simple: the endstop switch is placed on a short arm, connected to the servo. The whole… “thing” is attached somewhere to your extruder carriage, in such way, that when deployed, the switch is as close to the tip of the nozzle as (safely) possible – so it can measure maximal area of your bed.

When you try to home the Z axis or do an autolevel procedure, the arm rotates, and orients the switch towards the bed. When the switch triggers by hitting the bed, the Z axis moves a bit up, the servo rotates the arm back, and leaves the switch out of the way.

Here’s a video of my DIY sensor executing an auto level procedure:

The servo mount and arm I used were designed by me, just like everything else in my 3D printer 🙂
So it’s custom made to fit my printer. But you can download the models, and customize the so they fit on yours.
One “clever” trick you might have noticed on the video, is that I have placed the sensor in such way, that it’s possible to do a regular Z homing (if you don’t use the autolevel function), without activating the Z_SAFE_HOMING setting in Marlin! Well… there is still a tiny 5mm gap where the probe will crash if you try to home Z, but it’s next to impossible to do it – unless done intentionally.
I don’t like the safe Z homing, which places the extruder in the middle of the bed.
Just to be safe, if you are not sure what you are doing, better enable the Z_SAFE_HOMING 🙂


Here’s the arm and the servo mount I’m using.

You can use them as you wish, but you have to figure out on your own how to mount them on your printer 🙂 Use my video as a reference. There are similar models on thingiverse, that might be better suited for your printer.


The most important thing, is that you need a separate 5V power source for the servo. You can use the Arduino board itself, but the servo easily overloads the 5V regulator on the board, and can lead to unstable operation, spontaneous reboots, or even the regulator failing. So don’t do that.

If you power your printer via ATX PSU (like I do), it’s quite trivial – just connect the positive +5V output of the ATX PSU to the 5V pin shown on the picture below (no need to connect the GND wire).
If you use different kind of PSU, which has just 12V output, you can get 5V by using a cheap $0.36 step-down regulator. Connect it’s “+” and “-” inputs to the 12V output of your PSU, and connect it’s “+” output to the 5V pin from the picture (make sure the regulator is set to 5V before you connect the output!).

Now it’s time to connect the servo itself. You might need to extend the servo wires (they are usually pretty short).
Connect the servo to the first column of pins of the “SERVOS” connector – as shown on the picture. You have to check the color coding of your servo’s wires. On mine, the orange wire was “Signal”, and goes to D11, the red is “+” and goes to “5V”, and the brown is “-” and goes to GND.
The switch that will be used is the regular endstop switch, and there is no need to connect it to different pins – leave it as is – connected to the Z_MIN endstop pins.


In my case, I am using the Marlin firmware. In order to reconfigure it to use the servo, you will have to recompile it and upload it to the board via Arduino IDE. I will assume you are familiar with this, but if you are not – google is your friend. It’s pretty easy.
So, in order to get the servo sensor working, there are a couple of parameters that have to be changed / enabled (uncommented) in the Configuration.h file.

After you mount the probe, DO NOT TRY TO HOME Z!
You will have to find out the best values for Z_SERVO_ANGLES. Power on the printer, connect it to your PC, and using Pronterface or even the Arduino IDE serial monitor try sending the following command to the printer:

This command will try to set the servo to it’s middle position. If it does not work – then your wiring is incorrect!
Now, try to find the value of the S-parameter, which places the switch in such way, that it will be able to be triggered by the bed. This is your “deploy” angle. Write it down.
Now, find the angle, which gets the switch out of the way – it can be any value, which sets the arm to a position where it does not hit anything. This is your “stow” angle.
Now update the Z_SERVO_ANGLES parameter in Configuration.h, replace 150 with your deploy angle, and 10 with your stow angle.
Recompile, and upload the sketch to the RAMPS board again.
And that’s ALL! Now if you execute G28 (home), your printer should home itself as usual.
Just in case, do it with your finger on the OFF switch the first time you try…

What follows, is to set the probe offsets – the (X/Y/Z)_PROBE_OFFSET_FROM_EXTRUDER parameters. This can be done via gcode commands, so there is no need to recompile anything. The procedure is no different than setting up any other autolevel sensor, so I will leave that to you & google.

Finally, it’s time to test the probe accuracy. This can be done by homing the printer / placing the extruder in the middle of the bed so that the probe can be triggered, and then executing M48 command.
My probe gets this result consistently after M48:

Sometimes it’s even better – Standard Deviation 0.001 – 0.002!
This is PRETTY GOOD accuracy, comparable to the one you might get with BLTouch.


  • 9g Servo – $1.15
  • Optional 5V step-down regulator – $0.36
  • Optional Endstop Switch (you can use your existing switch) – or buy 5 for $2.66 (I could not find single switch). It’s IMPORTANT to use a switch with a roller – it provides better accuracy.

Worst case scenario, the whole contraption will cost you around $4! Which is 5 to 10 times cheaper than this other sensor I mentioned 🙂 Or maybe $30 if you manage to fry your mainboard. But don’t blame me…

Happy 3D Printing!

Leave a comment...

Leave a Reply

Your email address will not be published. Required fields are marked *