Adding Automatic Bed Leveling to Wanhao I3 Plus With ADVI3++ or Other FDM Printers




Introduction: Adding Automatic Bed Leveling to Wanhao I3 Plus With ADVI3++ or Other FDM Printers

This is an Instructable I've written to help people understand the Wanhao I3 plus (Monoprice maker select plus), and others. I've also included a little more documentation around Marlin V 1.1.8 Because I feel like there is very little if any, documentation on the internet. Every post I've come across has a different setup / Option / Opinion, So I'm hoping this instructable will shed some light on those areas.

This instructable covers Marlin V1.1.8 which is the "Software" or "firmware" the printer uses to Decipher G-Code, as well as a whole host of other features that the original developers were so kind to include.

I've included the source code, as well as the firmware and instructions on how to upload the firmware in the event you like to just download things and make it work.

This code enables Pin 25 of the Arduino, currently connected to the middle pin of the Z-Probe connector on the Wanhao board. and assigns it to the Z_MAX_PIN within Marlin. It then enables Automatic Bed Leveling Using the Bilinear Method with the Catmull-Rom Subdivision to synthesize more Leveling points and provide a more detailed mesh. The code disables the Pullup resistor on pin 25 and instead I have added a 10K pull-down resistor in-line with the signal wire. It also disables the inverting of the logic for the Z_MAX_PIN, in order for this to be used as a probe.

We will be soldering a new connector within this instructable and moving a jumper to reduce the voltage supplied to the probe to 5 Volts.

After that, we will need to determine our Z-Probe Offset to correctly adjust for the difference in height between the nozzle and the probe.

I took a lot of time documenting the code as well, for those of us who are still struggling to come to an understanding of the firmware. (Like myself). I'm hoping that the many many hours I've spent figuring this out will save a lot of people, a lot of time.

Please pay attention to the Pictures, as they are probably the most vital piece of information. Also, Each picture has a note attached that sometimes is only viewable on a Laptop or PC. The Instructables app and mobile site can sometimes hide those tips.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Overview - Basic Understanding

I have a 3D Printer. Now What?

Well, Let's start off with the basics.

You just purchased your 3D Printer and it has a touchscreen, lots of moving parts, and an SD Card slot for 3D files. That's about all you know.

Well hopefully, we can shed some light into those areas. We will start with 3D Printers, and then slicers, and finally the firmware that runs within these things.

3D Printers have a few parts you're going to want to know about.

1. X, Y, Z. Those are you three-dimensional Coordinates or Axis. Commonly referred to in number format. Ie. X175 Y180 Z50.

2. Typically they will have 5 Stepper Motors for all of the axis. (fancy motors that turn precisely where you tell them to)

1 for the X Position, 1 for the Y position, 2 for the Z position, and 1 more for the extruder that moves the plastic "Filament" that we melt down to create 3D Models. These motors use "Steps" or tiny movements, and we just need to tell them how many steps are equal to a real measurement in the real world. In our case, The Wanhao or Monoprice Printers usually use about 80 "steps" per Millimeter.

There is also "End Stop" Switches. These switches tell the Breakout board when the motor is at its "Zero" Point, or as far in one direction as it should go. There is one for each Axis. X, Y, and Z. Sometimes there is two per axis, known as the Minimum endstop, and maximum endstop. Most commonly printers have one or the other, but sometimes both.

3. They have and Extruder and a Hot End. The Extruder pushes the filament into the Hot End. The Hot End is similar to a Glue Gun, and it is what melts the filament to be printed. The Extruder is very commonly upgraded with better gears and springs that grip the filament. The Hot End has interchangeable nozzles for different applications. The most common size is 0.4 mm. That's TINY! but it does give us higher resolutions. Those nozzles also come in different materials, such as brass and hardened steel. The one that is standard is Brass and works well for most filament types, the hardened steel one is for ABS or Carbon fiber filaments. Most common Hardened steel upgrade is the Micro Swiss Hot End.

4. On the Hot end, there is a fan that keeps it cool, as to prevent the temperature from "running away" and keeping it at a precise temperature that we specify in our 3D model. (Some filaments melt at different temperatures, and if it is too hot / too cold, we will get unsatisfactory results referred to as "stringing", or "under-extrusion", plus multitudes of other things.

5. There's another fan called the "Blower Fan", Its job is to rapidly cool the filament exiting the extruder so we can keep or model stable, and in most cases, bridge gaps or overhangs in more complicated models. That otherwise would not be possible if the plastic was soft and melted. This fan speed in controllable within our 3D model settings.

6. You also may have what is referred to as a Heated Bed or Platform. This heats the Build platform to a specified temperature to prevent warping within larger models. As the plastic or filament cools, it shrinks. (surprise!, I know) When this shrinking happens, the plastic tends to "pull" up and away from the bed, causing printing issues or warping on the edges. Heating the Build plate reduces these occurrences to provide more accurate prints. It does next to nothing for Build Plate adhesion. Remember that, all too often to people increase the heated bed temperature thinking it makes the model "stick" better. It does not, and in most cases, you have a leveling issue on your hands.

A lot of people will upgrade there build platform to a Glass Bed. This is because glass is smoother, flatter, easier to level, and easier to clean. Borosillic Glass is the most common as it has the best temperature resistance, is smooth, thick, and less likely to crack.

7. LCD Screen, Some printers have a touch screen LCD such as the Wanhao and Monoprice. Others have a simpler LCD screen with text and a fancy dial referred to as a "Rotary Encoder". If your printer has the fancy touch version, it likely has its own firmware and if you decide to change the stock firmware on the breakout board, you will need to update the LCD as well.

8. Breakout Board, Motherboard, Board, or whatever else you want to call it. This is the "main board" or "brain" for your 3D printer. It handles all of the connections, motors, steps, endstop switches, Hot-End, Heated Bed, Z PROBE, and LCD. It also is responsible for Decoding the G-Code into the stepper motors and printing your 3d Model. This is mostly what we will be covering in this instructable.

The Breakout Board for 99% of all 3D printers is a Glorified Arduino, or microcontroller. If you've ever used an Arduino and written code, then this will be a walk in the park. The breakout board is an Arduino, just shaped differently and the pins have already been routed to specific connectors. This is GREAT NEWS! because it really simplifies what we need to accomplish.

The only downside is, well the manufacturer didn't give us a schematic for this board, and we have no idea what connectors are wired to what pins! That's okay, I've done a lot of research and have already figured them all out for you! WHOO! Now that we know what pins go where we can finally manipulate the code to make it do what we want. Such as Automatic Bed Leveling!


1. What is a Slicer? Well, its a fancy piece of software that takes our 3D Model, and cuts it up into Layers with specific settings set by us, and generates the 3 Dimensional G-Code for our printer to understand. WHOA!

Most 3D models are using a standard format of .STL, That's not always the case, but I will let you experiment and figure out the rest of them. Once we finally have our G-Code, we can send it to our printer Via USB or put it on an SD card, and then place the SD card into the printer.

The Most Common Slicers are Cura, Astroprint, Slic3r, Octoprint, and Repetier to name a few. They all behave differently, and you need to experiment with each one to get your desired results.


1. So what is firmware anyhoozle?

2. Firmware is the "software" or "operating system" installed on the Main Breakout Board.

There are many different types of firmware available, and the Wanhao and Monoprice use Marlin for their Firmware. Other Firmware includes Repetier, RepRap, Smoothie or Smoothieware, Teacup, and Sprinter.

Those are beyond the scope of this instructable but they operate in very similar ways, offering their own set of features and customizations. In this instructable, we will be modifying Marlin, and its features to work with our Wanhao / Monoprice Printer. Luckily for us, they were nice enough to provide the source code and we can change whatever we want within the Arduino IDE (Interactive Development Environment), and then upload that to our printer to give us more control.

Some of that has already been done for us, as the code I have written is a Fork from Sebastian's ADVI3++ Firmware. so we don't have to change much.

This may be very complicated and I will do my best to make it as easy as possible, but I'm going to continue under the assumption you have a basic understanding of Arduino, soldering, electronics, and what is, and how to flash a firmware. There are many many tutorials with the Instructables website that are very valuable resources to consider and use to your advantage.

Here is the obligatory "I'm not responsible if you break things" Comment.

Please be careful and read everything thuroughly as i would be upset if my instructions cause you to change something you shouldnt have, and you no longer could produce 3D Prints.

Rest assured i have provided the Original Source Code from the Manufacturer and the Orignial for ADVI3++ to get you back on your feet in case something dosnt work out.

Step 2: Things You Will Need

First things First.


1. You're going to need a bracket for your new Z-Probe! I am far from proficient in 3D Modeling, however, i have included a bracket I designed to work specifically with a 6mm Tactile Micro Switch. You may want to print this now! (The one I used during this process). You are more than welcome to design your own bracket, for better positioning, or different sensor or switch. Hopefully, by the end of this instructable, you will fully understand what would need to be changed within the Arduino IDE and how it affects the overall outcome.

2. A Switch or Sensor. This instructable covers mainly using a Microswitch as a probe, but that easily could be substituted for your favorite inductive, IR , or BLTouch Sensor. The switch that I used I had laying around but here is a link to some on Amazon for reference.

The important thing here is repeatability. The switches mechanical properties need to remain consistent for best performance/accuracy. If you do end up buying a switch online, make sure you do not purchase one labeled "SMD" or surface mount. They will not work with the bracket I have designed. You need a PCB mounted switch. Also, it's important to note that the switch I used was 6mm x 6mm x 6mm. Some switches are taller or shorter. That's fine, as long as you modify the value for the "Z_Probe_Offset" using the "M851 Z" Command.


3. Soldering Iron, Any will do but a finer tip helps with the smaller connections.

4. 18 - 20 Guage Wire.

5. A 3 Pin JST XH Header and Connector for style. (This is not required but it's nice to be able to unplug the probe if necessary.)

6. A 10K Resistor. Most of us have this laying around. I tried everything I could to Omit this stupid thing, but apparently, the board's ability to "Pull up" or "Pull down" a Particular pin is horrendous. so we need this to "Stabilize" the input pin. If you leave it out, the printer will think the probe is being held in the on position. The one you're looking for is BROWN BLACK ORANGE.

7. The last two things are the software. Technically speaking you don't need the software if you already have ADVI3++ installed, and decide to use the exact same setup as me. (Same bracket and similar microswitch). If you would like to customize your setup, you will need the Arduino IDE, and the customized Marlin Source Code.

Below attached is the Firmware file for flashing Via CURA, Octoprint, or your favorite Slicing software.

And just in case something isn't right. The Original Original Firmware . And the Original ADVI3++ Firmware.

Step 3: Connectors and More!

1. Start by Removing your filament, Disconnecting Power and the USB, and Laying the printer gently on its side. (wouldn't want to mess up any bracing or leveling)

2. Remove the 2 Screws holding the Center bracket in place.

3. Remove 6 more screws from the bottom of the printer cover plate. If you have already installed the "Z Braces" Mod, this step is a little tricky, but luckily the plate is flexible enough that you can pull it out by grabbing in the middle and pulling straight back.

4. Viola, You now have access to the custom Melzi inspired board. The only reference to this board is V5.1. There is currently no name for it, However, everything is almost identical to a newer style Melzi. You will notice that your Printer may look slightly different from mine. That is due to the fact I have installed a secondary board for handling the current to the heated bed platform. (you can find more information on google) but for reference, I used this module, With this Bracket.

Step 4: Solder Your Z Probe Connections

1. 4 More Screws to Get the board off the printer. You do not need to disconnect any of the connections however I did unplug the LCD because very thin ribbon cables can be a nightmare.

2. The first thing you're going to want to do is to move the Jumper I have highlighted in the pictures, from behind the Z Probe Connector. It is by default on the back right side behind pins 2 and 3. We need to De-Solder this jumper and Re-Solder it to the other side between pins 1 and 2. Doing this will bring the VCC voltage on pin 1 of the connector down to 5 Volts from 24!. Very important or we will break things! I just bridged the connection using solder because I find that easier. you can do whatever you feel comfortable with.

3. Once the Jumper is Removed, We can now solder on either a JST Header or just solder 3 wires to the board. Up to you.

4. With the jumper on the left and 3 wires soldered, we are now going to want to put a 10K Resistor between the Signal Wire and the Ground Wire. AKA Pin 2 and Pin 3. (or Arduino Pin 25 and GND) We need this resistor because the pin tends to "Float" between ground and 5 volts. Thus it gives us incorrect triggering of the Z-Probe. I Have covered all of my connections with shrink tube but hopefully, this step is self-explanatory.

(for those of you familiar with Arduino, this board would have needed an external pull-up or pull-down resistor regardless of the configuration. for whatever reason this board is noisy.)

5. Now that the Connections are made, our jumper is moved, and our resistor is in place...We're done!! Well Kinda. We need to zip tie any loose wires, get the signal and 5v wires ran to the extruder, and our screws back in!

Note: The two Screws that hold the Horizontal BRacket in place that you took off before the bottom plate (the one that connects the two Z Towers) The screws are longer than all of the others! Keep them separate!

Please Take note of the pictures for reference.

The 5v (pin 1) and Signal wire (pin 2) go to the switch and need to be routed all the way to the extruder. The Ground wire (pin 3) is only used in-line with the resistor, and gets connected to the signal wire. It then can be hidden in the bottom. Its only purpose is to pull the signal pin "Low" to eliminate false positives.

Step 5: Connect Your Z-Probe!

1. Remove the Two Ridiculously long screws from the bottom of the Fan, and pull the fan away from the Hotend. I recommend leaving the power off for this step because if you accidentally touch the fan, there's a possibility you can break off some of the fins.

2. Once the fan is removed, remove the two black spacers off of the screws and replace them with the bracket you printed earlier in step 1 of the instructable. Put the Spacers in your drawer of things for later!

3. Screw the fan back in place and get ready for the difficult part.

4. With the Tiny Bracket printed for the Switch in your hand, insert the tactile microswitch and Bend over the feet in Opposing Corners. This is important, as it helps to hold the switch in place as well as gives you the correct pinout for the Normally Open switch.

5. Pre-Tin the Wires that now run from the board and up over the extruder, i recommend stripping back a very tiny 1/16th of an inch or about 2.5-3mm and then solder those two wires to the switch. Be Quick, Plastic melts fast in front of a soldering iron! The orientation or polarity does not matter here.

6. Bend the now soldered wires out of the way and push the microswitch bracket into the extension arm and then use a rotating insertion method to snap the extension into the bracket. The idea here is that the arm can be rotated downward and used to probe, and then manually rotated back into the upright position for printing. I have added the G4 or Dwell command to give myself 5 seconds to rotate the probe. I'll talk more about that later as well.

(It may be worth noting that the arm is not very tight in the bracket. I am currently using a small printed part wedged in the gap of the arm to hold it in a 90-degree position. 3.2mm seems to be the gap here, and you can get away with a correctly sized Allen bit for a screwdriver.)

Step 6: Steps 7 and 8 Are for Reference Only and Do Not Need to Be Performed.

Steps 7 and 8 are only here to educate more people about marlin, and the I3 plus' board.

They are completely unnecessary and do not need to be completed.

After the switch is installed and wires connected to the board properly, (jumper moved, resistor installed, and pinout correct)

The only thing left to do is upload the firmware.. assuming you are currently running the ADVI3++ Firmware first. I have attached the completed firmware in step 2. No need to reflash the LCD as I have not changed or added anything to it. Think of it as an upgrade.

If you are not running the ADVI3++ firmware, I suggest you follow the instructions HERE. and return once completed.

Once you are done with that, proceed to step 8 and I will walk you through the commands to enable and set up the bed leveling procedure.

Step 7: Marlin?

So what is Marlin?

WELL, After reading their website...nobody can tell you better than them. So this is pulled straight from

"What is Marlin
Marlin is an open source firmware for the RepRap family of replicating rapid prototypers — popularly known as “3D printers.” It was derived from Sprinter and grbl, and became a standalone open source project on August 12, 2011 with its Github release. Marlin is licensed under the GPLv3 and is free for all applications. From the start Marlin was built by and for RepRap enthusiasts to be a straightforward, reliable, and adaptable printer driver that “just works.” As a testament to its quality, Marlin is used by several respected commercial 3D printers. Ultimaker, Printrbot, AlephObjects (Lulzbot), and Prusa Research are just a few of the vendors who ship a variant of Marlin.
One key to Marlin’s popularity is that it runs on inexpensive 8-bit Atmel AVR micro-controllers. These chips are at the center of the popular open source Arduino/Genuino platform. The reference platform for Marlin is an Arduino Mega2560 with RAMPS 1.4. As a community product, Marlin aims to be adaptable to as many boards and configurations as possible. We want it to be configurable, customizable, extensible, and economical for hobbyists and vendors alike. A Marlin build can be very small, for use on a headless printer with only modest hardware. Features are enabled as-needed to adapt Marlin to added components.
Main features Full-featured G-code with over 150 commandsComplete G-code movement suite, including lines, arcs, and Bézier curvesSmart motion system with lookahead, interrupt-based movement, linear accelerationSupport for Cartesian, Delta, SCARA, and Core/H-Bot kinematicsClosed-loop PID heater control with auto-tuning, thermal protection, safety cutoffSupport for up to 5 extruders plus a heated printbedLCD Controller UI with more than 20 language translationsHost-based and SD Card printing with autostartBed Leveling Compensation — with or without a bed probeLinear Advance for pressure-based extrusionSupport for Volumetric extrusionSupport for mixing and multi-extruders (Cyclops, Chimera, Diamond)Support for Filament Runout/Width SensorsPrint Job Timer and Print Counter How Marlin Works Marlin Firmware runs on the 3D printer’s main board, managing all the real-time activities of the machine.
It coordinates the heaters, steppers, sensors, lights, LCD display, buttons, and everything else involved in the 3D printing process. Marlin implements an additive manufacturing process called Fused Deposition Modeling (FDM) — aka Fused Filament Fabrication (FFF). In this process a motor pushes plastic filament through a hot nozzle that melts and extrudes the material while the nozzle is moved under computer control.
After several minutes (or many hours) of laying down thin layers of plastic, the result is a physical object. The control-language for Marlin is a derivative of G-code. G-code commands tell a machine to do simple things like “set heater 1 to 180°,” or “move to XY at speed F.” To print a model with Marlin, it must be converted to G-code using a program called a “slicer.” Since every printer is different, you won’t find G-code files for download; you’ll need to slice them yourself.
As Marlin receives movement commands it adds them to a movement queue to be executed in the order received. The “stepper interrupt” processes the queue, converting linear movements into precisely-timed electronic pulses to the stepper motors. Even at modest speeds Marlin needs to generate thousands of stepper pulses every second. (e.g., 80 steps-per-mm * 50mm/s = 4000 steps-per-second!) Since CPU speed limits how fast the machine can move, we’re always looking for new ways to optimize the stepper interrupt! Heaters and sensors are managed in a second interrupt that executes at much slower speed, while the main loop handles command processing, updating the display, and controller events. For safety reasons, Marlin will actually reboot if the CPU gets too overloaded to read the sensors."

How do I install Marlin? / Edit Marlin

Great Question!

1. You need the Arduino IDE. You can get that from the Arduino website located Here.

2. Once Downloaded, You can open Arduino and specify your controller. In our case, it's the Mega 2560!

So navigate to "Tools" > "Board:" you're going to want to select "Arduino/Genuino Mega or Mega 2560"

Then under "Tools" > "Processor" as "ATMega 2560 (Mega 2560)"

Last but not least the communication port under "Tools" > "Port:" Choose the available Com port listed. Most Likely "COM 1" (Note: 3D Printer must be connected via USB for this option to be available)

3. Now that that's out of the way, We can download the source code and extract it to a folder on the desktop. (Or wherever you want! don't let me tell you what to do!)

4. Now Navigate to the "Marlin" folder located inside of our newly extracted folder, and double-click on "Marlin.INO".

5. Now we wait, this may take awhile as marlin is fairly large and contains many files.

I've got the Arduino IDE thingy, and Marlin is open.

Nice!, Exactly where we want to be.

Marlin consists of Many Many Files, I'm going to try and stray from teaching the basics of Arduino programming to keep this short. However, if you are unfamiliar with Arduino you can find many tutorials within the IDE Software, or by visiting their website.

The first file is Marlin! HA, how appropriate. you'll notice that it is very basic, and only references a few things.

One of them, however, is Marlin.cfg.

That's where we will start,

Marlin config references exactly what is necessary for the firmware to work, and those "references" or "files" are what we can change to make things happen.

They are Listed like this

  • #include "fastio.h"
  • #include "macros.h"
  • #include "boards.h"
  • #include "Version.h"
  • #include "Configuration.h"
  • #include "Conditionals_LCD.h"
  • #include "tmc_macros.h"
  • #include "Configuration_adv.h"
  • #include "pins.h"

Specifically they are responsible for movements, speeds, accelleration, PINS, Settings, and much more.

The 2 Files we will be working with for this instructable are Configuration.h and pins_I3PLUS.h

There are so many files, that the only way to access them is via the tiny arrow in the top right of the Arduino IDE.

Feel free to change what you like, just be careful some of these things can cause real-world problems if changed incorrectly.

Step 8: What Did I Change? What Can You Change?

Well Lucky for us, within marlin they have Clearly defined Sections, Such as "Getting started", "Delta Printer", and "Scara Printer".

We don't have any of those so we can skip them.

I will be referencing these Sections going forward.

These will also be in order from top to bottom if you are looking at the marlin code. I won't be going over EVERYTHING because I feel like most of it is self-explanatory, and they all have comments next to them telling you what they are and what they do.

I will go over what I changed, why, and what it does.


Endstop Settings

Here we needed to enable the Z_MAX_PLUG so Marlin can use it as a probe,

However, because we will be pulling "Down" the signal, and then making it "High" to trigger, we needed to disable the internal pull-up resistor within the Arduino.

Then because we are doing that, we needed to "Invert" the Logic of the Z_MAX_ENDSTOP so marlin knows when that pin goes "HIGH", it will show as triggered.

Movement Settings

Here I have changed the Default Presets for Pre-Heating the Nozzle in the firmware to alight with PLA, PETG, and ABS. the 3 most common. (Not related to the Z-probe, but we're in here, so why not)

Z Probe Options

Here we need to tell Marlin what type of connection we will be using.

I didn't want to sacrifice my Z_MIN_ENDSTOP so we aren't going to use the #define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, and instead, we will enable #define Z_MIN_PROBE_ENDSTOP

After we tell it that the probe is separate from the Z_MIN_ENDSTOP we need to tell it what "type" of probe it is.

In our case, its a manually deployed probe. so naturally I enabled #define FIX_MOUNTED_PROBE

Because the bracket we created is offset form our nozzle's printing location, we need to tell it just how far off, and where it is. That way when probing, it can adjust its calculations to the location of where the measurement was taken.

I did end up changing the Z_PROBE_OFFSET_FROM_EXTRUDER option to better match my setup and bracket and it didn't seem to have any effect on the probing of the bed, probing height, or any movement, so i ended up leaving it at 0.

Next is Z-Clearance.because the prob is only about 1 mm down from the nozzle we can safely assume that 3mm is enough to move around the bed. this also speeds up the probing time because the printer starts "Babystepping" at this distance.

After that is enabling the M48 Command for testing and repeatability. Basically, it allows us to issue the M48 command and see how accurate out new probe is. COOL!

Bed Leveling

Here is where you can choose different Bed leveling profiles to better fit your printer.

Bilinear is what I enabled because its the best that we can enable without have a Text LCD screen and a rotary encoder knob.

Here things got a little complicated because you need to specify how far the probe can move in each direction and still be above the bed, and you have to negate the earlier measurements we put in for our probe offset in the X and Y directions.

Given the bed is 200 x 200 I was able to do this easily and have set these values for you.

After knowing where we can probe, the next thing to set is how many times we want to probe, and then whether or not we would like to Sub-Divide the bed leveling point into more points to get a more detailed Mesh level.

I know, complicated.

I also set the 3 point positions in case you would like to only use 3 point leveling.

3 point leveling is quick and easy and works great if your printer is perfectly square, and you're using a fairly accurate, very flat, thick piece of glass and the only variable you have is tilt.

Now we're going to move off of the configuration file, and move over to the pins_I3_Plus.h File.


This file used to include X, Y, and Z "STOP" Pins, but it was too confusing, so I've changed them to MIN and MAX Pins.

I've also added the Definition of defining the Z_MAX_PIN because marlin uses that pin for the Z_PROBE when you are not using the Z_MIN_PIN.

Here within this FIle is where you would add the "#define servo0_Pin 25" if you were going to swap the tiny button for the BLTOUCH Sensor. At the bottom of this step ive included a text file that tells you what settings to change for the BLTouch Sensor.

Step 9: Z Probe Offset - Level - and Print!

1. Now that the firmware is flashed and everything is installed, let us get to the fun part.

2. Turn on your printer and connect it to your favorite Slicer / Octoprint. We need to access the Terminal to issue some commands.

(If you do not have octoprint, or do not have a terminal to access the printer, you can alternatively use the "Serial Monitor" within the Arduino IDE Mentioned in step 6 to issue these commands. Note the Baudrate is 115200.)

3. Once Connected your initial terminal should read something like this.

Recv: ok
Send: M115

Recv: FIRMWARE_NAME:Marlin 1.1.8 (ADVi3++ABL 2.1.0) SOURCE_CODE_URL: PROTOCOL_VERSION:1.0 MACHINE_TYPE:Wahnao Duplicator i3 Plus EXTRUDER_COUNT:1 UUID:44b2f5d6-e7e4-47bf-be81-c2a6b4fc7975Recv: Cap:SERIAL_XON_XOFF0

Recv: Cap:EEPROM1




Recv: Cap:AUTOLEVEL1Recv: Cap:Z_PROBE1







Recv: ok

[...] Recv: echo:SD init fail

[...] Send: M503

Recv: echo: G21 ; Units in mm


Recv: echo:Filament settings: Disabled

Recv: echo: M200 D1.75

Recv: echo: M200 D0

Recv: echo:Steps per unit:

Recv: echo: M92 X81.00 Y81.00 Z400.50 E94.30

Recv: echo:Maximum feedrates (units/s):

Recv: echo: M203 X450.00 Y450.00 Z5.00 E25.00

Recv: echo:Maximum Acceleration (units/s2):

Recv: echo: M201 X1000 Y1000 Z100 E1000

Recv: echo:Acceleration (units/s2): P

Recv: echo: M204 P800.00 R800.00 T800.00

Recv: echo:Advanced: S

Recv: echo: M205 S0.00 T0.00 B20000 X8.00 Y8.00 Z0.40 E1.00

Recv: echo:Home offset:

Recv: echo: M206 X0.00 Y0.00 Z0.00

Recv: echo:Auto Bed Leveling:

Recv: echo: M420 S0 Z10.00

Recv: echo:PID settings:

Recv: echo: M301 P33.41 I1.47 D189.27

Recv: echo:Z-Probe Offset (mm):

Recv: echo: M851 Z 0

Recv: ok

4. Open the terminal and Home the printer by Sending "G28". (Without the quotes of course)

You should see something like this

Send: "G28"
Recv: echo:busy: processing

Recv: echo:busy: processing

Recv: echo:busy: processing

Recv: echo:busy: processing

Recv: X:0.00 Y:0.00 Z:0.00 E:0.00 Count X:0 Y:0 Z:0

Recv: ok

4.5. Now Send "M119". You should see the Z-Probe listed and OPEN. All others should be TRIGGERED.

Send: M119

Recv: Reporting endstop status

Recv: x_min: TRIGGERED

Recv: y_min: TRIGGERED

Recv: z_min: TRIGGERED

Recv: z_probe: open

Recv: ok

4.6 Now press and hold the button on the Z-probe or use whatever means necessary to trigger the probe. Send M119 again to see if its triggered. If it did, SUCCESS! proceed to part 5.

If that is not the case, something is wrong and we need to re-run through all of the steps. If the Z-Probe is listed and TRIGGERED make sure we are not pressing the switch or button. Check our wiring, Check the Resistor. And lastly, check the Endstop Status within the firmware to make sure it matches your setup.

Specifically this part

//#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors

// fine endstop settings: Individual pullups. will be ignored if ENDSTOPPULLUPS is defined
#endif // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
#define X_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
#define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe.

5. Now, here's the strange part that will make sense soon, Raise the Z Probe and Using the LCD screen level the bed, only this time instead of using a sheet of paper, move the bed all the way up to the nozzle until it just touches it. This is important because it means the nozzle height is 0, And we're going to use that for reference.

6. Once the bed is leveled to 0, Re-Home the bed either using the LCD or the Terminal "G28" command.

6.5. Next step is to Move the print head to the middle of the bed. (were attempting to find the Z-probe offset here).

7. So issue the Command "G1 X100 Y100 Z7"

8. That will move the extruder to the center, and at 7mm above the print surface.

9. Lower the probe to the down position and send "M48 V4". Pay attention to the output of the terminal.

Keep your finger on the OFF SWITCH in case something doesn't seem right.

The expected behavior is Probe > Raise > Probe > Raise Etc. 10 times over.

When Complete you should see something similar to this.

Recv: Finished!

Recv: Mean: 0.561798 Min: 0.557 Max: 0.564 Range: 0.007

Recv: Standard Deviation: 0.002233

Recv: Recv: X:100.00 Y:100.00 Z:5.56 E:0.00 Count X:8100 Y:8100 Z:2229

Recv: ok

10. Unfortunately that Z # is not very accurate, here is where the leveling of the bed comes into play.

Here comes the hard part of finding your Z probe offset.

Marlin explains it here, as long as your bed is "zeroed" to the nozzle his works pretty good.

11. Send the Command "M211 S0", This will disable the software end stops so we can lower the bed lower than 0 if necessary.

The reason we are about to do this really annoying really long thing is, so we know how "Much" lower the probe is, then the nozzle, in mm.

In an ideal world with better 3D Design we could just lower the nozzle to the bed height, and then lower the probe to the bed height, and then tighten the probe so the Probe offset is 0. Unfortunately, I do not have a bracket that allows me to do that reliably. so I need to know exactly how much lower the probe is and set my Z probe offset accordingly, so the nozzle ends up in the correct location when printing.

If we don't know this info, then when we level the bed, the nozzle will either be too high or too low for our prints.

So without further ado.

Part 1 the probe

12. Slowly lower the Z-Probe by either issuing the "G1" Command or by using Octoprint / Favorite Slicer interface.

Bring the probe down to the bed platform in .01 increments.

Then, When the probe is touching the bed, Send "M119", to report the position of the end stops.

Continue lowering the probe until you think the switch is pressed. and send "M119" again.

When the Z Probe goes from "OPEN" to "TRIGGERED" we know the position that the Z probe triggers at.

13. Send "M114" to find that position, and write it down.

Now Part 2 the nozzle

14. Raise the Z-Probe by rotating it up and out of the way.

issue the "G1" Command again or by using Octoprint / Favorite Slicer interface, Bring the nozzle down to the bed platform in .01 increments. Then, When the nozzle is touching the bed,

15. Send "M114", to report the position of the nozzle.

Write it down and subtract the difference.

(If issuing G1 Commands, you won't need m114 because you will already know where it is.)

I know, that's a lot to take in. But don't worry. I got it.

Recv: ok
Send: G1 Z-1

Recv: ok

Recv: ok

Send: G1 Z-1

Recv: ok

Recv: ok

Send: G1 Z-1

Recv: ok

Recv: ok

Send: G1 Z-1

Recv: ok

Recv: ok

Send: G1 Z-0.1

Recv: ok

Recv: ok

Send: G1 Z-0.1

Recv: ok

Recv: ok

Send: G1 Z-0.1

Recv: ok

Recv: ok

Send: G1 Z0.1

Recv: ok

Send: M119

Recv: Reporting endstop status

Recv: x_min: open

Recv: y_min: open

Recv: z_min: open

Recv: z_probe: open

Recv: ok

Recv: ok

Send: G1 Z-0.1

Recv: ok

Send: "M119"

Recv: Reporting endstop status

Recv: x_min: open

Recv: y_min: open

Recv: z_min: open

Recv: z_probe: TRIGGERED

Recv: ok

Send: "M114"

Recv: X:100.00 Y:100.00 Z:2.0 E:0.00 Count X:8100 Y:8100 Z:346

Recv: ok

// Write Down Z 2.0

Then raise probe and continue to lower until the nozzle touches.

Recv: ok

Send: G1 Z-0.1

Recv: ok

Recv: ok

Send: G1 Z-0.1

Recv: ok

etc..Then send "M114"

Send: M114

Recv: X:100.00 Y:100.00 Z: 1.1 E:0.00 Count X:8100 Y:8100 Z:346

Recv: ok

Take that first number, Subtract second number, 2 - 1.1 = .9

Take .9 and Negate it, -.9

16. Then send "M851 Z -.9" or whatever your offfset number is.

Send: M851 Z-.9

Recv: echo:Probe Z Offset: -0.90

Recv: ok

17. "M211 S1" - Re-enable the software endstops

"M500" - Save All the Things!


18. "G28"

19. "G29"

20. Print

I would recommend adding "G28", "G29", and "M420 S1" to the beginning of your G-Code or print starting script in Octoprint.

"G28" Homes the nozzle,

"G29" Autolevels the bed but requires G28 first.

"M420 S1" enables automatic bed leveling and can be disabled by sending "M420 S0".

"M420" Shows the status of bed leveling, and "M420 V4" shows the bed leveling Data.

The V4 Means Verbose Level 4, So in lamens terms...detailed X4

Once the bed is leveled you can Save the leveling data to EEPROM by issuing the "M500" Command, and the leveling data will automatically be recalled on the restart of the printer.

By default bed leveling is disabled but just needs to be re-enabled before you print again.

Also due to the minute but still very serious changes that happen to the leveling profile during the heating of the bed, I highly recommend that you preheat the bed (Not the nozzle too just the bed) before leveling. it makes a huge difference. Because i do not heat my Nozzle during leveling, the printer waits for the temperature to reach what ive set in my print. This gives me enough time to move the probe out of the way. If you do it differently or want it to wait longer, you can optionally ad the G4 Command to your starting G-Code.

G4 S10 for a 10 second wait time.

Epilog Challenge 9

Participated in the
Epilog Challenge 9

Be the First to Share


    • Sculpting Challenge

      Sculpting Challenge
    • 3D Printed Contest

      3D Printed Contest
    • Motor Vehicle Contest

      Motor Vehicle Contest

    20 Discussions


    Question 1 year ago

    Hi Kold,

    "I am currently using a small printed part wedged in the gap of the arm to hold it in a 90-degree position." - Do you have the STL for this? I'm using the Allen bit successfully now, but it doesn't feel sturdy.

    Thank you for the guide - followed it all the way through successfully, very much appreciated and fun to complete!


    Answer 1 year ago

    No longer required - I muddled my way through a Fusion360 trial and used your suggested 3.2mm width to print a usable part


    Question 2 years ago

    What is your G start code? Do you do any purging?


    Answer 2 years ago

    ;Set Bed Temp
    M190 R60
    ;Enable leveling profile
    M420 S1

    M82 ;absolute extrusion mode
    G1 Z25 F9000 ;move the platform down 25mm
    G92 E0 ;zero the extruded length
    G1 F200 E3 ;extrude 3mm of filament
    G92 E0 ;zero the extruded length again
    G1 F9000 ; Put printing message on LCD screen
    M117 Printing...


    Question 2 years ago

    Hello and thank you for posting this! Not sure if you will be able to help but i did a bit different connections as the don't need any resistors. Here is the information on how to.

    The thing is he dose not have any instructions on how to offset the nozzle. So I try to fallow your directions but they don't work as the zmin is replaced with bltouch. Would you be able to point or help me get the offset. I already have his code loaded and bltouch works just the information for offset is not there. Plus when I do M48 V4 it dose not do anything. But when I do G29 it dose start to auto level.


    Answer 2 years ago

    Never mind I did it in small numbers it end up being -2.0


    2 years ago

    Thanks for that. I will give that a go and go from there and post back my results. Your a champ.


    Question 2 years ago

    hi, super project, congratulations....

    I am looking for the wiring of a BLtouch, can you give me more instructions/ fotos for the wiring points

    (i.e. the white and the black cable)

    Thanks, have a nice day, Daniel


    Answer 2 years ago

    hopefully you've seen my comment below.


    Answer 2 years ago

    If we are using the BLtouch, we download this software instead of the one in your original instructions? And this installs over the already flashed ADVi3p software?



    Answer 2 years ago

    yes exactly


    Answer 2 years ago

    Download this firmware here.

    Then connect Red (5v) to [pin 1] Yellow (signal) to [pin2] and Brown (GND) to [pin 3] on the Z-Probe connector.

    DO NOT FORGET to move the jumper mentioned in Step 4!

    The white and black wires, White (Signal) to [pin 2] and black (GND) to [pin 1] on the Z Min connector.

    I have already screwed mine back together so I don't have any photos, if you do not get the BLUE LED to light up when powering up your printer, switch the White and black wires around. (Note that the blue led is in the bottom right corner and is very dim)

    Here is a bracket that I made for the BL-Touch Sensor.


    Question 2 years ago

    Great Instructable!! I was planning on using this with an inductance sensor. I have a voltage divider to get the resulting output voltage to 5V. It is expected that the probe produces 5V when it is away from the bed, and 0V when it detects the bed. Based on this, I am assuming that the pull-down resistor of 10K would not be required since voltage will be high when it is not active(ie detecting the bed). Appreciate your guidance if any of the following configuration items will also need to be changed?

    #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop.
    #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the probe.


    Answer 2 years ago

    The inverting would be false, as the OEM Endstops are true and go "HIGH" when triggered. so. you are right on the money there.

    The endstop Pull-ups may need to be enabled, the reason for this is so the board does not float to ground giving inaccurate readings. you could use a 10k "pull up" externally. although that would be unnecessary as the board seems to handle this task just fine.

    looking back on writing this, I should have just ran a ground out to the switch and used the internal pull-up resistors, reducing the complexity and omitting the 10k resistor and at last inverting the detection of the probe.

    You live and you learn I guess! Happy Leveling!


    Question 2 years ago

    Hello - Awesome doco. I ended up getting a different sensor and am having trouble with programming the firmware.
    The STL for the sensor fits in this and is currently working

    I get the correct response from the sensor when there it does not detect metal:

    Send: M119

    Recv: Reporting endstop status

    Recv: x_min: open

    Recv: y_min: open

    Recv: z_min: open

    Recv: z_probe: open

    Recv: ok

    Send: M10


    And when it connects to metal - triggered:

    Send: M119

    Recv: Reporting endstop status

    Recv: x_min: open

    Recv: y_min: open

    Recv: z_min: open

    Recv: z_probe: TRIGGERED

    Recv: ok


    If I could please get some help with the correct changes required for the firmware to recognise the sensors position and get it to actually stop when "triggered".



    Answer 2 years ago

    make sure that you clear your eeprom using M502 and M500. also check that this Is defined in your code


    in all respects it should work. it will not stop lowering the Z axis however when "homing", because it's assuming that your using the originally installed Z_MIN_ENDSTOP. the probe will only stop the lowering of the Z axis when sending G29. (autolevel) that's why I used a probe that could be "flipped" out of the way...

    If you would like to use the probe as a Z_MIN_ENDSTOP as well, and omit the original, you would need to connect the 5v output of the probe to the input of the Z_MIN_ENDSTOP (just forget about pin 25) on the board, then go back into the code..

    change your inverting for the "Z_MIN_ENDSTOP"
    and endstop pull-up resistor setting respectively to match your current setup of the "Z_PROBE"

    then comment out

    //#define Z_MIN_PROBE_ENDSTOP

    and uncomment


    then, enable "SAFE_Z_HOMING" so that the nozzle never tries to home outside of the build plate. that way the probe will always be above metal.

    let me know if you have any other questions!


    Question 2 years ago on Step 9

    great guide, could you post a picture of the finished product with the probe mounted? I am a bit confused as to how the whole thing looks when completed and where the probe will actually mount to the extruder assembly.


    Answer 2 years ago

    Thank You!, and yes, I have added photos of the probe's location. Great Idea!


    Question 2 years ago on Step 9

    Hello Kold, i did everything as you say i used the .hex file but every time i hit the buttom on the switch i dont get trigger on the z_probe i get the trigger on x,y and z_min but not on the Z_probe any suggestions? i am getting 5V on the red wire what voltage/resistense do i need to get on the signal wire of course after the ground and 10k resistor?


    Answer 2 years ago

    You need to make sure the resistor is placed between the ground connection and signal wire. the resistor is there to "pull" the signal to ground so when you hit the switch it goes "high" and the signal goes through.