Building the C-Bot 3d Printer : Part 36 : Adding an inductive z-probe to RepRap Firmware / RADDS

Jump to C-Bot blog index to see all the posts.


This post describes how I installed an inductive Z-probe on my C-Bot 3d printer, using RADDS hardware with RepRap Fimrware.

My C-Bot printer has a 12″ square build plate, with 4-point screw leveling: Not the easiest thing to keep level.  I decided to tackle installing an inductive Z-probe to help with the leveling, since RepRap Firmware supports it.

Very important:  Before you get started, you’ll either need an aluminum build plate, or some copper tape you can stick on your existing surface at the points you want to probe.

Other info:

  • This sensor works in conjunction with your Z-endstop:  You still home using the endstop.  But after the home, the probe takes over fine-tuning the leveling process.

Get the probe:

I picked up a LJ12A3-4-Z/BY inductive probe off E-bay some time back.  It’s stats:

  • 4mm sensing distance (to iron)
  • NO, PNP
  • 6-36v input, 300ma
  • Brown = Positive, Blue = Negative, Black = signal

Make a bracket:

I modeled up a bracket for it in Autodesk Maya, that would hang off the rear of my hotend gantry.

After the probe was mounted to the bracket, I adjusted the probe so it was about 1mm from the build-plate, if the nozzle was touching the plate.  Basically, a different in 1mm from nozzle to probe-base.


You can download the bracket from Thingiverse here.

Wire it up:

Voltage Divider:

Update:  I’ve been told you can drive these sensor directly off 5v:  I’ve not tested this,but if you’re going to attempt it, it’s worth a shot.  Save you from having to deal with the voltage divider below, and it means you can wire + & – directly into the RADDS board itself.

The probe needs 6-36v, the signal input on the RADDS board only accepts 5v, and my PSU is 12v:  Need to make a voltage divider!  Generally speaking, you need two resistors, with the smaller one half the value of the larger one. Like 10k & 5k.  Of course none of my resistors worked this well, and even when I did find some that may ‘sort of match’, they value they split wasn’t 5v.

After MUCH combinations, I came up with this:  Big 2k (really 1970 on my meter).  Small was two in a series: 1k (really 970) and 670 (really 660) for a total of 1730:  1730 isn’t remotely half of 1970, not even close.  However when setup on my beadboard, it was splitting out to 5.6v, which was the closest I got all day.

Later I read that anything over 3v would trigger things fine, so I was probably making this way harder on myself than I should have.

Mockup on the breadboard, using my Macbook Air as the ‘inductive aluminum surface’ 😉


Final shrink-wrapped setup.  Resistors hidden beneath the wrap.


RADDS Board:

The signal line needs to run into the “Servo PWM3 pin” (aka Due digital 39, AKA E0_AXIS endstop[3]), which is located in a cluster of solder-points on the corner of the board:  I soldered in a header, so that I could plug my signal line into it.


Connect the wires:

Signal from probe (since having it’s voltage lowered above) -> ‘Servo PMW3’ 5v pin on RADDS board (image above).

Positive & Negative probe leads -> PSU 12v +- terminals.

Update the Firmware:

G32 is the command that triggers the probing on the board.  But the probing can be setup two different ways:

  • Use a bed.g macro filled with M30 commands (and others).
  • Use config.g filled with M557 commands, no bed.g.

I like the idea of having a separate macro file to configure my probing:  If bed.g exists, when you execute a G32, the bed.g is parsed.  If there is no bed.g, G32 instead looks for pre-configured M557’s, that live in config.g.

Initial setup

Below, I discuss how I setup config.g and bed.g


When you first add the code for the probing in config.g, it’s important that you set the ‘Z offset’ in G31 to 0: You’ll later calibrate it and edit it with the final setting.  Here’s my probing section:

M558 P4 X0 Y0 Z1 ; M558 must come before G31.
G31 X49 Y52 Z.4 P500

To break it down:

  • M558 – Set Z Probe Type
    • P4 : Set the sensor type.  When using an inductive sensor plugged in to the PMW3 pin, you need to set this to 4.
    • X0 Y0 Z1 : Use the sensor for the Z axis only.
  • G31 – Set Current Probe
    • X49 Y52 : This is the distance in mm that the sensor is away from the nozzle (used my calipers to roughly figure this out).  Since my sensor is behind and to the right of my nozzle, these are both positive values, since 0,0 is in the front left of the bed.  You can leave these zero, but I’ve read that having them set makes the calibration more accurate.  However, it makes setting up bed.g more complicated (more on that below).
    • Z.4 : This is the difference in height between the sensor and the nozzle.  Set this to zero the first time you set it up, it will be calibrated later.
    • P500 : The ‘trigger value’ : Really only important if using an IR probe, but I read for switches just set this to 500.


This is where you define the points to probe/sample.  I’m doing a 5-point probe, but you can use as few as 3.

The only really confusing part is if you’ve entered any probe offsets in config.g’s G31 (above):  They need to be accounted for below, since you’re telling the system where to send the probe.  If the probe has a 50x, 50y offset from the nozzle, and you tell the probe to go to 0,0, it’ll try to run the nozzle outside the bounds of your printer, and much stepper chattering / printer shaking will ensue until you kill the power.

To calculate the below values, this was my process:

  • Home the printer, G28.
  • In my software (Simply3D), manually jog the toolhead around to the 5 points I want to sample  When I get the probe to a sample spot, I note the current X,Y value (which is for the nozzle), and I add the offset values  to it.
  • Make sure the probe is always over the bed!  If you position the probe off-bed, when it goes to sample that point, it’ll drive the bed straight up into your nozzle :(

My bed.g:

; Probe the bed and do 5-factor auto calibration
; These are the same toolhead points, but with the sensor offsets added. Note, to use these points, you must set config.g's G31 X49 Y52
G30 P0 X49 Y52 Z-99999 ; Four... - Front Left
G30 P1 X49 Y305 Z-99999 ; ...probe points... - Back Left
G30 P2 X299 Y305 Z-99999 ; ...for bed... - Back Right
G30 P3 X299 Y52 Z-99999 ; ...levelling - Front Right
G30 P4 X149 Y152 Z-99999 S5 ; 5th probe point + store the levelling - Center
G1 X0 Y0 ; Send X & Y back to zero before print starts. This is commented out during the initial calibration.

To break it down:

  • M561 – Set Identity Transform : Clear out any previous probing transformation done.
  • G28 –  Home : Must always home before probing.
  • G30 – Single Z Probe :
    • P# : Each sample point must be assigned an index, from 0-4.
    • X# Y# : the location on the bed to send the probe.  These include the offset set in config.g’s G31.
    • Z -99999 : A value less than -9999 tells the system to probe here.
    • S5 : The final probe has the S value entered, telling it to store all 5 points.
  • G1 X0 Y0 : Send the toolhead back to X0 Y0 before print starts.  Just something I like to do, since I purge the nozzle there.  Note, during the initial calibration stage this is commented out, which makes setting the probe to nozzle z-height easier (more below).

Calibrate the nozzle-to-probe height

As discussed above, I set my proximity sensor to be about 1mm above my nozzle height.  These sensors have a 4mm detection distance for highly inductive materials like iron, but for aluminum, it’s much closer, around 1mm it seems.

Once the config.g and bed.g have been updated, fire up the printer, heat up the nozzle and bed (if you can) and execute a G32:  This will both home, and then start the probing sequence (based on what you’ve defined in bed.g).  Be excited as you watch your printer automatically drive around probing for points!  It’s important the nozzle/bed is heated up, because thermal expansion.

When the probing is done (and everything is still hot), use this process to determine the nozzle-to-probe height difference:

  • You can either enter the below commands, or use some other control software (Simplify3D) to do it.
  • G1 Z0 ;  Send the bed\nozzle to the current Z0 position.  This should move the plate close to the nozzle, but not touch it: Should be 1mm or less away.
  • G92 Z10 ; This tricks the machine so it thinks the toolhead is actually 10mm above the bed.
  • Slip a piece of paper between the nozzle and build plate.
  • G91 ; Set Relative moves.
  • G1 Z-.1 ; Start raising the bed\lowering the nozzle by -.1mm values.
  • Track how many moves you make.  Keep raising the bed\lowering the nozzle until the paper just barely moves:  You should still be able to slip the paper under the nozzle.
  • Write that number down.  Mine was -.4mm.
  • Let your machine cool, power it down.

Update config.g and bed.g

Take the positive value of that number from above, and update your config.g’s G31 Z# with it:  This is now your calibrated offset!

G31 X49 Y52 Z.4 P500

In your bed.g, enable the last line to send the toolhead back to G1 X0 Y0 if you want.

The next time you run a G32 and then send the nozzle to Z0, it should be just touching the build plate, allowing you to slip a piece of paper under it with the same friction as above.  If not, something is amiss.

However, it’s possible this position still isn’t optimal for printing the first layer:  I did a test print with a hollow cube (no roof, no floor, 2 shells) just slightly smaller than my build volume.  The nozzle was still slightly too high for good first layer adhesion.  Rather than constantly updating your firmware value to try and tweak this, you can use your slicer software, covered below.

Update your print Profiles:

My slicer software is Simply3D, but I’m guessing other slicers (Slic3r, Cura, etc) work similarly.

Start Script

The start script is the gcode that is execute before a print starts.  The only change I had to make was switch out the line that did the home operation (G28) with the new G3d command, which calls to bed.g, which homes and probes.  This is what mine looks like:

G92 Z0 E0 ; Set current z position to zero.
G1 Z2 ; Lower Z to be safe 2mm.
G32 ; bed.g - home and probe bed - If not probing, this would be G28 instead to just home.
G1 E50 F600 ; Purge nozzle 50mm 10mm sec When a print ends it's retracted by 30mm.
G92 E0 ; zero extruder
G1 X0 Y10 ; Move nozzle to left front corner of build platform.
G92 X0 Y0 ; Zero X & Y here to start the build.

Refine the Z-height

As mentioned above, my first layer was a bit too high, and wasn’t quite sticking right.  Simplify3D has a section in its ‘G-Code’ menu called ‘Global G-Code Offsets’: These allow you to provide an additional global offset to all values in the gcode.  As it turns out, setting XYZ to 0,0,-.025 mm made for a great first layer.  Iterating with this value is far easier/faster than updating the firmware.

Thoughts for dialing this in:

  • With the Z value set to zero (the default), do a test print of a box with a solid bottom.
  • If the first layer doesn’t stick well enough, cancel the print, lower by -.02 and try again.  If you see the extrusion curling up and off the bed as it extrudes, it’s actually to close, and add .02 and try again.
  • Keep iterating on this process until you get a nice stuck first layer.

Final Thoughts

Now that it’s working, I’m so sad I did’t do this sooner.  Full-volume first layers are just ‘spot on’ now.  It’s almost magical to watch it work.  Get an aluminum plate and do this mod!

Resource List:

Jump to C-Bot blog index to see all the posts.

New 3D Print: Millennium Falcon
New CNC cut: Honeywood
    • brandon dockery
    • October 5th, 2017 8:27am

    Hey are you still using reprap firmware or have you switched to repetier.

  1. I was using Repetier first, then switched to RepRapFirmware: Never looked back, by far my favorite firmware.

    • brandon
    • October 5th, 2017 9:35am

    I thought they stopped updating reprap firmware for radds?

  2. Not at all: Dan Newman had been doing it, but when he was unable to continue, David Crocker (the guy who makes RRF) took it over. You can find the latest builds updated here:

    • brandon
    • October 5th, 2017 10:50am

    Great I can finally put my rads board to use.

    Have you had any issues with the z axis? I have a very large bed at 30×30″ and i’ve since went from 2 lead screws to four as having the lead screw in the middle caused the sides to teeter totter back and forth. Not sure it’s due to the linear motion or not. I have 10mm rods with two igus bushings each on each axis. With 4 lead screws the issue goes away but I believe since there is only one stepper motor I have been unable to turn the belt by hand.

  3. My bed is 12×12″, and I’ve had success with 2 rear screws, and one mid front\one back screw (no teeter-tottering for me). I’ve not had success with with screws on the L\R sides: This introduced some weird z artifacting.

    Note, the latest builds of RRF support Z-bed leveling with multiple leadscrews. I’ve not tried this yet, but technically this means you could have a separate stepper driver per screw, each independently leveled. Not sure how this works with keeping them in sync over time, but if every time you build you re-run your bed leveling, it should auto-fix itself every print.

    • brandon
    • October 5th, 2017 11:16am

    I have one continuous belt and that seems to keep everything in sync. I may try to go with 3 lead screw setup.

  1. No trackbacks yet.