Introduction: Wanhao Duplicator I3 Plus Auto Bed Leveling

This instructable will help you establishing the so called "auto bed leveling" on your Wanhao Duplicator i3 Plus printer.

It will use a modified version of the original Wanhao firmware and an optical sensor with some rewiring.

There are a lot of prerequisites and changes - so I suggest this only to experienced tinkerers.

Step 1: Warnings and Disclaimer

Ok folks. We'll be doing some serious tinkering of electrical and mechanical nature.

Opening the printer exposes areas of lethal voltages.

You will likely loose your printer's warranty when altering the hardware.

This Instructable is provided "as is". Unless there are no major design flaws, please do not ask for modifications that fit your needs. Instead feel free to enhance the design and post it in the comments.

I cannot be held responsible for any harms you or your printer may encounter.

Also I cannot be held responsible for poor English writing since im am German and this is my first instructable.

Step 2: Prerequisites

Since we will be using an optical sensor that works on light reflections the original build surface has to go away.

Tests showed that the sensor works on dark surfaces, but gets irritated by white symbols and letters in the buildtak.

Instead it works excellent on glas build plates. But again unwanted reflections are bad - this time from the aluminum heated bed. Therefore the glas plate has to be painted black on the lower side. Use some high temperature black spray paint and give it at least three layers of paint.

This instructable incorporates a sensor mount that only fits if you are already using a ciiCooler mod.

Feel free to design a new sensor mount if you do not have this cooler in place or if you prefer to reposition the sensor.

Step 3: The Sensor

The sensor we are using is made and sold by David Crocker.

It has an analog and digital output mode which it determines by detecting the pullup resistor on the output pin.

The DI3+ is using pullups on the inputs but they seem to be wrong in value for the sensor.

Therefore we add an additional 10k resistor between +5V and output of the sensor.

Once powered up the sensor confirms digital output by blinking the led twice.

Four blinks indicate analog output.

Step 4: Sensor Mount

I've created a very basic sensor mount that you can find on Thingiverse.

It's far away from being shiny and nice, but does the job.

The mount is screwed to the screw holes that originally were used by the stock fan duct.

Step 5: Wiring

Now this is the hard part.

Let's look at the sensor connector. Three pins. OUT - GND - VCC

Basically you could use any of the free i/o pins on the ext connector of the mother board.

It will be later configured as new z-min sensor in the firmware.

Of course you need to solder in a connector first.

I was successfully using Arduino pin #35 for it.

In this case you will need to wire as following:

Ext connector pin 9 (GND) to center pin of sensor (GND)

Ext connector pin 10 (VCC) to right pin of sensor (VCC)

Ext connector pin 6 (#35) to center pin of sensor (OUT).

For the wiring I was using a three wire servo cable and routed it along the existing flat cable of the extruder.

Once you have wired it up you can already test if the sensor works by holding something underneath and check if the sensor's LED lights up. Also check for the double blink at power up.

Step 6: Arduino IDE

Download and install Arduino IDE 1.0.6:

Under Tools > Board > select “Arduino Mega 2560 or Mega ADK”

Connect your PC to your printer using a printer cable.

Under Tools > Serial Port select the correct COM port.

It is important that you use this version of the Arduino IDE.

Newer versions may not compile at all.

Step 7: Firmware & Mods

Download zip file of firmware with auto-leveling enabled:

Unzip firmware into folder and open Marlin.ino

I have added a #define to activate auto bed leveling and it's related settings.

In Configuration.h you'll find an entry called


If commented out

// #define ABLSUPPORT

your printer will work with the original z-min home switch and no auto bed leveling.

If not commented out


you will be using the optical sensor connected to #35 as described in step "Wiring".

The following changes have been made to the stock firmware:


#ifdef ABLSUPPORT const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop. #else const bool Z_MIN_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop. #endif

Required because of inverted logic compared to the original home switch.

#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line) #endif #ifdef ENABLE_AUTO_BED_LEVELING // these are the positions on the bed to do the probing #define LEFT_PROBE_BED_POSITION 35 #define RIGHT_PROBE_BED_POSITION 165 #define BACK_PROBE_BED_POSITION 165 #define FRONT_PROBE_BED_POSITION 35 // these are the offsets to the prob relative to the extruder tip (Hotend - Probe) #define X_PROBE_OFFSET_FROM_EXTRUDER 0 #define Y_PROBE_OFFSET_FROM_EXTRUDER -34 #define Z_PROBE_OFFSET_FROM_EXTRUDER 0 //screw this setting - it's not working #define Z_RAISE_BEFORE_HOMING 8 // (in mm) Raise Z before homing (G28) for Probe Clearance.

// Be sure you have this distance over your Z_MAX_POS in case #define XY_TRAVEL_SPEED 3600 // X and Y axis travel speed between probes, in mm/min #define Z_RAISE_BEFORE_PROBING 2 //How much the extruder will be raised before traveling to the first probing point. #define Z_RAISE_BETWEEN_PROBINGS 2 //How much the extruder will be raised when traveling from between next probing points



The probe bed positions have been adjusted to match the optical sensor's mechanical position.

The x and y probe offsets from extruder have been adjusted to match the optical sensor's mechanical position.

If you choose to not use the sensor in line with the nozzle but shifted sideways adjust x-probe offset accordingly.

The y probe offset matches the sensor mount provided.

Also I have lowered the xy travel speed to 3600.

The number of probing points has been changed from 2 to 3 (4 to 9).


#define Z_MIN_PIN 35 #else #define Z_MIN_PIN 23 #endif

If auto bed leveling is enabled we are using pin 35, else we use pin 23 which is the original z home switch.

Note: If you are planning to use a different pin than #35 change it accordingly.

Now compile and upload the firmware. to your printer.

Step 8: Testing the Sensor

With the ABLSUPPORT enabled firmware and connected sensor make sure your x-carriage is high enough so the sensor's LED is off.

In the terminal type M119 and check the z-min status.

It should report "z_min: open".

Block the sensor (LED on) and enter M119 again.

It should now report "z_min: TRIGGERED".

If you don't get this result look for your screw-up before continuing.

Now if this is ok try homing all axes by entering G28.

Have your finger ready on the power switch - just in case.

It will now home x and y axes and move to the bed's center to home the z-axis.

If G28 worked out well enter G29.

Note: Only use G29 after a previous G28 - nothing else or you will get bogus results.

Watch it probing your bed and throwing messages about the measured positions in the terminal.

You may play around with the bed leveling screws and re-probe the bed to see how the results are changing.

Good time to adjust your bed for minimal offsets.

Step 9: The Damned Z-Probe Offset

If you would start a print now, you will get nothing but mid-air printing.


In Configuration.h this setting should incorporate the z-offset of your sensor since it is slightly higher than your nozzle (which is good).


Obviously the early version of Marlin(1.0.x) that Wanhao has been using contains a z-probe offset bug.

You can find details here:

No chance to fix that in my eyes.

Since we cannot solve it this way we use a workaround in the slicer's start script.

Step 10: Changes in the Slicer Startup Script

Look at your startup script.

Where ist says G28 ... replace G28 with the following:

G28 ; home axes

G29 ; auto bed level

G1 Z0 ; move z to zero

G92 Z1.25 ; apply offset of 1.25 mm to z

The G92 part is what applies the z-offset so you are printing on the bed and not mid-air.

You will have to figure out the right value by test printing and adjusting until your results are fine.

From now on only use this script - but only if you are using the auto bed level feature!

Better make a new profile for the ABL prints.

I figured that printing a 0.2mm high "Saturn Ring" was a good help for determining the offset.

You want the first print layer to be somewhat half compressed on the bed.

The three rings I printed were already using the ABL feature and all came out perfect despite I was playing around with the bed level screws big time.

So it's alive!

Step 11: Wrap Up

Hope this Instructable gave you a good start in using ABL on your DI3+.

If you run into issues please don't ask, but find out and contribute in the comments.

I just don't have the time for it ...

... and if you fry your motherboard have 100 bucks ready for a replacement.